java项目自动化单元测试

2023-11-18

对于我们开发人员来说,单元测试一定不会陌生,但在各种原因下会被忽视,尤其是在我接触到的项目中,提测阶段发现各种各样的问题,我觉得有必要聊一下单元测试。

为了写而写的单元测试没什么价值,但一个好的单元测试带来的收益是非常客观的。问题是怎么去写好单元测试?怎么去驱动写好单元测试?

一 现状

现状一:多个项目完全没有单元测试。

现状二:开发人员没有写单元测试的习惯,或者由于赶业务记录而没有时间去写。

现状三:单元测试写成了集成测试,比如容器、数据库,导致单元测试运行时间长,失去了意义。

现状四:太依赖集成测试。

在gitlab上随便找两个项目的测试情况,基本不考虑单元测试就合并发布,形同虚设。

站在开发的角度讲,导致以上问题的原因大概有以下几点:

  1. 开发成本

    对于系统初期,可能要花很多时间去写新业务,对于老系统又太过庞大,无法下手。

  2. 维护成本

    每修改相关的类,或者重构一次代码,我们就要去修改相应的单元测试。

  3. ROI

​ 投入产出是不是正收益?可能无论是管理者还是我们开发自己都回质疑这个问题,所以有时候没有强有力的动力。

二 怎么解决

说来说去都是成本的问题,所以我们怎么去解决成本呢?

那么,我们一切从最开始说起:开发的成本

一个单元测试的传统写法,包含以下几个方面:

  1. 测试数据 (被测数据,和依赖对象)
  2. 测试方法
  3. 返回值断言
  • 示例
  @Test  
public void testAddGroup() {    
      // 数据    
      BuyerGroupDTO groupDTO = new BuyerGroupDTO();    
      groupDTO.setGmtCreate(new Date());    
      groupDTO.setGmtModified(new Date());    
      groupDTO.setName("中国");    
      groupDTO.setCustomerId(customerId);    
      // 方法    
      Result<Long> result = customerBuyerDomainService.addBuyerGroup(groupDTO);    
      // 返回值断言    
      Assert.assertTrue(result.isSuccess());    
      Assert.assertNotNull(result.getData());  
  }

一个简单的测试还好,但如果是一逻辑复杂,且入参数据复杂的时候,那写起来其实挺头痛的。怎么解放我们程序员的双手?

“工欲善其事必先利其器”

我们以最大的努力降低我们的开发成本,这就涉及到我们测试框架和工具的选择问题

1 、测试框架选择

首先第一个问题就是junit4和junit5的选择,【从junit4到junit5】 我觉得最便利的一个好处就是可以参数化测试,并且基于参数化测试我们可以更加灵活的配置我们的参数。

效果如下:

@ParameterizedTest
@ValueSource(strings = { "racecar", "radar", "able was I ere I saw elba" })
void palindromes(String candidate) {    
    assertTrue(StringUtils.isPalindrome(candidate));
}

更好的是,junit5提供了扩展,比如我们常用的json格式。这里我们使用json文件作为输入:

@ParameterizedTest  
@JsonFileSource(resources = {"/com/cq/common/KMPAlgorithm/test.json"})   
public void test2Test(JSONObject arg) {    
    Animal animal = JSONObject.parseObject(arg.getString("Animal"),Animal.class);     
    List<String> stringList = JSONObject.parseArray(arg.getString("List<String>"),String.class);    
    when(testService.testOther(any(Student.class))).thenReturn(stringArg);    
    when(testService.testMuti(any(List.class),any(Integer.class))).thenReturn(stringList);    
    when(testService.getAnimal(any(Integer.class))).thenReturn(animal);    
    String result = kMPAlgorithm.test2();    //todo verify the result  
}

2、 mock框架

mock类的框架

Mockito: 语法特别优雅,对于容器类的模拟比较合适,且对于返回值为空的函数调用也提供比较好的断言。缺点是不能模拟静态方法(3.4.x以上版本已支持)

EasyMock: 使用方法类似,但是更严格

PowerMock: 可以作为Mockito的一个补充,比如要测试静态方法,不过不支持junit5

Spock: 基于Groovy语言的单元测试框架

3、 数据库层

这里主要介绍一下H2数据库,其基于内存来作为对于关系型数据库的模拟,运行完成自动释放,达到隔离的目的。

