• 2
  • 3
分享

  单元测试(Unit Testing)又称为模块测试, 是针对程序模块(软件设计的最小单位)来进行正确性检验的测试工作。 程序单元是应用的最小可测试部件。简单来说,就是测试数据的稳定性是否达到程序的预期。谈到测试,我们为什么要对程序进行测试呢?测试会为程序带来什么好处呢?

  我们日常开发时可能在不经意间写错,如果等到最后阶段去检验项目成果时,发现有错误,这时候我们很难找到Bug的源头在哪里。我们都知道,有可能一处出错会导致步步错的情况。

  测试就在我们的上述说法中,显得尤为重要,当我们做完项目的一个小模块,先去测试一下这个小模块是否正确或达到预期,如果错误或者没有达到预期就需要反复修改,直到正确或达到预期,也就是使用了单元测试。

  单元测试的编码规范一般涉及到以下内容:

  类名: 定义测试类,类名是由被测试类名Test构成。例如:CalculatorTest;

  包名:定义的测试类需要放在xxx.xxx.xxx.test包中。例如:package com.autodrive.test;

  方法名: 测试方法的方法名有两种定义方式test测试方法和测试方法。例如:testCheck和check;

  返回值: 因为我们的方法只是在类中测试,可以独立运行,所以不需要处理任何返回值,所以这里使用void。例如:public void check();

  参数列表: 因为我们的方法是用来测试的,至于参数列表的传入是没有必要的。我们在测试的时候自行传入需要的参数测试即可。所以在此参数列表为空。例如:例如:public void check();

  @Test注解: 测试是需要运行来完成的。如果我们只有一个main方法,显然在结构上还是需要我们去注释掉测试过的。解决此问题这里我们需要在测试方法上方加@Test注解来完成测试,只要是加该注解的方法,可以单独运行此方法来完成测试。

  IDEA快捷导入Junit4、5: 使用IDEA的小伙伴,你们的福音来了。我们可以先创建测试类和方法,然后在测试方法上方加入@Test注解,此时IDEA显示的@Test注解是飘红的,这时候我们使用Alt + Enter组合键来打开导入Junit单元测试列表,然后再选择Junit4或者Junit5确定。

  在SpringBoot往往存在单元测试用到如下的注解与写法:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
@Transactional
@Rollback(true) // 事务自动回滚,默认是true。可以不写
public class NoticeServiceTest {
    @Autowired
    private NoticeService noticeService;
    @Test
    public void sayHello() {
        helloService.sayHello("zhangsan");
    }
}

  在上面这个例子中,@SpringBootTest启动了SpringBoot环境,扫描应用程序的spring配置,并构建完整的Spring Context,其classes = Application.class启动了整个项目。通过@SpringBootTest我们可以指定启动类,或者给@SpringBootTest的参数webEnvironment赋值为SpringBootTest.WebEnvironment.RANDOM_PORT,这样就会启动web容器,并监听一个随机的端口,同时,为我们自动装配一个TestRestTemplate类型的bean来辅助我们发送测试请求。

  @Transactional表明调用数据库并作事务处理;@RunWith(SpringRunner.class)声明在Spring的环境中进行单元测试,这样Spring的相关注解就会被识别并起效,而@Autowired启动了Spring。

  当项目使用了@Component注解,在SpringBoot项目启动的时候就会跟着实例化/启动,这个@Component注解的类里有多线程方法,随着启动类中定义的ApplicationStartup类启动了,那么在你执行单元测试的时候,由于多线程任务的影响,就可能对你的数据库造成了数据修改,即使你使用了事务回滚注解。

  高效的单元测试应该脱离数据库,以满足快速启动完成测试、支持服务间调用的需求。可以通过如下几点来对上述例子进行优化:

  1. 启动Spring会让run->Junit Test的时候程序变慢,这是每次运行单元测试都很慢的原因之一。然后单元测试是只针对某一个类的方法来测,启动Spring很多时候是多余的,所以我们只需要对应的实体类实例就够了。在需要注入bean的时候,我们直接new。

