前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >单元测试工具(连载3)

单元测试工具(连载3)

作者头像
顾翔
发布2019-12-12 13:14:21
3870
发布2019-12-12 13:14:21
举报

1.4 对JUnit 4的高级操作

1.@BeforeClass和 @AfterClass

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

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

2.防止超时

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

publicvoid squareRoot(int n) {

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

}

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

@Test(timeout=1000)//1000ms

publicvoid 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 classCalculatorTest {

...

}

@RunWith(BlockJUnit4ClassRunner.class)

public class CalculatorTest {

...

}

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

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

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

protectedabstract List<T> getChildren();

protectedabstract Description describeChild(T child);

protectedabstract void runChild(T child,RunNotifier notifier);

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

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

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

/**

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

*/

publicabstract void evaluate() throws Throwable;

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

lTestRule: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 {@linkStatement} to be modified

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

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

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

*/

Statement apply(Statementbase,Description description);

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

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

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

l……

4.参数化测试
案例2:计算一个数的平方。

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

import org.junit.AfterClass;

import org.junit.Before;

import org.junit.BeforeClass;

import org.junit.Test;

import static org.junit.Assert. * ;

publicclass AdvancedTest {

privatestatic Calculator calculator=newCalculator();

@Before

publicvoid 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 Collection<Object[]>data {

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{

}

星云测试

http://www.teststars.cc

奇林软件

http://www.kylinpet.com

联合通测

http://www.quicktesting.net

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-07-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 软件测试培训 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.4 对JUnit 4的高级操作
    • 1.@BeforeClass和 @AfterClass
      • 2.防止超时
        • 3.Runner(运行器)
          • 4.参数化测试
            • 案例2:计算一个数的平方。
          • 5.批量测试
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档