主要配置:ddl文件路径、dml文件路径。这里不作详述。

但对于要不要集成数据库,很难去定义,它的作用主要是用来验证sql语法的问题,但是相对来说较重,建议可以用于轻量级的集成测试。

三 、Junit5和Mockito

后面讲到的自动生成使用的框架和业界使用最多的都是MocKito,所以这里重点介绍一下,包括使用时遇到的问题。

1 使用方法

  1. 分别单独引入依赖,推荐引入最新版
<!-- junit5 -->
<dependency>  
    <groupId>org.junit.jupiter</groupId>  
    <artifactId>junit-jupiter</artifactId>  
    <version>5.7.2</version>  
    <scope>test</scope>
</dependency>
<!-- mockito -->
<dependency>  
    <groupId>org.mockito</groupId>  
    <artifactId>mockito-core</artifactId>  
    <version>3.9.0</version>  
    <scope>test</scope></dependency>
<!-- mockito 的junit5适配器 -->
<dependency>  
    <groupId>org.mockito</groupId>  
    <artifactId>mockito-junit-jupiter</artifactId>  
    <version>3.9.0</version>  
    <scope>test</scope>
</dependency>
  1. 使用spring-test全家桶
<dependency>  
    <groupId>org.springframework.boot</groupId>  
    <artifactId>spring-boot-starter-test</artifactId>  
    <scope>test</scope>  
    <version>2.5.0</version>
</dependency>

junit5的使用方法这里就不多做介绍,主要说一下这个ArgumentsProvider接口,实现它就可以自定义参数化类,类似于自带的ValueSource、EnumSource等。

2 、Mockito 主要注解介绍

先问为什么,为什么需要Mockito

因为:现在的java项目几乎离不开spring框架,而其最为著名的就是IOC,所有的bean用容器来管理,所以这给我们单元测试带来一个问题,如果要对bean做单元测试,就需要启动容器,那么带来的时间的开销将会很大。所以Mockito给我门带来了一系列的解决方法,让我们可以轻松的对bean 进行测试。

@Componentpublic 
class A {    
    @Autowired    
    private B b; // 完全mock    
    @Autowired    
    private C c; 
    // 需要执行方法    
    @Autowired 
    D d; 
    // 需要执行真实方法    
    public void func(){    }
}

@Component
class C {    
    @Autowired    
    private B b;    
    public void needExec(){    }
}

@Component
public class B {}

假设我们要对上面的A.func()进行单元测试。

@InjectMocks注解

表示需要注入bean的类,有两种

  1. 被测试类,这种很容易理解,我们测试这个类,当然也需要向其注入bean。比如上面的A

  2. 被测试类中的,需要执行其真实的方法,但其里面也要主要bean,也就是上面的C,我们需要测试neeExec方法,但我们不关系B的具体细节。现实中比如事物,并发锁等。这一类需要Mockito.spy(new C())的形式,不然会报错

@Mock

表示要mock的数据,也就是不真实执行其方法内容,只按照我们的规则执行,或者返回,比如使用when().thenReturn()语法。

当然也可以,执行真实方法,则需要when().thenCallRealMethod()方式。

@Spy


表示所有方法都走真实方式,比如有些工具类,转换类,我们也写成了bean的形式(严格来说这种需要写成静态工具类)。

@ExtendWith(MockitoExtension.class)
public class ATest  {  
    @InjectMocks  
    private A a=new A();   
    @Mock  
    private B b;  
    @Spy  
    private D d;  
    @InjectMocks  
    private C c= Mockito.spy(new C());
    @BeforeEach  
    public void setUp() throws Exception {    
        MockitoAnnotations.openMocks(this);  
    }  
    @ParameterizedTest  
    @ValueSource(strings = {"/com/alibaba/cq/springtest/jcode5test/needMockService/A/func.json"})   
    public void funcTest(String str) {    
        JSONObject arg= TestUtils.getTestArg(str);                          
        a.func();    //todo verify the result 
                                     
    }
}

3 、Mockito和junit5常见问题

1. mock静态方法
mockito3.4以后开始支持,之前的版本可以使用PowerMock辅助使用

2. Mockito版本和java版本兼容问题

报错如下

Mockito cannot mock this class: xxxMockito can only mock non-private & non-final classes.

