参考文档:单元测试(三)了解JUnit包

1. JUnit 注解

1.1. @Test

  1. (expected=XXException.class) 如果程序的异常和 XXException.class 一样,则测试通过
  2. (timeout=100)如果程序的执行能在100毫秒之内完成,则测试通过

1.2. @Ignore

被忽略的测试方法:加上之后,暂时不运行此段代码

1.3. @Before

每一个测试方法之前运行

1.4. @After

每一个测试方法之后运行

1.5. @BeforeClass

方法必须必须要是静态方法(static 声明),所有测试开始之前运行,注意区分before,是所有测试方法

1.6. @AfterClass

方法必须要是静态方法(static 声明),所有测试结束之后运行,注意区分 @After

1.7. @RunWith

首先要分清几个概念:测试方法、测试类、测试集、测试运行器。

其中测试方法就是用@Test注解的一些函数。

测试类是包含一个或多个测试方法的一个**Test.java文件。

测试集是一个suite,可能包含多个测试类。

测试运行器则决定了用什么方式偏好去运行这些测试集/类/方法。而@Runwith就是放在测试类名之前,用来确定这个类怎么运行的。也可以不标注,会使用默认运行器。运行器将在后续3.3章节做详细解释。

1.8. @Rule

Rule是JUnit4.7加入的新特性,有点类似于拦截器,用于在测试方法执行前后添加额外的处理。实际上是@Before,@After的另一种实现。使用时需要放在实现了TestRule的成员变量上或者返回TestRule的方法上,且修饰符为public。Rule会应用于该类每个测试方法。

Rule的详情见3.4章节。

1.9. @ClassRule

junit中的@classrule,可以在所有类方法开始前进行一些初始化调用,比如创建临时文件,@ClassRule中指定创建临时文件夹,这是在所有的测试方法前会创建文件夹,并且会在所有测试完成后,递归删除其下的子目录和子文件夹。@Rule是方法级别的,每个测试方法执行时都会调用被注解的Rule,而@ClassRule是类级别的,在执行一个测试类的时候只会调用一次被注解的Rule。

1.10. @FixMethodOrder

Junit 4.11里增加了指定测试方法执行顺序的特性,测试类的执行顺序可通过对测试类添加注解 “@FixMethodOrder(value)” 来指定,其中value 为执行顺序,三种执行顺序可供选择:默认(MethodSorters.DEFAULT),按方法名(MethodSorters.NAME_ASCENDING)和JVM(MethodSorters.JVM),当没有指定任何顺序时,按默认来执行。

  1. MethodSorters.DEFAULT
    默认顺序由方法名hashcode值来决定,如果hash值大小一致,则按名字的字典顺序确定
    由于hashcode的生成和操作系统相关(以native修饰),所以对于不同操作系统,可能会出现不一样的执行顺序,在某一操作系统上,多次执行的顺序不变

  2. MethodSorters.NAME_ASCENDING (推荐)
    按方法名称的进行排序,由于是按字符的字典顺序,所以以这种方式指定执行顺序会始终保持一致;
    不过这种方式需要对测试方法有一定的命名规则,如 测试方法均以testNNN开头(NNN表示测试方法序列号 001-999)

  3. MethodSorters.JVM
    按JVM返回的方法名的顺序执行,此种方式下测试方法的执行顺序是不可预测的,即每次运行的顺序可能都不一样(JDK7里尤其如此).

1.11. @Sql

在写单元测试时,往往需要在数据库中准备对应的测试数据。我们可以在测试用例中,通过代码的方式往数据库中插入数据。但这么做会使测试代码比较臃肿。个人觉得,通过sql脚本去导入数据,再结合@Transactional注解对数据进行回滚,是一种更好的方案。

为此,spring为我们准备了很有用的注解@Sql。@Sql注解可以执行SQL脚本,也可以执行SQL语句。它既可以加上类上面,也可以加在方法上面。默认情况下,方法上的@Sql注解会覆盖类上的@Sql注解,但可以通过@SqlMergeMode注解来修改此默认行为。

@Sql有下面的属性:

  • config:与注解@SqlConfig作用一样,用来配置“注释前缀”,“分隔符”等。

  • executionPhase:决定SQL脚本或语句什么时候会执行,默认是BEFORE_TEST_METHOD。

  • statements:配置要一起执行的SQL语句。

  • scripts:配置SQL脚本路径。

  • value:scripts的别名,它不能和scripts同时配置,但statements可以。

