[转载]JUnit3 与 JUnit4 的区别

Unit3 与 JUnit4 的区别

标签: junitandroidjava测试

2015-04-21 13:53 731人阅读 评论(0) 收藏 举报

 分类:

android自动化测试(28) 

本想总结下JUnit3和JUnit4的区别,方便自己的同时也方便他人,不想却违反了DRY原则,网上已经出现了很多的文章。

既然无须再重复造轮子,就在此推荐两篇个人认为不错的文章,地址如下:

360doc:http://www.360doc.com/content/12/0202/23/1542811_183778321.shtml

百度文库:http://wenku.baidu.com/link?url=AJOP-jcuMM9Zdx_iyyKPpyUBOOu06PhWVk89AWkRVbYShzd8j6713ztqe453ta7yMDNVqjpQWmm7j8YbvqHy-EW-uwfFb4_rf-nW84n9Po3

将文章内容拷贝如下,以防止原文被删除,无法参阅。

---------------- begin -------------------------------

JUnit 4是与JUnit3完全不同的API,它基于Java 5.0中的注解、静态导入等构建而成。JUnit 4更简单、更丰富、更易于使用,并引入了更为灵活的初始化和清理工作,还有限时的和参数化测试用例。

代码实例最能说明问题。因此,在本文中,我将使用一个例子来展示不同的测试用例:一个计算器。该示例计算器很简单,效率并不高,甚至还有一些错误; 它仅仅操作整数,并且把结果存储在一个静态变量中。Substract方法并不返回一个有效的结果,而且也没有实现乘法运算,而且看上去在 squareRoot方法中还存在一个错误:无限循环。这些错误将帮助说明使用JUnit 4进行测试的有效性。你可以打开和关闭这个计算器,而且你可以清除这些结果。下面是其实现代码:

package calc;

public class Calculator {

//存储结果的静态变量

private static int result;

public void add(int n) {

result = result + n;

}

public void substract(int n) {

result = result - 1; //错误:应该是"result = result - n"

}

//还没实现

public void multiply(int n) {

}

public void divide(int n) {

result = result / n;

}

public void square(int n) {

result = n * n;

}

public void squareRoot(int n) {

for (; ;) ;//错误:无限循环

}

//清除结果

public void clear() {

result = 0;

}

//打开屏幕,显示"hello",并报警

public void switchOn() {

result = 0;

//实现其它的计算器功能

}

//显示"bye bye",报警,并关闭屏幕

public void switchOff() {

}

public int getResult() {

return result;

}

}

以下代码是基于JUnit3.8实现的单元测试:

package junit3;

import calc.Calculator;

import junit.Framework.TestCase;

public class CalculatorTest extends TestCase {

private static Calculator calculator = new Calculator();

@Override

protected void setUp() {

calculator.clear();

}

public void testAdd() {

calculator.add(1);

calculator.add(1);

assertEquals(calculator.getResult(), 2);

}

public void testSubtract() {

calculator.add(10);

calculator.subtract(2);

assertEquals(calculator.getResult(), 8);

}

public void testDivide() {

calculator.add(8);

calculator.divide(2);

assertTrue(calculator.getResult() == 5);

}

public void testDivideByZero() {

try {

calculator.divide(0);

fail();

} catch(ArithmeticException e) {

}

}

public void notReadyYetTestMultiply() {

calculator.add(10);

calculator.multiply(10);

assertEquals(calculator.getResult(), 100);

}

} 

以下代码是基于JUnit4实现的单元测试:

package JUnit 4;

import calc.Calculator;

import org.junit.Before;

import org.junit.Ignore;

import org.junit.Test;

import static org.junit.Assert.*;

public class CalculatorTest {

private static Calculator calculator = new Calculator();

@Before

public void clearCalculator() {

calculator.clear();

}

@Test

public void add() {

calculator.add(1);

calculator.add(1);

assertEquals(calculator.getResult(), 2);

}

@Test

public void subtract() {

calculator.add(10);

calculator.subtract(2);

assertEquals(calculator.getResult(), 8);

}

@Test

public void divide() {

calculator.add(8);

calculator.divide(2);

assert calculator.getResult() == 5;

}

@Test(expected = ArithmeticException.class)

public void divideByZero() {

calculator.divide(0);

}

@Ignore("not ready yet")

@Test

public void multiply() {

calculator.add(10);

calculator.multiply(10);

assertEquals(calculator.getResult(), 100);

}

} 

JUnit3 和 JUnit4的区别

1、JUnit 4使用org.junit.*包而JUnit 3.8使用的是junit.Framework.*;为了向后兼容,JUnit4发行版中加入了这两种包。

2、JUnit3中,测试类需要继承junit.framework.TestCase类,而在JUniy4则不用。

3、JUnit3通过分析方法名称来识别测试方法:方法名必须以“test”为前缀,它必须返回void,而且它必须没有任何参数(例如 public void testDivide())。不遵循这个命名约定的测试方法将被JUnit框架忽略,而且不抛出任何异常(指示发生了一个错误)。