原因是2.17.0及之前的版本与java8是兼容的

但2.18之后需要使用java11,为了在java8中使用Mockito,则需要引入另一个包

<dependency>    
    <groupId>net.bytebuddy</groupId>    
    <artifactId>byte-buddy</artifactId>    
    <version>1.12.6</version>
</dependency>

3. Jupiter-api版本兼容问题

Process finished with exit code 255
    java.lang.NoSuchMethodError: org.junit.jupiter.api.extension.ExtensionContext.getRequiredTestInstances()Lorg/junit/jupiter/api/extension/TestInstance

第一个问题是因为junit5中api、engine、params版本不一致导致的。

第二个问题是因为jupiter-api版本太低的问题,5.7.0以后的版本才支持。

四、测试代码自动生成

选好了框架,我们还是没有解决我们的问题,“怎么节约开发成本?” ,这一节我们来谈这个问题,这也是我主要想表达的。

对于写单元测试,一直以来是比较头痛的事情,要组装各种各样的数据,可能还没跑成功,就被一堆“xxxx不能为null”的报错搞烦了。因此我们有理由去设想,有没有办法去解决这件事情。

1、 业界和方案调研

在做这个事情之前,肯定是要调研有没有现成的框架。答案是有,但很遗憾,没有找到完全契合我想要的效果,我们来看一下这些插件:

public class BaseTest {    
    protected TestService testService;    
    public String baseTest() {        
        return testService.testBase(1); // 4    
    }
    
}

public class JCode5 extends BaseTest {     
    public void testExtend(){        
        String s = testService.testOther(new Student()); //1         
        // 调用 另一个方法        
        System.out.println(testBean());        
        // 调用基类方法        
        baseTest();    
    }    // 使用testService    
    public String testBean() {        
        testService.testMuti(new ArrayList<Integer>() {{add(1);}}, 2); //2        
        return testService.getStr(12); //3    
    }   
    /**     * 测试范型类     */    
    public void testGeneric(Person person) {        
        //test        
        list.stream().forEach(a -> {            
            System.out.println(a);        
        });        
        for (int i = 0; i < 2; i++) {            
            Long aLong = testService.getLong("1213", "12323");            
            System.out.println(aLong);        
        }       
        System.out.println(testBean());    
    }
}

public class TestService {    
    public String testBase(Integer integer) {        
        return "TestBase";    
    }    
    public List<String> testMuti(List<Integer> a, Integer c) {        
        List<String> res = new ArrayList<>();        
        res.add(a.toString() + c + "test muti");        
        return res;    
    }     
    public String getStr(Integer integer) {        
        return "TestService" + getInt();    
    }     
    public String testOther(Student student) {        
        return student.getAge() + "age";    
    }
}

如上,testExtend一共调用了testService的4个方法,我们对比下各个插件生成的代码。

1、TestMe

  
@Test    
void testTestExtend() {        
    when(testService.getStr(anyInt())).thenReturn("getStrResponse");        
    when(testService.testMuti(any(), anyInt())).thenReturn(Arrays.<String>asList("String"));        
    when(testService.testOther(any())).thenReturn("testOtherResponse");        
    jCode5.testExtend(Integer.valueOf(0));    
}  

@Test    
void testTestGeneric() {        
    when(testService.getStr(anyInt())).thenReturn("getStrResponse");        
    when(testService.getLong(anyString(), anyString())).thenReturn(Long.valueOf(1));        
    when(testService.testMuti(any(), anyInt())).thenReturn(Arrays.<String>asList("String"));
        
    jCode5.testGeneric(new Person());    
}

1、生成的代码基本符合逻辑,包括需要mock的bean的逻辑都生成了。

2、但它把最重要的一环,也就是数据省略了,只是单纯的用了构造函数的形式。这显然对于我们DDD模型不适应。

3、另外他没用用到junit5的一些特性,比如参数化测试。

4、对于testExtend的方法,它只识别了3个方法。没有识别父类的调用。

2、JunitGenerate

只能生成基础的框架代码,对于我想mock的逻辑、以及测试方法都没有生成,用处不大。

@Test
public void testTestExtend() throws Exception {
    //TODO: Test goes here... 
}

3、Squaretest

生成的方法非常丰富,且一个非常厉害的一点,它能生成多个分支,比如代码逻辑中有if条件,它能生成两个测试,从而走不同的分支。

