JUnit深入浅出

JUnit是一个回归测试框架,是程序员测试——白盒测试,继承TestCase类就可以用JUnit进行测试了

View Code
import junit.framework.TestCase;
public class Test extends TestCase{
public void testAdd(){
assertEquals(1, 1);
}
}

1、编写的测试类必须继承junit.framework.TestCase
2、里面的测试方法命名应该以test开头,必须是public void 而且不能有参数,否则不能使用junit
3、尽量一个testXXX方法对一个功能单一的方法进行测试
4、使用assertEquals等junit.framework.TestCase中的断言方法来判断测试结果正确与否

 

JUnit提供了一对方法,一个在运行测试方法前初始化一些必备的条件,而另外一个就是测试完毕后去掉初始化的条件
setUp()---->testXXX()---->tearDown()

View Code
import hb.util.SampleCalculator;
import junit.framework.TestCase;

public class TestSample extends TestCase {

public SampleCalculator calculator = null;

public void testAdd(){
int result = calculator.add(50, 20);
System.out.println(result);
assertEquals(70, result);
}

public void testSubtration(){
int abc = calculator.subtration(50, 20);
System.out.println(abc);
assertEquals(30, abc);
}

//每次测试一次的时候先执行setUp()这个方法
@Override
public void setUp(){
calculator = new SampleCalculator();
System.out.println("set up!");
}
//每次测试一次完成之后执行tearDown()这个方法
@Override
public void tearDown(){
System.out.println("tearDown");
}
}

Error和Failures的区别?
Errors:表示程序本身的错误(程序有逻辑问题)

View Code
import junit.framework.TestCase;
public class ErrorTest extends TestCase{
public void testError(){
assertEquals(3, 3);
int result = 8 / 0;
}
}
View Code
import junit.framework.TestCase;
public class ErrorTest extends TestCase{
public void testError(){
assertEquals(3, 3);
int result = 8 / 0;
}
}

因此,我们在写测试程序的时候要先保证Errors是没有错误的,然后再来看Failures有没有错误

 

JUnit4.x利用了java5的特性(注释Annotation)的优势,比3.x使用起来更加方便简单,它不是简单的旧版本升级,它是一个全新的框架,整个框架的报结构已经彻底改变,但4.x版本任然能够

很好的兼容旧版本的测试套件。

利用JUnit4.x的注解方式测试

View Code
import static org.junit.Assert.*;
import hb.util.Calculator;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;

public class TTest {

private Calculator calculator = new Calculator();

//在所有方法运行之前运行
@BeforeClass
public static void beforeClass(){
System.out.println("-----------beforeClass");
}

//在所有方法运行之后运行
@AfterClass
public static void afterClass(){
System.out.println("---------afterClass");
}

//每个测试方法运行之前运行
@Before
public void before(){
System.out.println("==============before");
}

//每个测试方法运行之后运行
@After
public void after(){
System.out.println("===========after");
}

@Test
public void testAdd(){
int result = calculator.add(3, 6);
assertEquals(9,result);
System.out.println("testAdd() is OK");
}

@Test
public void testDivision(){
System.out.println("in test division");
}

@Ignore //表示这个方法是不被运行的
@Test
(expected=java.lang.ArithmeticException.class,timeout=100) //timeout表示要求方法在100毫秒内运行完成,否则报错
public void testDivide(){
int z = calculator.subtration(8,2);
}
}

运行结果:
-----------beforeClass
==============before
testAdd() is OK
===========after
==============before
in test division
===========after
---------afterClass

结论:@BeforeClass --> @Before --> @Test --> @After --> @AfterClass

1、注释before与方法setUp()方法类似
2、注释after方法与tearDown()方法类似
3、测试期望异常和超时时间,例如@Test(timeout=100),我们给测试函数设定一个执行时间,超过了这个时间(100毫秒),它们就会被系统强行终止,并且系统还会向你汇报该函数结束的原因

是因为超时,这样就能发现Bug了;
同时还可以测试期望的异常@Test(expected=lllegalArgumentException.class)
4、@Ignore:忽略的测试方法,标注的含义——某些方法尚未完成,暂不参与此次测试
5、@BeforeClass:针对所有测试,在所有测试方法执行前执行一次,且必须为public static void
6、@AfterClass:针对所有测试,在所有测试方法执行结束后执行一次,并且必须为public static void


JAVA5新添加的新特性,可以使用import进来某个Class的静态members,主要有两种表现形式:
1、引进某个特定的静态成员
import static packageName.ClassName.staticMemberName;
2、引进所有的静态成员
import static packageName.ClassName.*;
这样引进后,就可以像自身成员那样使用import进来的成员,上面代码中assertEquals这个方法就是这么引用过来使用的。

批量处理的学习?
方法引入一种“测试套件”的概念,JUnit提供了一种批量运行测试类的方法,叫做测试套件。
测试套件的写法需要遵循一下原则:
1、创建一个空类作为测试套件的入口,
2、使用注解org.junit.runner.RunWith和org.junit.runners.Suite.SuitClasses修饰这个空类
3、将org.junit.runners.Suite作为参数传入给注解RunWith,以提示JUnit为此类测试使用套件运行器执行
4、将需要放入此测试套件的测试类组成数组作为注解SuiteClasses的参数
5、保证这个空类使用public修饰,而且存在公开的不带任何参数的构造函数

//该类是用来测试User类这个方法的

View Code
import static org.junit.Assert.*;
import hb.util.User;
import org.junit.Test;

public class TestUser {
@Test
public void testGetName(){
assertEquals("黄彪", new User().getName());
}
}

//该测试类是用来测试类T这个方法的
import hb.util.T;
import static org.junit.Assert.*;
import org.junit.Test;

public class TTest {

@Test
public void testAdd(){
int result = new T().add(5, 3);
assertEquals(8,result);
}
}

//将TestUser、TTest这个两个测试类一并处理
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;

@RunWith(Suite.class) //告知JUnit此类测试使用套件运算至星器
@SuiteClasses({TestUser.class,TTest.class})//需要测试的类的方法
public class AllTest {
}

代码规范?
1、单元测试的代码应位于单独的Source Folder下,即与src同一级别
2、测试类应该与被测试类位于统一package,即src和自己建立的测试folder目录相同
3、选择有测试意义的测试方法名,单元测试方法名均需使用test<待测试方法名>[概要描述],例如public void testDivdeDivisorZero(),这样很容易知道测试方法的含义
4、保持测试的独立性
5、为暂时未实现的测试代码抛出失败(fail)或者是忽略(ignore),例如使用fail("not yet implemented")或是@Ignore("not yet implemented")
6、在调用断言(assert)方法时给出失败的原因



 Failures:表示测试失败(结果与期望的值不一致)

posted @ 2011-11-17 19:35  胖鹅  阅读(466)  评论(1编辑  收藏  举报