在JUnit4中,测试方法不必以‘test‘为前缀,而是使用@Test注解。但测试方法也必须返回void并且无参。在JUnit4中,可以在运行时控制这个要求,并且不符合要求的话会抛出一个异常:

java.lang.Exception: Method xxx should have no parameters
java.lang.Exception: Method xxx should be void

@Test注解支持可选参数。它声明一个测试方法应该抛出一个异常。如果它不抛出或者如果它抛出一个与事先声明的不同的异常,那么该测试失败。

4、在JUnit3.8中,TestCase类定义了assertEquals()方法,如果要在JUnit中向后兼容,必须静态地导入Assert类。这样一来,就可以像以前一样使用assertEquals方法。

另外,在JUnit 4中,还引入了两个新的断言方法,它们专门用于数组对象的比较。如果两个数组包含的元素都相等,那么这两个数组就是相等的。

public static void assertEquals(String message, Object[] expecteds, Object[] actuals);

public static void assertEquals(Object[] expecteds, Object[] actuals); 

由于JDK 5.0的自动装箱机制的出现,原先的12个assertEquals方法全部去掉了。

例如,原先JUnit 3.8中的assertEquals(long,long)方法在JUnit 4中要使用assertEquals(Object,Object)。对于assertEquals(byte,byte)、 assertEquals(int,int)等也是这样。这种改进将有助于避免反模式。

在JUnit 4中,新集成了一个assert关键字(见我们的例子中的divide()方法)。你可以象使用assertEquals方法一样来使用它,因为它们都抛出相同的异常(java.lang.AssertionError)。JUnit 3.8的assertEquals将抛出一个junit.framework.AssertionFailedError。注意,当使用assert时, 你必须指定Java的"-ea"参数;否则,断言将被忽略。

5、预设环境(Fixture)

Fixture是在测试期间初始化和释放任何普通对象的方法。在JUnit 3.8中,你要使用setUp()来实现运行每一个测试前的初始化工作,然后使用tearDown()来进行每个测试后的清理。这两个方法在 TestCase类中都得到重载,因此都被唯一定义。注意,我在这个Setup方法使用的是Java5.0内置的@Override注解-这个注解指示该 方法声明要重载在超类中的方法声明。在JUnit 4中,则代之使用的是@Before和@After注解;而且,可以以任何命名。

6、如果想忽略某个测试方法,在JUnit3中,通过注释掉该方法或者改变命名约定,这样测试运行机就无法找到它;问题随之而来,如果在众多测试中忽略某些测试方法,你可能记不住重命名这个方法;

而在JUnit4中,把@Ignore注解添加到@Test的前面或者后面即可。其好处在于,测试运行机将会统计出忽略的测试方法数目、运行的测试方法数目以及运行失败的测试方法数目。@Ignore使用一个可选参数(一个String)记录方法被忽略的原因。

7、在JUnit3.8中,可以选择使用若干运行机:文本型,AWT或者Swing。JUnit4仅使用文本测试运行机。

注意,JUnit4不会显示任何绿色条来通知你测试成功了。如果你想看到任何类型的绿色的话,那么你可能需要使用JUnit扩展或一种集成了JUnit的IDE(例如 IDEA或者Eclipse)。

JUnit4的高级特性

@BeforeClass/@AfterClass与@Before/@After 注解比较


@BeforeClass和@AfterClass


@Before和@After


在每个类中只有一个方法能被注解。


多个方法能被注解,但其执行的顺序未特别指定,且不运行重载方法。


方法名是不相关的。


方法名是不相关的。


每个类运行一次。


在每个测试方法执行前/执行后运行。


在当前类的@BeforeClass方法运行前先运行超类的@BeforeClass方法。在超类中声明的@AfterClass方法将在所有当前类的该方法运行后才运行。


超类中的@Before在所有子类的该方法运行前运行。在超类中的@After在在所有子类的该方法运行后才运行。


必须是公共和静态的。


必须是公共和非静态的。


即使一个@BeforeClass方法抛出一个异常,所有的@AfterClass方法也保证被运行。


即使一个@Before或者@Test方法抛出一个异常,所有的@After方法也保证被运行。

关于限时测试

Test注解的timeout参数可以指定方法执行时间(单位毫秒),如果方法没有在指定时间内结束,则测试不通过。

关于参数化测试

当使用不同的参数对同一方法测试时,可以使用”参数化测试”加以优化,可参照相关资料。

关于测试集

为了在JUnit 3.8的一个测试集中运行若干测试类,你必须在你的类中添加一个suite()方法。而在JUnit 4中,你可以使用注解来代之。你需要使用@RunWith和@Suite注解编写一个空类。

package test;

import org.junit.runner.RunWith;

import org.junit.runners.Suite;

@RunWith(Suite.class)

@Suite.SuiteClasses({AAATest.class,BBBTest.class})

public class AllTests {

} 

在此,@RunWith注解告诉JUnit它使用org.junit.runner.Suite。这个运行机允许你手工地构建一个包含测试(可能来自许多类)的测试集。这些类的名称都被定义在@Suite.SuiteClass中。当你运行这个类时,它将运行AAATest和BBBTest。