private NoticeService noticeService = new NoticeService();

  2. @SpringBootTest是在SpringBoot项目上使用的,它在@SpringBootContextLoader的基础上,配置文件属性的读取,会读取、解析一些项目配置文件,还会连接数据库,然后如果启动类又带有别的启动类、@Component、多线程等,而单元测试很多时候可以避免启动SpringBoot,减少启动所耗费的大量时间,即不使用@SpringBootTest注解。

  3. 应当使用断言来判断单元测试结果是否符合预期。

  4. @RunWith 在JUnit中有很多个Runner,他们负责调用具体测试代码,每一个Runner都有各自的特殊功能,你要根据需要选择不同的Runner来运行你的测试代码,且一般都是使用SpringRunner.class。如果我们只是简单的做普通Java测试,不涉及Spring Web项目,可以省略@RunWith注解,这样系统会自动使用默认Runner来运行你的代码。

  5.单元测试可以通过Mock数据的方式避开对数据库的调用,减少很多数据库连接的时间。Mock是模拟一切操作数据库的步骤,不执行任何SQL,我们直接模拟这句操作数据库的代码执行会是成功的,而且可以模拟任何返回值,主要有两个注解。只要是本地的,自己写的bean,都可以使用@MockBean,它会把所有操作数据库的方法模拟。如果是没有返回值的方法,我们就可以不管。如果是有返回值的方法,我们可以给它返回各自我们需要模拟的值。如果是我们本地,调用别的公司,别的地方给我们写好的接口,不是操作我们自己的数据库,是我们写好入参,别人给我们返回值,我们就用@SpyBean。

  Mock所需依赖如下:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>

  通过以上优化,可以大大缩短我们单测的时间,提高我们开发效率。



作者:王鹏    

来源:http://www.51testing.com/html/19/n-7789619.html

  • 【留下美好印记】
    赞赏支持
登录 后发表评论
+ 关注

热门文章

    最新讲堂

      • 推荐阅读
      • 换一换
          • 功能测试就是对产品的各功能进行验证,根据功能测试用例,逐项测试,检查产品是否达到用户要求的功能。常用的测试方法如下:页面链接检查:每一个链接是否都有对应的页面,并且页面之间切换正确。相关性检查:删除/增加一项会不会对其他项产生影响,如果产生影响,这些影响是否都正确。检查按钮的功能是否正确:如update,cancel,delete,save等功能是否正确。字符串长度检查:输入超出需求所说明的字符串长度的内容,看系统是否检查字符串长度,会不会出错.字符类型检查:在应该输入指定类型的内容的地方输入其他类型的内容(如在应该输入整型的地方输入其他字符类型),看系统是否检查字符类型,会否报错.标点符号检...
            0 0 935
            分享
          •   大家好,今天给大家分享一个写代码的设计模式,就是我们最最耳熟能详的单例设计模式。  可能很多人都听说过这个单例设计模式了,甚至都写的贼溜,但是今天给大家说说用这个这个单例设计模式,咱们是怎么把代码的性能大幅度提升的,单例模式跟代码性能的关系,恐怕很多兄弟还没认真研究过呢!  一次请求执行流程  首先我们先来看看什么叫做单例模式,要理解单例模式,我们就得先说说不用单例模式的时候,我们平时创建对象是怎么弄的。  平时创建对象这个简单吧,比如我们搞一个对外的web接口,然后再接口收到一个请求的时候,就创建一个对象。  这个伪代码如下:  @RestController("/user&q...
            0 0 1116
            分享
          •   2012 年,当 Facebook 的用户数量达到 10 亿时,首席执行官马克-扎克伯格(Mark Zuckerberg)表示,要想再获得 10 亿用户,"最重要的显然是移动"。 在当时的一次采访中,扎克伯格对布鲁姆伯格说:"随着越来越多的手机变成智能手机,这将是一个巨大的机遇"。  显然,他是正确的。 全球移动通信系统协会情报部门(GSMA)是总部设在英国的一家代表全球移动运营商的组织,其研究部门最近的一项调查发现,全球目前有 46 亿人连接到移动互联网,约占全球人口的 57%;  然而到了现在,新增移动互联网用户的增长速度正在放缓。 从 2015...
            0 0 24
            分享
          • 这是时常被问到的问题,尤其是UI自动化的运行,过程非常耗时,所以,所以多线程不失为一种首先想到的解决方案。多线程是针对的测试用例,所以和selenium没有直接关系,我们要关心的是单元测试框架。unittest首先,应该说明的是unittest本身是不支持多线程的。当然,如果你学过Python的threading模块,也未必不行。不过我在stackoverflow 找了半天,大多是介绍unittest 测试多线程模块,并非是unittest本身如何多线程运行用例。“我如何学习葵花宝典” 和 “我如何验证 张三 学会了葵花宝典”是两回事,而我显然要解决的问题是前者。又重新百度,结果就找了答案。核...
            0 0 2175
            分享
          •   JVM内存是我们在系统部署、优化、问题排查中的一项重要内容,在最近支持的几个项目中,多次出现与JVM内存相关的问题,因此有必要加强一下实施人员对JVM内存的理解,从而更好地应对今后可能再次出现的问题。  关于JVM内存相关理论的文章,网上有很多,下面的内容是参照网络文章并结合我们实际工作中的问题做出的一些总结,重点在JVM的内存结构上,供大家参考。  公式一  JVM在我们看来,就是一个java进程,无论我们的系统使用的是tomcat、weblogic、还是websphere,系统起来后对应的就是一个java进程。这个java进程的内存组成可以粗略的用下面的公式来表示:  JAVA进程内存...
            13 13 1476
            分享
      • 51testing软件测试圈微信