但是,最大的缺点是“收费软件,不开源”,这就决定了我们没法用它,除非是特别需要。另外测试用过程中还发现了一些其他问题,比如对于继承,重载之类的问题,它解决的也不是很好,往往识别不了需要调用的方法。

虽然无法使用,但还是可以借鉴。

五、 打造代码自动生成最佳方案

使用别人写的插件(JCode5)。有兴趣的也可以自己试试。

1、 插件安装

idea插件市场下载,搜索JCode5

2、 插件使用

插件有三个功能

  1. 生成测试代码,也就是生成单元测试。

  2. 生成json数据,通常用来生成测试数据,比如model。用来参数化测试。

  3. 增加测试方法,随着业务开发,类可能增加一下功能方法,这个时候相应的可以增加测试方法

定位到需要测试的类,快捷键或菜单定位到generater,如下,选择JCode5。

1、生成测试类

目前支持三个选项,后续会逐渐完善

另外两个功能类似,直接尝试使用一下就行。

2、生成的结果---类+json数据

  
@ParameterizedTest  
@ValueSource(strings = {"/com/cq/common/JCode5/testExtend.json"})   
public void testExtendTest(String str) {    
    JSONObject arg= TestUtils.getTestArg(str);    
    Integer i = arg.getInteger("Integer");     
    // 识别泛型活着集合类    
    List<String> stringList = JSONObject.parseArray(arg.getString("List<String>"),String.class);     
    String stringArg = arg.getString("String");     
    String stringArg1 = arg.getString("String");     
    String stringArg0 = arg.getString("String");     
    // 识别四个方法,包括父类调用、其他方法调用    
    when(testService.testBase(any(Integer.class))).thenReturn(stringArg);    
    when(testService.testMuti(any(List.class),any(Integer.class))).thenReturn(stringList);    
    when(testService.getStr(any(Integer.class))).thenReturn(stringArg0);    
    when(testService.testOther(any(Student.class))).thenReturn(stringArg1);    
    jCode5.testExtend(i);    //todo verify the result  
}

如上除了生成基本的代码,另外会生成测试数据,它会将该方法所需要的测试数据全都生成在一个json文件当中,完全实现“数据和代码的分离”

如testExtend.json:

{ 
    "Integer":1,  "String":"test",  "List<String>":[    "test"  ]
}

3、补充判定语句

这一块前期考虑对于不同的方法有不同的校验,所以目前想的还是开发者自己去写验证代码。

注意事项

在自动生成完代码之后,虽然可以运行,但如我们前面提到的,为了写单元测试而写的单元测试是没什么价值的,我们的最终目的是为了写一个好的测试。代码自动生成,但它终究能力有限,所以还是需要我们自己再去验证,比如

  1. 该插件生成的代码需要junit5和mockito的支持,使用时需要引入相关的依赖

  2. 增加assert校验逻辑,看是不是想要的结果,目前插件不会自动生成assertEquals等断言代码。

  3. 运用参数化测试能力,复制一份生成的json文件并修改输入数据,多组测试

3 、插件实现介绍

主要的实现思路,参考了dubbo的SPI的源码,也就是自动实现自适应SPI那部分,简单点说就是反射获取代码逻辑,然后生成测试代码。

mock数据可定制,目前的想法是:

  • 固定值比如目前的String: test、Integer和boolean: 0、1
  • 测试者使用配置模版,比如txt文件包含keyValue对
  • 使用Faker,对于name、email、phone这种特定倾向的数据进行特色自动生成
  • 自动分支测试,这一块的想法目前主要针对if来做,需要一定的时间。
  • 其他

对于代码自动生成,还是有很多东西可以做的,但有些问题还尚待解决,希望能尽最大努力解放我们的双手,也能提高我们单元测试的质量。

最后:下方这份完整的软件测试视频学习教程已经整理上传完成,朋友们如果需要可以自行免费领取【保证100%免费】

软件测试面试文档

我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

图片

