JUnit是一个回归测试框架,是程序员测试——白盒测试,继承TestCase类就可以用JUnit进行测试了
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()
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:表示程序本身的错误(程序有逻辑问题)
import junit.framework.TestCase; public class ErrorTest extends TestCase{ public void testError(){ assertEquals(3, 3); int result = 8 / 0; } }
Failures:表示测试失败(结果与期望的值不一致)
import junit.framework.TestCase; public class TestFailure extends TestCase{ public void testFailure(){ assertEquals(5, 3); } }
因此,我们在写测试程序的时候要先保证Errors是没有错误的,然后再来看Failures有没有错误
JUnit4.x利用了java5的特性(注释Annotation)的优势,比3.x使用起来更加方便简单,它不是简单的旧版本升级,它是一个全新的框架,整个框架的报结构已经彻底改变,但4.x版本任然能够很好的兼容旧版本的测试套件。
利用JUnit4.x的注解方式测试 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类这个方法的 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)方法时给出失败的原因