使用 JUnit 进行 Java 代码的单元测试

发表于:2013-10-14 11:54

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

 作者:Bairrfhoinn    来源:51Testing软件测试网采编

  另外要说的是,注解 @Before 是定义在 org.junit.Before 这個类中的,因此使用时需要将其引入我们的代码中。这样做了之后,每次我们运行测试方法时,JUnit 都会先运行 setUp() 方法将 result 的值清零。不过要注意的是,这里不再需要 @Test 注解,因为这并不是壹個 test,只是壹個前置工作。同理,如果“在任何测试执行之后需要进行的收尾工作,我们应该使用 @After 来标注,方法与它类似。由于本例比较简单,不需要用到此功能,所以我们只是简单了给它添加了壹個 tearDown() 方法并在收尾时打印壹句话到控制台,并且使用 @After 来注解这個方法。
  使用@BeforeClass 和 @AfterClass 来完成只需要执行壹次的前置工作和后置工作
  上面我们提到了两個注解 @Before 和 @After ,我们来看看他们是否适合完成如下功能:有壹個类负责对大文件(超过500 MB)进行读写,他的每壹個方法都是对文件进行操作。换句话说,在调用每壹個方法之前,我们都要打开壹個大文件并读入文件内容,这绝对是壹個非常耗费时的操作。如果我们使用 @Before 和 @After ,那么每次测试都要读取壹次文件,效率及其低下。所以我们希望的是,在所有测试壹开始读壹次文件,所有测试结束之后释放文件,而不是每次测试都读文件。JUnit的作者显然也考虑到了这个问题,它给出了@BeforeClass 和 @AfterClass 两個注解来帮我们实现这个功能。从名字上就可以看出,用这两個注解标注的函数,只在测试用例初始化时执行 @BeforeClass 方法,当所有测试执行完毕之后,执行 @AfterClass 进行收尾工作。在这里要注意壹下,每個测试类只能有壹個方法被标注为 @BeforeClass 或 @AfterClass,而且该方法必须是 public static 类型的。
  使用@Test 的属性 timeout 来完成限时测试,以检测代码中的死循环
  现在假设我们的 Calculator 类中的 square() 方法是個死循环,那应该怎么办呢,比如说像下面这样:
public void square(int n){
for(;;){}
}
  如果测试的时候遇到死循环,你的脸上绝对不会露出笑容的。因此,对于那些逻辑很复杂,循环嵌套比较深的、有可能出现死循环的程序,因此壹定要采取壹些预防措施。限时测试是壹個很好的解决方案。我们给这些测试函数设定壹個预期的执行时间,超过了这壹时间,他们就会被系统强行终止,并且系统还会向你汇报该函数结束的原因是因为超时,这样你就可以发现这些 Bug 了。要实现这壹功能,只需要给 @Test 标注加壹個参数timeout即可,代码如下:
@Test(timeout=2000L)
public void testSquare() {
calculator.square(3);
assertEquals(9, calculator.getReuslt());
}
  timeout参数表明了你预计该方法运行的时长,单位为毫秒,因此2000就代表2秒。现在我们让这個测试方法运行壹下,看看失败时是什么效果。
  使用@Test 的属性expected来监控测试方法中可能会抛出的某些异常
  JAVA中的异常处理也是壹個重点,因此你经常会编写壹些需要抛出异常的函数。如果你觉得壹個函数应该抛出异常,但是它没抛出,这算不算 Bug 呢?这当然是Bug,JUnit 也考虑到了这壹点,并且可以帮助我们找到这种 Bug。例如,我们写的计算器类有除法功能,如果除数是壹個0,那么必然要抛出“除0异常”。因此,我们很有必要对这些进行测试。代码如下:
@Test(expected=java.lang.ArithmeticException.class)
public void testDivide(){
calculator.divide(0);
}
  如上述代码所示,我们需要使用@Test注解中的expected属性,将我们要检验的异常(这里是 java.lang.ArithmeticException)传递给他,这样 JUnit 框架就能自动帮我们检测是否抛出了我们指定的异常。
  指定 JUnit 运行测试用例时的 Runner
  大家有没有想过这個问题,当你把测试代码提交给JUnit框架后,框架是如何来运行你的代码的呢?答案就是Runner。在JUnit中有很多个Runner,他们负责调用你的测试代码,每壹個Runner都有其各自的特殊功能,你要根据需要选择不同的Runner来运行你的测试代码。可能你会觉得奇怪,前面我们写了那么多测试,并没有明确指定壹個Runner啊?这是因为JUnit中有壹個默认的Runner,如果你没有指定,那么系统会自动使用默认Runner来运行你的代码。换句话说,下面两段代码含义是完全壹样的:
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@RunWith(JUnit4.class)
public class CalculatorTest {
...//省略此处代码
}
//用了系统默认的JUnit4.class,运行效果完全壹样
public class CalculatorTest {
...//省略此处代码
}
43/4<1234>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

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

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

沪ICP备05003035号

沪公网安备 31010102002173号