川石教育
全国咨询热线:136-9172-9932
  1. 首页 > 资讯与干货 > IT资讯

对JUnit 4的高级操作

作者:川石学院 日期:2021-10-22 17:36:52 点击数:

  一天一个关于测试知识点,5分钟内讲解你最关心的软件测试问题,今天就来谈谈关于软件测试中的“对JUnit 4的高级操作”。

对JUnit 4的高级操作(图1)

  1.@BeforeClass和 @AfterClass

  有一个类是负责对大文件(超过500MB)进行读写,它的每一个方法都是对文件进行操作。换句话说,调用每个方法前,都要打开一个大文件,并读入文件内容,这绝对是一个非常耗时的操作。如果使用@Before和@After,那么每次测试都要读取一次文件,效率极其低下。

  @BeforeClass和@AfterClass两个标识来帮助实现这个功能。顾名思义,用这两个Fixture标注的函数,只在测试用例初始化时执行 @BeforeClass方法,当所有测试执行完毕后,执行@AfterClass方法进行收尾工作。这里要注意,每个测试类只能有一个方法被标注为@BeforeClass或@AfterClass,并且该方法必须是public和static。

  2.防止超时

  比如,程序里存在死循环,如何处理?如在“简单计算器”产品代码中,有语句。

  public void squareRoot(int n) {

  for(; ;) ; // Bug : 死循环

  }

  要实现这一功能,给@Test标注加一个参数即可。

  @Test(timeout=1000) //1000ms

  public void testSquareRoot() {

  calculator.squareRoot(4);

  assertEquals(2,calculator.getResult());

  }

  也就是说,测试用例等待时间1000ms(即1s),如果1s内没有反应,就认为测试失败。

  3.Runner(运行器)

  当测试代码提交给JUnit 4框架后,JUnit 4框架通过Runner如何来运行测试代码。如果不设置,就认为是默认的,但是也可以进行如下设置。

  Import org.junit.internal.runners.TestClassRunner;

  import org.junit.runner.RunWith;

  // 使用了系统默认的TestClassRunner,与下面代码完全一样

  public class CalculatorTest {

  ...

  }

  @RunWith(BlockJUnit4ClassRunner.class)

  public class CalculatorTest {

  ...

  }

  JUnit 4的Runner主要有BlockJUnit4ClassRunner、JUnit38ClassRunner、ParentRunner、Statement、TestRule、Description、RunNotifier、Enclosed和InvokeMethod。其中BlockJUnit4ClassRunner.class是默认的Runner。

  •   Enclosed:是实现内部类中测试类的运行器。

  •   ParentRunner:是JUnit 4测试执行器的基类,它提供了一个测试器所需要的大部分功能。继承它的类需要实现。

  protected abstract ListgetChildren();

  protected abstract Description describeChild(T child);

  protected abstract void runChild(T child,RunNotifier notifier);

  •   Parameterized:则可以设置参数化测试用例。

  •   JUnit38ClassRunner:是为了向后兼容JUnit 3而定义的运行器。

  •   Statement:在运行时,执行testcase前可以插入一些用户动作,它就是描述这些动作的一个类。继承这个类要实现。

  /**

  * Run the action,throwing a {@code Throwable} if anything goes wrong.

  */

  public abstract void evaluate() throws Throwable;

  这个方法会先后在ParentRunner.run()和ParentRunner.runLeaf()这两个方法里面调用。另外,可以自定义一个Statement,并且实现evaluate()方法。

  •   TestRule:可以描述一个或多个测试方法如何运行和报告信息的接口。在TestRule中可以额外加入一些check,可以让一个test case失败/成功,也可以加入一些setup和cleanup要做的事,也可以加入一些log之类的报告信息。总之,跑test case之前的任何事,都可以在里面做。需要实现apply()方法。

  /**

  * Modifies the method-running {@link Statement} to implement this

  * test-running rule.

  * @param base The {@link Statement} to be modified

  * @param description A {@link Description} of the test implemented in {@code base}

  * @return a new statement,which may be the same as {@code base},

  * a wrapper around {@code base},or a completely new Statement.

  */

  Statement apply(Statement base,Description description);

  •   Description:存储着当前单个或多个test case的描述信息。这些信息跟逻辑无关,比如原数据信息等。实例化Description用Description.createTestDescription()方法。

  •   RunNotifier:运行时通知器。执行Runner.run(RunNotifier runNotifier)方法时,需要传一个RunNotifier进去,这个RunNotifier是事件的管理器,它能帮助监控测试执行的情况。

  •   InvokeMethod:最终执行test case里面的测试方法通过这个类来做,这个类会间接调用Method.invoke()方法通知编译器执行@test方法。

  •   ……

  4.参数化测试

  案例2-2:计算某个数的平方。

  测试“计算某个数的平方”这个函数,暂且分3类:正数、0、负数测试代码如下。

  import org.junit.AfterClass;

  import org.junit.Before;

  import org.junit.BeforeClass;

  import org.junit.Test;

  import static org.junit.Assert. * ;

  public class AdvancedTest {

  private static Calculator calculator=new Calculator();

  @Before

  public void clearCalculator() {

  calculator.clear();

  }

  @Test

  public void square1() {

  calculator.square(2);

  assertEquals(4,calculator.getResult());

  }

  @Test

  Public void square2() {

  calculator.square(0);

  assertEquals(0,calculator.getResult());

  }

  @Test

  Public void square3() {

  calculator.square(-3);

  assertEquals(9,calculator.getResult());

  }

  }

  如果用参数化实现代码,就简化成如下形式。

  import static org.junit.Assert.assertEquals;

  import org.junit.Test;

  import org.junit.runner.RunWith;

  import org.junit.runners.Parameterized;

  import org.junit.runners.Parameterized.Parameters;

  import java.util.Arrays;

  import java.util.Collection;

  @RunWith(Parameterized.class)

  public class SquareTest{

  private static Calculator calculator = new Calculator();

  private int param;

  private int result;

  @Parameters

  public static Collectiondata {

  return Arrays.asList( new Object[][] {

  {2,4},

  {0,0},

  {-3,9},

  } );

  }

  // 构造函数,对变量进行初始化

  public void SquareTest(int param,int result) {

  this .param=param;

  this .result =result;

  }

  @Test

  Public void square(){

  calculator.square(param);

  assertEquals(resul,calculator.getResult());

  }

  }

  5.批量测试

  对于批量测试,就是把所有的测试类打成一个包一起运行,其代码如下。

  import org.junit.runner.RunWith;

  import org.junit.runners.Suite;

  @RunWith(Suite.class)

  @Suite.SuiteClasses({

  CalculatorTest.class,

  SquareTest.class

  } )

  public class AllCalculatorTests{

  }


相关文章
  • 亚马逊运营成功转行软件测试,薪资13K表示很满意!2021-10-22 17:36:52
  • 西安川石的兰朋友喊你来当他的学弟学妹啦!2021-10-22 17:36:52
  • 国外的月亮也不一定比国内测试猿的年薪美~2021-10-22 17:36:52
  • 建筑工程专业朱同学成功转行为软件测试人!2021-10-22 17:36:52
  • 财务管理专业转行软件测试月薪甩会计几条街!2021-10-22 17:36:52
  • 只有技术沉淀才能成功上岸,深圳就业薪资13K!2021-10-22 17:36:52
  • 薪资11K!实现自我价值,从掌握一门IT技术开始...2021-10-22 17:36:52
  • 文科生转行软件测试照样拿下高薪15K!2021-10-22 17:36:52
  • 恭喜罗同学喜提19.5K,成功入行软件测试!2021-10-22 17:36:52
  • 毕业1年,迷茫的他最终选择转行软件测试2021-10-22 17:36:52