这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java项目自动化单元测试 的相关文章

  • 软件测试|Windows系统配置pytest+allure环境教程

    前言 allure可以输出非常精美的测试报告 也可以和pytest进行完美结合 不仅可以渲染页面 还可以控制用例的执行 本文我们将介绍Windows系统中如何配置allure环境 第一步 配置Java环境 因为 allure 的运行依赖于J
  • “揭秘性能测试工具:优化软件性能的关键秘籍“

    性能测试工具的设计宗旨是为了模拟用户对软件应用程序或系统的各种操作 旨在评估关键的性能指标 包括响应时间 吞吐量 并发能力和资源利用率 通过这些工具模拟的多用户环境 我们能够产生与实际工作负载相似的条件 并监测系统在这种情况下的性能表现 一
  • Jmeter 压测-性能调优5大注意

    2024软件测试面试刷题 这个小程序 永久刷题 靠它快速找到工作了 刷题APP的天花板 CSDN博客 文章浏览阅读2 2k次 点赞85次 收藏11次 你知不知道有这么一个软件测试面试的刷题小程序 里面包含了面试常问的软件测试基础题 web自
  • 38条Web测试经验分享

    1 页面链接检查 每一个链接是否都有对应的页面 并且页面之间切换正确 可以使用一些工具 如LinkBotPro File AIDCS HTML Link Validater Xenu等工具 LinkBotPro不支持中文 中文字符显示为乱码
  • Selenium小技巧!

    Chrome DevTools 简介 Chrome DevTools 是一组直接内置在基于 Chromium 的浏览器 如 Chrome Opera 和 Microsoft Edge 中的工具 用于帮助开发人员调试和研究网站 借助 Chro
  • Locust负载测试工具实操

    本中介绍如何使用Locust为开发的服务 网站执行负载测试 Locust 是一个开源负载测试工具 可以通过 Python 代码构造来定义用户行为 避免混乱的 UI 和臃肿的 XML 配置 步骤 设置Locust 在简单的 HTTP 服务上模
  • 2种方法,教你使用Python实现接口自动化中的参数关联

    通常在接口自动化中 经常会参数关联的问题 那么什么是参数关联 参数关联就是上一个接口的返回值会被下一个接口当做参数运用 其中Python中可以实现参数关联的方法有很多种 今天小编给大家介绍下 如何通过Python来实现接口自动化中的参数关联
  • 外包干了3个月,技术退步明显。。。。。

    先说一下自己的情况 本科生 19年通过校招进入广州某软件公司 干了接近4年的功能测试 今年年初 感觉自己不能够在这样下去了 长时间呆在一个舒适的环境会让一个人堕落 而我已经在一个企业干了四年的功能测试 已经让我变得不思进取 谈了2年的女朋友
  • 测试用例评审流程优化

    测试用例 评审是QA日常工作流程中的关键一环 是QA同学完善测试用例 交流测试经验的好机会 负责组内测试用例建设以来 作者对于评审流程做了一些优化工作 本文作者将整个优化过程中的心得体会做了一个总结 希望能给大家带来帮助 01 原始流程 1
  • 软件测试|Python中如何提取列表中索引为奇数的元素

    简介 在Python中 我们经常需要从列表中提取特定位置的元素 如果我们想要提取列表中索引为奇数的元素 可以使用一些简单的方法来实现这一目标 本文将介绍如何在Python中提取列表中索引为奇数的元素 并提供示例代码来帮助大家更好地理解这个过
  • 软件测试|Pydantic处理时间类型数据

    简介 我们之前介绍过使用 pydantic 验证数据 比如校验数据的格式等 但是在我们的日常工作中 还有一种数据是需要我们验证的 比如时间数据 时间数据不同于字符串 列表等数据 与他们的验证不一样 本文就来为大家介绍一下 pydantic
  • 软件测试|教你如何使用Python绘制出奥运五环旗

    简介 我们之前介绍过使用turtle来绘制正多边形 但是绘制正多边形只是turtle模块最基础的使用 我们可以使用turtle模块绘制出更多不一样的精彩图形 本文就来给大家介绍一个比较简单的turtle绘图实例 绘制奥运五环旗 初始化参数
  • Python自动化测试 | 如何使用Robot Framework进行自动化测试?

    2024软件测试面试刷题 这个小程序 永久刷题 靠它快速找到工作了 刷题APP的天花板 CSDN博客 文章浏览阅读2 3k次 点赞85次 收藏11次 你知不知道有这么一个软件测试面试的刷题小程序 里面包含了面试常问的软件测试基础题 web自
  • msyql 异常,别干着急,70%的问题都在这里!

    2024软件测试面试刷题 这个小程序 永久刷题 靠它快速找到工作了 刷题APP的天花板 CSDN博客 文章浏览阅读2 3k次 点赞85次 收藏11次 你知不知道有这么一个软件测试面试的刷题小程序 里面包含了面试常问的软件测试基础题 web自
  • 甜蜜而简洁 —— 深入了解Pytest插件pytest-sugar

    在日常的软件开发中 测试是确保代码质量的关键步骤之一 然而 对于测试报告的生成和测试结果的可读性 一直以来都是开发者关注的焦点 Pytest插件 pytest sugar 以其清晰而美观的输出 为我们提供了一种愉悦的测试体验 本文将深入介绍
  • 月薪2W的软件测试工程师,到底是做什么的?

    在生活中 我们常常会遇到以下几种窘迫时刻 准备骑共享单车出行 却发现扫码开锁半天 车子都没有反应 手机导航打车 却发现地图定位偏差很大 司机总是跑错地方 买个水 却遭遇自动售货机吐币 或者不找零钱 好不容易休息打个游戏 却一直出现卡顿 闪退
  • Python常用的自动化小脚本!

    一 list转json string转json 可以使用Python内置的 json 模块将列表 List 和字符串 String 转换成JSON格式 List转JSON假设我们有一个列表 List my list apple banana
  • 一文让你了解UI自动化测试

    测试都起什么作用 是项目的保险 但不是项目的救命草 测试无实际产出 但作用远大于实际产出 测试是从项目维度保证质量 而不是测试阶段 UI自动化 下面简称自动化 基于UI进行自动功能测试 以Web端作为例子 一般的UI功能自动化都是基于HTM
  • 一文让你快速写出高效的软件测试用例

    前言 编写测试用例的目的就是确保测试过程全面高效 有据可查 但要编写出高效的测试用例 需要搞清楚什么是测试用例 以及如何编写出高效的测试用例 接下来将从以下几个部分来进行展开 1 什么是测试用例 2 如何编写测试用例 3 软件测试学习资源分
  • 用Python实现高效数据记录!Web自动化技术助你告别重复劳动!

    自动化关键数据记录 简介 关键数据记录是 Web 自动化测试中的关键部分 它们提供了关于系统行为和执行过程的详细信息 有助于验证用例的正确性 排查问题和确保应用程序的质量 行为日志 行为日志是一种用于记录系统或应用程序的操作和事件的技术 它