关于测试运行机

JUnit4中广泛地使用了测试运行机。如果没有指定@RunWith,仍会使用一个默认的运行机(org.junit.internal.runners.TestClassRunner)执行。带有@Test的方法的类都隐含地拥有一个@RunWith。

转自: http://blog.csdn.net/zhang103886108/article/details/45169561

时间: 2024-10-11 04:52:56

[转载]JUnit3 与 JUnit4 的区别的相关文章

JUnit3 和 JUnit4的区别

JUnit3 和 JUnit4的区别 1.JUnit 4使用org.junit.*包而JUnit 3.8使用的是junit.Framework.*;为了向后兼容,JUnit4发行版中加入了这两种包. 2.JUnit3中,测试类需要继承junit.framework.TestCase类,而在JUniy4则不用. 3.JUnit3通过分析方法名称来识别测试方法:方法名必须以"test"为前缀,它必须返回void,而且它必须没有任何参数(例如 public void testDivide()

Junit3与Junit4的区别

Junit4最大的亮点就是引入了注解(annotation),通过解析注解就可以为测试提供相应的信息,抛弃junit3使用命名约束以及反射机制的方法. /** * 被测试类 */ package com.stock.finance.service; import java.util.List; import java.util.zip.DataFormatException; import com.stock.finance.db.dao.TableCompanyDAO; import com.

Junit3和Junit4使用区别

在项目经常会用到单元测试,这里对Junit在开发中的使用标准及使用方法进行简单的介绍. 1.包目录的定义以及相关jar包的添加 2.Junit3和Junit4分别对测试类的编写 所测试的源代码: [java] view plain copy print? package com.techbirds; public class HelloWorld { public void sayHello(){ System.out.println("hello...."); throw new N

junit3和junit4的使用区别如下

junit3和junit4的使用区别如下1.在JUnit3中需要继承TestCase类,但在JUnit4中已经不需要继承TestCase2.在JUnit3中需要覆盖TestCase中的setUp和tearDown方法,其中setUp方法会在测试执行前被调用以完成初始化工作,而tearDown方法则在结束测试结果时被调用,用于释放测试使用中的资源,而在JUnit4中,只需要在方法前加上@Before,@After 3.在JUnit3中对某个方法进行测试时,测试方法的命令是固定的,例如对addBoo

junit基础学习之-junit3和4的区别(4)

junit3和junit4的使用区别如下 1.在JUnit3中需要继承TestCase类,但在JUnit4中已经不需要继承TestCase 2.在JUnit3中需要覆盖TestCase中的setUp和tearDown方法,其中setUp方法会在测试执行前被调用以完成初始化工作,而tearDown方法则在结束测试结果时被调用,用于释放测试使用中的资源,而在JUnit4中,只需要在方法前加上@Before,@After 3.在JUnit3中对某个方法进行测试时,测试方法的命令是固定的,例如对addB

[转载] Android raw与assets区别

*res/raw和assets的相同点: 1.两者目录下的文件在打包后会原封不动的保存在apk包中,不会被编译成二进制. *res/raw和assets的不同点:1.res/raw中的文件会被映射到R.java文件中,访问的时候直接使用资源ID即R.id.filename:assets文件夹下的文件不会被映射到R.java中,访问的时候需要AssetManager类.2.res/raw不可以有目录结构,而assets则可以有目录结构,也就是assets目录下可以再建立文件夹 *读取文件资源: 1

【转载】strlen与sizeof区别

自己小结: sizeof使用时,若是数组变量,则是数组变量占的大小 char a[10]; sizeof(a)=10 若是指针,则为指针大小,数组变量作为函数参数传递时,会退化成指针,且函数内是不知道原数组大小的 char *s="abcdddddd"; sizeof(s) = 4 指针 void f(char a[]) {sizeof(a) = 4 指针} 下面转载自百度百科 ------------------------------------------------------

转载---谈谈redis,memcache的区别和具体应用场景

转载地址:http://www.cnblogs.com/Hondsome/p/5962144.html 1. Memcached简介 Memcached是以LiveJurnal旗下Danga Interactive公司的Bard Fitzpatric为首开发的高性能分布式内存缓存服务器.其本质上就是一个内存key-value数据库,但是不支持数据的持久化,服务器关闭之后数据全部丢失.Memcached使用C语言开发,在大多数像Linux.BSD和Solaris等POSIX系统上,只要安装了lib

转载:scala中:: , +:, :+, :::, ++的区别

原文链接:https://segmentfault.com/a/1190000005083578 初学Scala的人都会被Seq的各种操作符所confuse.下面简单列举一下各个Seq操作符的区别. 4种操作符的区别和联系 :: 该方法被称为cons,意为构造,向队列的头部追加数据,创造新的列表.用法为 x::list,其中x为加入到头部的元素,无论x是列表与否,它都只将成为新生成列表的第一个元素,也就是说新生成的列表长度为list的长度+1(btw, x::list等价于list.::(x))