测试源代码如下:
package test.junit38test; /** * @创建作者: LinkinPark * @创建时间: 2016年1月26日 * @功能描述: 这里写一个算法类,实现加减乘除 */ public class Linkin { public int add(int a, int b) { return a + b; } public int subtract(int a, int b) { return a - b; } public int multiply(int a, int b) { return a * b; } public int divide(int a, int b) { return a / b; } }测试类代码如下:
package test.junit38test; import junit.framework.TestCase; /** * @创建作者: LinkinPark * @创建时间: 2016年1月26日 * @功能描述: Linkin算法类的测试类 */ public class LinkinTest extends TestCase { private Linkin linkin = null; public void setUp() { System.out.println("这里运行每个测试实例以前的准备工作。。。"); linkin = new Linkin(); System.out.println("linkin对象:"+linkin.toString()); } public void testAdd() { System.out.println("这里是加法的测试用例。。。"); } public void testSubtract() { System.out.println("这里是减法的测试用例。。。"); } public void tearDown() { System.out.println("这里运行每个测试实例之后的销毁动作。。。"); System.out.println("=========华丽丽的分割线==========="); } }
控制台输入如下:
- 测试类编写规则:
1,源代码和测试代码需要分开。我们不要在源代码中直接编码自己的测试代码,不利于代码的管理,应该养成良好的习惯。
2,测试类和目标源代码的类应该位于同一个包下面,即它们的包名应该一样。这样子有一个好处就是说,我们在测试代码中编写不需要导入源代码的包。
其实这也就是maven的一种约定的目录结构,利于我们很直观的编写代码。
3,测试类的命名规则:如果源代码类型是Linkin,那么相关该测试类就叫LinkinTest。如果源代码测试方法是add,那么相关该测试方法方法名就叫testAdd。
完整的约定目录结构如下:
- 测试类编写的注意点:
1,测试类必须继承于TestCase。这里类在junit framework下,继承该类表示你写的这个类是测试类,可以嫁入3Xjunit来进行测试。
最简单的看看你是否可以运行你的测试类,就是右键然后选择run as。如果不继承这个类是不会在eclipse中出现run as junit的。
2,测试类中所有的测试方法必须是void的,必须是无参的,方法名必须以test开头的,否则该测试方法不会被执行测试,最后一个条件,该方法必须是public的,否则报错。
下面故意编写几个错误的测试方法我们来看下效果:
如果方法名不是以test开头的,该方法不会纳入junit测试范围。比如如下测试方法就不会被测试:
public void ttestAdd() { System.out.println("这里是加法的测试用例。。。"); }
如果方法名以test开头,但是返回值不是void的,比如如下测试方法不会被执行测试:
public String testAdd() { System.out.println("这里是加法的测试用例。。。"); return ""; }
如果方法名以test开头,但是方法不是无参的,比如如下测试方法不会被执行测试:
public void testAdd(String str) { System.out.println("这里是加法的测试用例。。。"); }
如果方法名以test开头,但是不是用public来修饰。比如如下测试方法会被执行,但是报错:
void testAdd() { System.out.println("这里是加法的测试用例。。。"); }
3,每个测试方法之间一定要保持完全的独立性,不允许出现任何的依赖关系。这样子可以保证我们删除一些方法后不会对其他的方法产生任何的影响。我们不能依赖于测试方法的执行顺序。
4,每个测试方法执行前重复的代码放入setUp方法中,每个测试方法执行后重复的代码放入tearDown方法中。前面的初体验代码中,我们看控制台输出也发现了每次运行一个测试用例,就会重新执行setUp和tearDown方法,我们每次new的测试实例也并不是同一个,这样子就实现了上述我说的第3点了,包装每个测试方法方法相互独立,互不干扰。
OK,现在我已经比较介绍了junit3X系列如何使用了,接下来这里针对我们前面写的那个算法工具类,来写一个完整的测试类。具体代码如下:
package test.junit38test; import junit.framework.Assert; import junit.framework.TestCase; /** * @创建作者: LinkinPark * @创建时间: 2016年1月26日 * @功能描述: Linkin算法类的测试类 */ public class LinkinTest extends TestCase { private Linkin linkin = null; public void setUp() { linkin = new Linkin(); } public void testAdd() { int add = linkin.add(1, 1); Assert.assertEquals(2, add); } public void testSubtract() { int subtract = linkin.subtract(2, 1); Assert.assertEquals(1, subtract); } public void testMultiply() { int multiply = linkin.multiply(2, 1); Assert.assertEquals(2, multiply); } public void testDivide() { int divide = linkin.divide(2, 2); Assert.assertEquals(1, divide); } public void testDivide8Zero() { try { linkin.divide(2, 0); fail("这里应该抛出异常被捕获的,结果却没有。。。"); } catch (Exception e) { Assert.assertTrue(true); } } public void tearDown() { } }在上面的代码中,值得一提的就是testDivide8Zero方法,该方法是测试异常的情况,比如说除法运算中,被除数肯定不能是空。
单元测试最主要的一方面就是在代码中执行测试情况的能力。我们要确保无论何时发生异常,我们都要做出相关的处理。所以我们就只能try,catch了。
1,在try中先执行的异常代码,这里应该人工fail()一个错误,就是说如果本来应该是异常的代码没有抛出异常那么这个时候就应该fail让他失败掉。
2,在catch中执行一个空的断言,确保try里面的错误代码被正确的捕获到了。
OK,关于3X系列的测试我暂时先说这么多,下一篇博客整理junit中的断言。