JUnit单元测试详解

JUnit简介

        JUnit适用于编写可复用测试集的简单框架

        JUnit测试是程序员测试,即白盒测试,因为程序员知道被测试的软件如何完成功能和完成什么功能

        

JUnit优点

       Junit是极限编程和重构中被极力推荐的工具,因为在实现自动单元测试的情况下可以大大提高开发的效率,但是实际上编写测试代码也是需要大量精力和时间的,那么关于JUnit的优点体现在哪儿呢?

  1.  极限编程:要求在编写代码之前先写测试,这样可以强制你在写代码之前好好思考代码的功能和逻辑,否则编写的代码不稳定,那么你需要同时维护测试和实际代码,这个工作量就会大大增加。因此在极限编程中,基本过程是这样的:构思 -> 编写测试代码 -> 编写代码 ->测试,而且编写测试和编写代码都是增量式的,写一点测一点,在编写以后的代码如果发现问题可以更快追踪到问题的原因,减少回归错误的纠错难度
  2. 重构:其好处和极限编程是类似的,因为重构也是改一点测一点,减少回归错误减少的时间消耗
  3. 其他情况:我们在开发的时候用JUnit写一些适当测试也是必要的,因为一般我们也是要编写测试的代码的,可能原来用的不是Junit,但是如果使用JUnit,而且针对接口方法编写测试代码会减少以后的维护工作,例如以后对方法内部的修改,这相当于是重构的工作了,另外就是Junit有断言功能,如果测试结果不通过会告诉我们拿个不通过,因此使用JUnit的好处便是这个结果是否正确的判断是他自己完成的,我们只需要看看它告诉我们结果是否正确就可以了,在一般情况下会大大提高效率

为什么要使用JUnit

  1. 测试框架可以帮助我们对编写的程序进行有目的的测试,帮助我们最大限度地避免代码中的bug,以保证系统的正确性和稳定性
  2. JUnit的断言机制,可以直接将我们的预期结果和程序运行的结果进行一个比对,确保对结果的可预知性
  •      编写代码时,我们总是会作出一些假设,断言就是在代码中捕获这些假设
    • 可以将断言看成异常处理的一种高级形式
    • 断言便是为一些布尔表达式,程序员相信在程序中的某个特定点该表达式为真

JUnit常用注解

  • @AfterClass:所修饰的方法会在所有方法运行结束后被执行,static修饰,只执行一次
  • @BeforeClass:所修饰的方法会在所有方法运行结束前被执行,static修饰,只执行一次
  • @Test:将一个普通方法修饰为测试方法
    • @Test(timeout=毫秒)                        //可以作为性能测试
    • @Test(expected=XX.class)
      • @Test(expected=ArithmeticException.class):预期被测方法是否抛出对应的异常
  • @Before:会在每一个测试方法运行之前执行一次
  • @After:会在每一个测试方法运行之后测试一次
  • @Ignore:所修饰的测试方法会被测试运行器忽略
  • @RunWith:可以更改测试运行器org.junit.runner.Runner

一个JUnit4大的单元测试用例执行顺序为:@BeforeClass > @Before > @Test > @After > @AfterClass

每一个测试方法的调用顺序为:@Before -> @Test -> @After

JUnit4与JUnit5的区别

特性 Junit4 Junit5
在当前类的所有测试方法之前执行。注解在静态方法上。此方法可以包含一些初始化代码 @BeforeClass @BeforeAll
在当前类的所有测试方法之后执行。注解在静态方法上。此方法可以包含一些清理代码 @AfterClass @AfterAll
在每个测试方法之前执行。注解在非静态方法上。可以重新初始化测试方法所需要使用的类的某些属性 @Before

@BeforeEach

在每个测试方法之后 执行。注解在非静态方法上。可以回滚测试方法引起的数据库修改 @After @AfterEach

JUnit测试套件使用及参数化设置

@RunWith注解:当类被@RunWith注解修饰,或者类继承了一个被该注解修饰的类,JUnit将会使用注解所指明的运行器来运行测试,而不是JUnit默认的运行器

   JUnit测试套件

JUnit单元测试详解_第1张图片

说明:

  •   使用@RunWith注解,修改运行测试器。例如@RunWith(Suite.class),这个类就成为测试套件的入口类
  •   @Suite.SuiteClasses()中放入测试套件的测试类,以数组的形式{class1,class2,...}作为参数

    JUnit参数化设置

        如果测试代码大同小异,代码结构都是相同的,不同的只是测试的数据和预期值,那么有没有更好的办法将相同的代码结构提取出来,提高代码的重用度呢?

解决:进行参数化测试

  步骤:
  1. 要进行参数化测试,需要在类上面指定如下的运行器:@RunWith(Parameterized.class)
  2. 然后在提供数据的方法上加一个@Parameter注解,这个方法必须是静态static的,并且返回一个集合Collection;
  3. 在测试类的构造方法为各个参数赋值(构造方法是由JUnit调用的),最后编写测试类,它会根据参数的组数来运行测试很多次

JUnit单元测试详解_第2张图片

(运行结果如下图,可以知道该测试类同时测了提供的三组数据)

JUnit单元测试详解_第3张图片

JUnit断言

  断言概述

    断言是编程术语,表示为一些布尔表达式,程序员相信在程序中的某个特定点该表达式为真,可以在任何时候启动和禁用断言验证因此可以在测试时启用断言而在部署时禁用断言。同样,程序投入运行后,最后用户在遇到问题时可以重新启动断言。

    使用断言可以创建更稳定,品质更好且不易出错的代码。当需要在一个值为FALSE时只中断当前操作的话,可以使用断言。单元测试必须使用断言(Junit/JunitX)

  断言方法

这个类提供了很多有用的断言方法来编写测试用例。只有失败的断言才会被记录。Assert类中有一些有用的方法列示如下

Method Description
assertNull(Object o) 检查对象是否为空
assertNotNull(Object o) 检查对象是否不为空
assertEquals(long expected,long actual) 检查long类型值是否相等
assertEquals(double expected,double actual,double delta 检查指定精度的double值是否相等
assertFalse(boolean condition) 检查条件是否为假
assertTrue(boolean condition) 检查条件是否为真
assertSame(Object expected,Object actual) 检查两个对象引用是否引用同一对象(即对象是否相等)
assertNotSame(Object expected,Object actual) 检查两个对象引用是否不引用同一对象(即对象是否不等)

注意:对象相同与内容相同有一定区别

JUnit单元测试详解_第4张图片

  

JUnit单元测试详解_第5张图片

你可能感兴趣的:(测试,junit,单元测试,java)