随机推荐

  • 每日小练习 ——《计算布尔表达式的值》LeetCode Plus 会员专享题【详细解析】Hive / MySQL

    大家早上好 本人姓吴 如果觉得文章写得还行的话也可以叫我吴老师 欢迎大家跟我一起走进数据分析的世界 一起学习 感兴趣的朋友可以关注我的数据分析专栏 里面有许多优质的文章跟大家分享哦 另外也欢迎大家关注我的SQL刷题专栏 里面有我分享的高质量
  • 开源的AI算法可以进行物体识别,动物识别

    有许多开源的AI算法可以进行物体识别和动物识别 其中最常用的算法是深度学习中的卷积神经网络 Convolutional Neural Network CNN 如Google开源的Inception和ResNet模型 以及Facebook开源
  • Java VS Python各自在AI人工智能领域的应用前景

    目前AI领域应用最广泛的开发语言是Python Python在过去几年里在人工智能和机器学习领域取得了巨大的成功和普及 有几个原因使得Python成为AI开发的首选语言 丰富的库和框架 Python拥有许多专门用于AI和机器学习的优秀库和框
  • STM32学习笔记

    GPIO 通用输入输出口 所有GPIO口都是挂载在APB2外设总线上 GPIO外设名称按照GPIOA GPIOB GPIOC来命名 每个GPIO外设有16个引脚 0 15 GPIOA的第0号引脚称作PA0 八种输入输出模式 1 浮空输入 可
  • 去除快捷方式箭头BAT脚本

    去除快捷方式箭头BAT脚本 1 脚本功能 去除window电脑桌面图标右下角的快捷方式小箭头 对于强迫症患者绝对是福音 总之清除了之后非常的舒畅 2 脚本内容 echo off color 2 reg delete HKCR lnkfile
  • Knowledge Distillation and Student-Teacher Learning for Visual Intelligence

    本文是蒸馏学习综述系列的第四篇文章 Knowledge Distillation and Student Teacher Learning for Visual Intelligence A Review and New Outlooks的
  • C89和C99标准比较

    1 增加restrict指针 C99中增加了公适用于指针的restrict类型修饰符 它是初始访问指针所指对象的惟一途径 因此只有借助restrict指针表达式才能访问对象 restrict指针指针主要用做函数变元 或者指向由malloc
  • PAT B 1055 集体照(C语言)

    一 题目 拍集体照时队形很重要 这里对给定的 N 个人 K 排的队形设计排队规则如下 每排人数为 N K 向下取整 多出来的人全部站在最后一排 后排所有人的个子都不比前排任何人矮 每排中最高者站中间 中间位置为 m 2 1 其中 m 为该排
  • 设备退出:“设备正在使用”的快速解决办法

    我们常常遇到U盘或移动硬盘显示因为 设备正在使用 而无法拔出的情况 如果冒然拔出 可能会造成数据丢失或损坏设备的情况 现在提供一个可以快速解决的办法 步骤一 win r 打开cmd命令命令面板 步骤二 输入diskpart 进入磁盘分区管理
  • android手机拍摄权限,react-native 手机拍照权限

    第一步 在 android app src main AndroidManifest xml 添加 然后运行项目在手机应用权限哪里查看 这是添加前的 这是添加后的 第二步调用 import React Component from reac
  • Vuforia的各种Target的简单介绍(包括地面识别)

    Vuforia的各种Target的简单介绍 包括地面识别 前言 Vuforia的两种识别分类 1 需要特定目标的识别 2 不需要特定目标的识别 上边两种的优缺点 基于优缺点进行的阿应用场景推荐 需要目标的类型 上传你的目标到服务器 不需要目
  • Android UI-开源框架ImageLoader的完美例子

    android layout gravity left center vertical android layout marginLeft 20dip android textSize 22sp gt GridView异步加载图片显示 20
  • Android APK反编译 最新版 解决Could not decode arsc file

    本人小白 初学Android 这不想着找点成熟的app看看 学习一下 就找到反编译了 拜读各位前辈大神的文章 弄啊弄 总是出现 Could not decode arsc file 的错误 擦擦 愁人啊 百度不行 就Google 捯饬啊捯饬
  • Ubuntu 安装与使用 Visual Studio Code

    1 Visual Studio Code简介 1 1 什么是Visual Studio Code Visual Studio Code是微软推出的一个运行于 Mac OS X Windows和 Linux 之上的 针对于编写现代 Web 和
  • 服务计算:简单的web程序

    CloudGo 框架选择 看了go的一些框架如beego和iris觉得挺好的 本来想用 但是虚拟机出了点问题装不成 windows上装成了没ab指令 所以使用官方的net http库做简单的实验 看完beego和iris的特性我还是比较想用
  • Linux下yum安装dstat,安装配置整理之 dstat

    tech163 usr local download dstat help Usage dstat afv options delay count Versatile tool for generating system resource
  • 菜鸡面试遇到有印象的问题(LINUX下内核如何管理内存)

    目录 写在文章的前面 本人C C 面试岗位 学艺不精 研究生做的与代码无关的工作 仅记录每次面试遇到的问题勉励自己 一 x86下的物理地址空间布局 二 linux虚拟地址内核空间分布 三 linux虚拟地址用户空间分布 1 page 页 2
  • 通过tableExport.js插件导出jqgrid表格数据

    通过tableExport js插件导出jqgrid表格数据 提前说 没有实现导出pdf png和ppt 实现了导出 JSON XML CSV TXT SQL MS Word Ms Excel 代码实例 包含改进的tableExport j
  • MySQL建表设置默认值取值范围

    一 设置默认值 设置默认值采用default 如代码所示 二 设置取值范围 设置取值范围采用check 如代码所示 create table student id int not null primary key auto incremen
  • java项目自动化单元测试

    对于我们开发人员来说 单元测试一定不会陌生 但在各种原因下会被忽视 尤其是在我接触到的项目中 提测阶段发现各种各样的问题 我觉得有必要聊一下单元测试 为了写而写的单元测试没什么价值 但一个好的单元测试带来的收益是非常客观的 问题是怎么去写好