你知道 Junit 是怎么跑的吗?

发表于:2021-7-08 09:44

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

 作者:磊叔_GLMapper    来源:掘金

#
JUnit
分享:
  Junit 是由 Kent Beck 和 Erich Gamma 于 1995 年底着手编写的框架,自此以后,Junit 框架日益普及,现在已经成为单元测试 Java 应用程序的事实上的标准。
  在软件开发领域中,从来没有这样的事情:少数几行代码对大量代码起着如此重要的作用  --- Martin Fowler
  从一个简单的例子开始认识 Junit
  本文注重点在于研究 Junit 运行的基本原理和执行单元测试的流程,所以对于一些额外的信息和数据不单独准备,本文所使用的测试 case 如下:
  package com.glmapper.bridge.boot;
  import org.junit.*;
  public class JunitSamplesTest {
      @Before
      public void before(){
          System.out.println(".....this is before test......");
      }
      @After
      public void after(){
          System.out.println(".....this is after test......");
      }
      @BeforeClass
      public static void beforeClass(){
          System.out.println(".....this is before class test......");
      }
      @AfterClass
      public static void afterClass(){
          System.out.println(".....this is after class test......");
      }
      @Test
      public void testOne(){
          System.out.println("this is test one");
      }
      @Test
      public void testTwo(){
          System.out.println("this is test two");
      }
  }
  执行结果如下:
  .....this is before class test......
  Disconnected from the target VM, address: '127.0.0.1:65400', transport: 'socket'
  .....this is before test......
  this is test one
  .....this is after test......
  .....this is before test......
  this is test two
  .....this is after test......
  .....this is after class test......
  从代码和执行结果来看,BeforeClass 和 AfterClass 注解分别在测试类开始之前和之后执行,Before 和 After 注解在测试类中每个测试方法的前后执行。
  问题域
  从开发者的角度来看,对于任何一个技术产品组件,如果想要更好的使用它,就意味着必须了解它。通过上面提供的 case 可以看到,Junit  使用非常简单,基本 0 门槛上手,通过给测试的方法加一个 @Test 注解,然后将待测试逻辑放在 被 @Test 标注的方法内,然后 run 就好了。简单源于组件开发者的顶层抽象和封装,将技术细节屏蔽,然后以最简洁的 API 或者注解面向用户,这也是 Junit 能够让广大开发者容易接受的根本原因,值得我们借鉴学习。
  回归正题,基于上面分析,Junit 使用简单在于其提供了非常简洁的 API 和注解,那对于我们来说,这些就是作为分析 Junit 的基本着手点;通过这些,来拨开 Junit  的基本原理。基于第一节的小案例,这里抛出这样几个问题:
  · Junit 是怎么触发执行的
  · 为什么被标注 @Test 注解的方法会被执行,而没有标注的不会
  · Before 和 After 执行时机
  · BeforeClass 和 AfterClass 执行时机
  · Junit 是怎么将执行结果收集并返回的(这里不关注 IDE 提供的渲染)
  Junit 是如何执行的?
  这里把断点直接打在目标测试方法位置,然后 debug 执行。
  通过堆栈来找到用例执行的整个路径。因为本 case 是通过 idea 启动执行,所以可以看到的入口实际是被 idea 包装过的。但是这里也抓到了 JUnitCore 这样的一个入口。
  JUnitCore  是运行测试用例的门面入口,通过源码注释可以看到,JUnitCore 从 junit 4 才有,但是其向下兼容了 3.8.x 版本系列。我们在跑测试用例时,其实大多数情况下在本地都是通过 IDE 来触发用例运行,或者通过 mvn test 来运行用例,实际上,不管是 IDE 还是 mvn 都是对 JUnitCore 的封装。我们完全可以通过 main 方法的方式来运行,比如运行下面代码的 main 方法来通过一个 JUnitCore 实例,然后指定被测试类来触发用例执行,为了尽量使得堆栈更贴近 Junit 自己的代码,我们通过这种方式启动来减少堆栈对于代码执行路径的干扰。
  public class JunitSamplesTest {
      @Before
      public void before(){
          System.out.println(".....this is before test......");
      }
      @After
      public void after(){
          System.out.println(".....this is after test......");
      }
      @BeforeClass
      public static void beforeClass(){
          System.out.println(".....this is before class test......");
      }
      @AfterClass
      public static void afterClass(){
          System.out.println(".....this is after class test......");
      }
      @Test
      public void testOne(){
          System.out.println("this is test one");
      }
      @Test
      public void testTwo(){
          System.out.println("this is test two");
      }
      public static void main(String[] args) {
          JUnitCore jUnitCore = new JUnitCore();
          jUnitCore.run(JunitSamplesTest.class);
      }
  }
  这里得到了最简化的测试执行入口:
  如果使用 java 命令来引导启动,其实就是从 JunitCore 内部自己的 main 方法开始执行的。
  /** 
   * Run the tests contained in the classes named in the args. If all tests run successfully, exit with a status of 0. Otherwise exit with a status of 1. Write
   * feedback while tests are running and write stack traces for all failed tests after the tests all complete.
   * Params:
   * args – names of classes in which to find tests to run
   **/
  public static void main(String... args) {
      Result result = new JUnitCore().runMain(new RealSystem(), args);
      System.exit(result.wasSuccessful() ? 0 : 1);
  }

  本文内容不用于商业目的,如涉及知识产权问题,请权利人联系51Testing小编(021-64471599-8017),我们将立即处理
精选软件测试好文,快来阅读吧~

关注51Testing

联系我们

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

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

沪ICP备05003035号

沪公网安备 31010102002173号