一、JUnit概述&配置
1、Junit是什么?
Junit是一个Java 编程语言的开源测试框架,用于编写和运行测试。官网 地址:https://junit.org/junit4/
2、Maven配置
xml version="1.0" encoding="UTF-8"?> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
4.0.0
junit
junitTest
0.0.1-SNAPSHOT
pom
junit
junit
4.12
二、Assertions 断言
JUnit提供了一些辅助的函数,用来判断被测试的方法是否如我们预期的效果一样正常执行。这些辅助函数被称之为断言。
三、Test Runners 测试运行器
JUnit中所有的测试方法都是由测试运行器负责执行。当一个类被@RunWith注释或拓展了一个@RunWith注释的类,JUnit将会使用引用的类来执行测试,而不是使用JUnit内置的运行器。
org.junit.runner.JUnitCore.runClasses(TestClass1.class, ...); |
Suite:Suite是一个标准的运行器,允许手动构建包含来自许多类的测试集。
Parameterized:Parameterized是一个实现参数化测试的标准运行器。运行参数化测试类时,测试方法和测试数据进行合并来创建测试实例。
Categories:Categories运行器来制定分类,定义测试被包含或排除。
四、Aggregating tests in suites 套件
测试套件用于捆绑几个单元测试用例并且一起执行他们,使用@RunWith 和 @Suite 注解。
@RunWith(Suite.class) @Suite.SuiteClasses({AssertTests.class, CalculatorTest.class}) public class SuiteTest { // the class remains empty, used only as a holder for the above annotations} |
五、Test execution order 执行顺序
要改变测试执行的顺序只需要在测试类上使用 @FixMethodOrder注解,并指定一个可用的MethodSorter即可:
@FixMethodOrder(MethodSorters.DEFAULT):JUnit默认使用一个确定的,但不可预测的顺序。
@FixMethodOrder(MethodSorters.JVM): 保留测试方法的执行顺序为JVM返回的顺序,每次测试的执行顺序有可能会所不同。
@FixMethodOrder(MethodSorters.NAME_ASCENDING):根据测试方法的方法名排序,按照词典排序规则(ASC从小到大递增)。
@FixMethodOrder(MethodSorters.NAME_ASCENDING) public class ExecutionOrderTest { @Test public void testB() { System.out.println("second"); } @Test public void testA() { System.out.println("first"); } @Test public void testC() { System.out.println("third"); } } |
运行结果:
first second third |
六、Expected Exceptions 异常测试
用于测试某一方法是否抛出了正确的异常。
1、@Test(expected=xxx)方式:当抛出的异常与expected参数指定的异常相同时,测试通过。
2、try...fail...catch...方式:捕捉具体待测语句的异常信息并断言,当没有异常被抛出的时候fail方法会被调用,输出测试失败的信息。
3、ExpectedException Rule方式:使用Rule标记来指定一个ExpectedException,并在测试相应操作之前指定期望的Exception类型。
public class ExpectedExceptionsTest { //方法一:@Test(expected=xxx) @Test(expected = IndexOutOfBoundsException.class) public void empty() { new ArrayList().get(0); } //方法二:try...fail...catch... 当没有异常被抛出的时候fail方法会被调用,输出测试失败的信息。 @Test public void testExceptionMessage() { try { new ArrayList().get(0); fail("Expected an IndexOutOfBoundsException to be thrown"); } catch (IndexOutOfBoundsException anIndexOutOfBoundsException) { assertThat(anIndexOutOfBoundsException.getMessage(), is("Index: 0, Size: 0")); } } //方法三:在测试之前使用Rule标记来指定一个ExpectedException,并在测试相应操作之前指定期望的Exception类型(如IndexOutOfBoundException.class) @Rule public ExpectedException thrown = ExpectedException.none(); @Test public void shouldTestExceptionMessage() throws IndexOutOfBoundsException { List list = new ArrayList(); thrown.expect(IndexOutOfBoundsException.class); thrown.expectMessage("Index: 0, Size: 0"); list.get(0); } } |
七、Matchers and assertThat
JUnit4.4引入了Hamcrest框架,Hamcest提供了一套匹配符Matcher,这些匹配符更接近自然语言,可读性高,更加灵活。并且使用全新的断言语法assertThat,结合Hamcrest提供的匹配符,只用这一个方法,就可以实现所有的测试。
assertThat语法:
assertThat(T actual, Matcher matcher); assertThat(String reason, T actual, Matcher matcher); |
其中reason为断言失败时的输出信息,actual为断言的值或对象,matcher为断言的匹配器,里面的逻辑决定了给定的actual对象满不满足断言。
Matchers详见:
http://hamcrest.org/JavaHamcrest/javadoc/1.3/org/hamcrest/Matchers.html
八、Ignoring tests 忽略测试方法用 @Ignore 注解了将不会被执行
类用 @Ignore 注解后,其下所有测试方法将不会被执行
public class IgnoreTest { @Ignore("Test is ignored as a demonstration") @Test public void testSame() { assertThat(1, is(1)); } } |
九、Timeout for tests 超时测试
@Timeout 注解用来测试特定方法的执行时间。如果测试方法的执行时间大于指定的超时参数,测试方法将抛出异常,测试结果为失败。指定的超时参数单位为毫秒。
1、@Test注解上的timeout参数,作用域为方法,单位毫秒
@Test(timeout = 2000) public void testSleepForTooLong() throws Exception { log += "ran1"; TimeUnit.SECONDS.sleep(100); // sleep for 100 seconds } |
2、Timeout Rule,作用域为测试类
public class TimeoutTests { public static String log; private final CountDownLatch latch = new CountDownLatch(1); @Rule public Timeout globalTimeout = Timeout.seconds(3); // 3 seconds max per method tested @Test public void testSleepForTooLong() throws Exception { log += "ran1"; TimeUnit.SECONDS.sleep(100); // sleep for 100 seconds } @Test public void testBlockForever() throws Exception { log += "ran2"; latch.await(); // will block } } |
十、Parameterized tests 参数化测试
参数化测试允许开发人员使用不同的值反复运行同一个测试。创建参数化测试步骤:用 @RunWith(Parameterized.class) 来注释 test 类。
创建一个由 @Parameters 注释的公共的静态方法,它返回一个对象的集合(数组)来作为测试数据集合。
创建一个公共的构造函数,接受测试数据。
为每一列测试数据创建一个实例变量。
用实例变量作为测试数据的来源来创建测试用例。
1、Constructor方式
@RunWith(Parameterized.class) public class FibonacciTest { @Parameters(name = "{index}: fib({0})={1}") public static Collection data() { return Arrays.asList(new Object[][] { { 0, 0 }, { 1, 1 }, { 2, 1 }, { 3, 2 }, { 4, 3 }, { 5, 5 }, { 6, 8 } }); } private int fInput; private int fExpected; public FibonacciTest(int input, int expected) { this.fInput = input; this.fExpected = expected; } @Test public void test() { assertEquals(fExpected, Fibonacci.compute(fInput)); } } |
2、Field injection方式
@RunWith(Parameterized.class) public class FibonacciTest { @Parameters(name = "{index}: fib({0})={1}") public static Collection data() { return Arrays.asList(new Object[][] { { 0, 0 }, { 1, 1 }, { 2, 1 }, { 3, 2 }, { 4, 3 }, { 5, 5 }, { 6, 8 } }); } @Parameter // first data value (0) is default public /* NOT private */ int fInput; @Parameter(1) public /* NOT private */ int fExpected; @Test public void test() { assertEquals(fExpected, Fibonacci.compute(fInput)); } } |
本文内容不用于商业目的,如涉及知识产权问题,请权利人联系51Testing小编(021-64471599-8017),我们将立即处理