1.12. @SqlConfig

@SqlConfig用于配置如何去解释@Sql注解中指定的Sql脚本。

@SqlConfig可以用于类上,也可以用于方法上。

@Sql注解也有一个config属性,作用与@SqlConfig相同,不同的是作用域只在对应的@Sql注解范围。它的优先级也大于类注解的@SqlConfig。

blockCommentStartDelimiter:多行注释开始字符,默认是/*。

blockCommentEndDelimiter:多行注释结束字符,默认是*/。

commentPrefix:单行注释前缀,默认是–。

commentPrefixes:指定多个单行注释前缀,默认是[“–”]。

dataSource:指定脚本执行的数据库的名字,只有在多个数据源时需要指定。

encoding:指定sql脚本文件的字符编码。

errorMode:配置错误模式,默认是SqlConfig.ErrorMode的DEFAULT。

separator:配置脚本语句分隔符,默认是’\n’。

transactionManager:指定transactionManager bean,只有有多个transactionManager时需要指定。

transactionMode:指定脚本执行的事务模式,默认是SqlConfig.TransactionMode的DEFAULT。

1.13. @SqlMergeMode

@SqlMergeMode可以加在类上,也可以加在方法上。用于指示方法上的@Sql和类上@Sql注解配置是否合并。方法上的@SqlMergeMode注解优先级更高。默认值是SqlMergeMode.MergeMode的OVERRIDE。

2. JUnit常用类

2.1. Test接口

Test接口使用了Composite设计模式,是单独测试用例 (TestCase),聚合测试模式(TestSuite)及测试扩展(TestDecorator)的共同接口。 它的public int countTestCases()方法,它来统计这次测试有多少个TestCase,另外一个方法就是public voidrun( TestResult ),TestResult是实例接受测试结果, run方法执行本次测试。

2.2. TestCase抽象类

TestCase是Test接口的抽象实现,(不能被实例化,只能被继承)其构造函数TestCase(string name)根据输入的测试名称name创建一个测试实例。由于每一个TestCase在创建时都要有一个名称,若某测试失败了,便可识别出是哪个测试失败。

TestCase类中包含的setUp()、tearDown()方法。setUp()方法集中初始化测试所需的所有变量和实例,并且在依次调用测试类中的每个测试方法之前再次执行setUp()方法。tearDown()方法则是在每个测试方法之后,释放测试程序方法中引用的变量和实例。

开发人员编写测试用例时,只需继承TestCase,来完成run方法即可,然后JUnit获得测试用例,执行它的run方法,把测试结果记录在TestResult之中。(Junit3的用法,Junit4就是用注解实现)

2.3. Assert静态类

JUnit 提供了6大类31组断言方法,包括基础断言、数字断言、字符断言、布尔断言、对象断言。

Assert类主要的静态成员

  1. AreEqual:方法被重载了N多次,主要功能是判断两个值是否相等;如果两个值不相等,则测试失败。
  2. AreNotEqual:方法被重载了N多次,主要功能是判断两个值是否不相等;如果两个值相等,则测试失败。
  3. AreNotSame:引用的对象是否不相同;如果两个输入内容引用相同的对象,则测试失败.
  4. AreSame:引用的对象是否相同;如果两个输入内容引用不相同的对象,则测试失败
  5. Fail:断言失败。
  6. Inconclusive:表示无法证明为 true 或 false 的测试结果
  7. IsFalse:指定的条件是否为 false;如果该条件为 true,则测试失败。
  8. IsTrue:指定的条件是否为 true;如果该条件为 false,则测试失败
  9. IsInstanceofType:测试指定的对象是否为所需类型的实例;如果所需的实例不在该对象的继承层次结构中,则测试失
  10. IsNotInstanceofType: 测试指定的对象是否为所需类型的实例;如果所需的实例在该对象的继承层次结构中,则测试失败
  11. IsNull:测试指定的对象是否为非空
  12. IsNotNull:测试指定的对象是否为非空

