JAVA自动化之Junit单元测试框架详解(上)

发表于:2021-4-19 09:23

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:逍遥子    来源:CSDN

  一、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),我们将立即处理
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号