Assert类的使用

  1. Assert类所在的命名空间为Microsoft.VisualStudio.TestTools.UnitTesting 在工程文件中只要引用Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll就可以使用了。
  2. 使用Assert类可以对特定功能进行验证,单元测试方法执行开发代码中的方法代码,但只有包含Assert语句时才能报告代码行为方面的内容。
  3. Assert在测试方法中,可以调用任意数量的Assert类方法,如Assert.AreEqual()方法。Assert类有很多方法可供选择,其中许多方法具有多个重载。
  4. 使用CollectionAssert类可比较对象集合,也可以验证一个或多个集合的状态。
  5. 使用StringAssert类可以对字符串进行比较。此类包含各种有用的方法。如:StringAssert.Contains、StringAssert.Matches和StringAssert.StartWith。
  6. AssertFailedException只要测试失败,就会引发AssertFailedException异常。如果测试超时,引发意外的异常,或包含生成了Failed结果的Assert语句,则测试失败。
  7. AssertInconclusiveException只要测试生成的结果是Inconclusive,就会引发AssertInconclusiveException。通常,向仍在处理的测试添加Assert.Inconclusive来指明该测试尚未准备好,不能运行。

2.4. TestSuite测试包类

TestSuite类负责组装多个Test Cases。待测得类中可能包括了对被测类的多个测试,而TestSuit负责收集这些测试,使我们可以在一个测试中,完成全部的对被测类的多个测试。 TestSuite类实现了Test接口,且可以包含其它的TestSuites。它可以处理加入Test时的所有抛出的异常。 TestSuite处理测试用例有6个规约(否则会被拒绝执行测试)

  1. 测试用例必须是公有类(Public)
  2. 测试用例必须继承与TestCase类
  3. 测试用例的测试方法必须是公有的( Public )
  4. 测试用例的测试方法必须被声明为Void
  5. 测试用例中测试方法的前置名词必须是test
  6. 测试用例中测试方法误任何传递参数

2.5. TestResult结果类和其它类与接口

TestResult结果类集合了任意测试累加结果,通过TestResult实例传递个每个测试的Run()方法。TestResult在执行TestCase是如果失败会异常抛出 TestListener接口是个事件监听规约,可供TestRunner类使用。它通知listener的对象相关事件,方法包括测试开始startTest(Test test),测试结束endTest(Test test),错误,增加异常addError(Test test,Throwable t)和增加失败addFailure(Test test,AssertionFailedError t) TestFailure失败类是个“失败”状况的收集类,解释每次测试执行过程中出现的异常情况。其toString()方法返回“失败”状况的简要描述

3. Junit的运行器

3.1. 什么是Runner,@RunWith()到底有什么用?

Runner是Junit的运行器,即运行测试用例的工具。

我们可以在测试类之上,使用@RunWith()注解为这个类指定一个特定的Runner。当我们没有指定@RunWith()的时候,会自动使用Junit的默认Runner——BlockJunit4ClassRunner。

3.2. 常用的Runner

Suite:测试套件 ;

Category:按种类区分的套件;

Parameterized:参数化测试;

Theories:排列组合。

4. Junit的Rule使用

Rule是JUnit4.7加入的新特性,有点类似于拦截器,用于在测试方法执行前后添加额外的处理。实际上是@Before,@After的另一种实现。使用时需要放在实现了TestRule的成员变量上或者返回TestRule的方法上,且修饰符为public。Rule会应用于该类每个测试方法。

4.1. Verifier

所有测试结束后对测试执行结果添加额外的逻辑验证测试最终成功与否。该抽象类为子类提供一个接口方法verify()供扩展

4.2. ErrorCollector

是Verifier类的一个子类实现,用于在测试执行过程中收集错误信息,不会中断测试,最后调用verify()方法处理。

4.3. TemporaryFolder

是抽象类ExternalResource的一个子类实现,用于在JUnit测试执行前后,创建和删除临时目录

4.4. TestName

是抽象类TestWatcher的一个子类实现,用于在测试执行过程中获取测试方法名称。在starting()中记录测试方法名,在getMethodName()中返回

4.5. TestWatcher

监视测试方法生命周期的各个阶段。该抽象类为子类提供了五个接口方法succeeded(), failed(), skipped(), starting()及finished()供扩展

4.6. Timeout

与@Test中的timeout相对应,@Test只能修饰待测试方法,Timeout可以修饰待测试类

ExpectedException:与@Test中的expected相对应,提供更强大灵活的异常验证功能,@Test只能修饰待测试方法,ExpectedException可以修饰待测试类

4.7. 自定义Rule

当内置的Rule无法满足你的需求的时候,你还可以通过实现TestRule来自定义Rule。

地址:https://blog.csdn.net/weixin_34399060/article/details/93886426