转载:http://tonl.iteye.com/blog/1948869

参考:

http://thihy.iteye.com/blog/1771826

http://developer.51cto.com/art/201103/252490.htm

http://www.ibm.com/developerworks/cn/java/j-lo-junit4/

http://www.infoq.com/cn/articles/road-of-automated-unit-testing-practices

http://coolshell.cn/articles/8209.html

http://blog.csdn.net/andycpp/article/details/1327147

http://www.infoq.com/cn/news/2012/02/I-Hate-Unit-Test

http://coolshell.cn/category/process

用Junit进行单元测试很方便,尤其是Junit4引入了很多Annotation注解以后。看测试的示例:

待测试类:

  1. public class Calculator {
  2. public int add(int a, int b) {
  3. return a + b;
  4. }
  5. public int minus(int a, int b) {
  6. return a - b;
  7. }
  8. public int square(int n) {
  9. return n * n;
  10. }
  11. //Bug : 死循环
  12. public void squareRoot(int n) {
  13. for(; ;)
  14. ;
  15. }
  16. public int multiply(int a, int b) {
  17. return a * b;
  18. }
  19. public int divide(int a, int b) throws Exception {
  20. if (0 == b) {
  21. throw new Exception("除数不能为零");
  22. }
  23. return a / b;
  24. }
  25. }

单元测试类:

  1. import org.junit.After;
  2. import org.junit.AfterClass;
  3. import org.junit.Assert;
  4. import org.junit.Before;
  5. import org.junit.BeforeClass;
  6. import org.junit.Ignore;
  7. import org.junit.Test;
  8. public class CalculatorTest {
  9. private Calculator cal = new Calculator();
  10. @BeforeClass // 注意,这里必须是static...因为方法将在类被装载的时候就被调用(那时候还没创建实例)
  11. public static void before()
  12. {
  13. System.out.println("global");
  14. }
  15. @AfterClass
  16. public static void after() {
  17. System.out.println("global destroy");
  18. }
  19. @Before
  20. public void setUp() throws Exception {
  21. System.out.println("一个测试开始。。");
  22. }
  23. @After
  24. public void tearDown() throws Exception {
  25. System.out.println("一个测试结束");
  26. }
  27. @Test
  28. @Ignore
  29. public void testAdd() {
  30. int result = cal.add(1, 2);
  31. Assert.assertEquals(3, result);
  32. }
  33. @Test
  34. public void testMinus() {
  35. int result = cal.minus(5, 2);
  36. Assert.assertEquals(3, result);
  37. }
  38. @Test
  39. public void testMultiply() {
  40. int result = cal.multiply(4, 2);
  41. Assert.assertEquals(8, result);
  42. }
  43. @Test(timeout = 1000) // 单位为毫秒
  44. public void testSquareRoot() {
  45. cal.squareRoot(4);
  46. }
  47. @Test(expected = Exception.class)
  48. public void testDivide() throws Exception {
  49. System.out.println("teddd");
  50. cal.divide(4, 0);// 很简单的办法.......
  51. }
  52. //  @Test
  53. //  public void testDivide() {
  54. //      int result = 0;
  55. //      try {
  56. //          result = cal.divide(10, 5);
  57. //      } catch (Exception e) {
  58. //          e.printStackTrace();
  59. //          Assert.fail();// 如果这行没有执行。说明这部分正确。
  60. //      }
  61. //      Assert.assertEquals(2, result);
  62. //  }
  63. }

在Eclipse里Run As -> JUnit Test,运行测试类,Eclipse的JUnit的View显示如:

        可以看到,CalculatorTest类中总共有5个测试用例,ignore了一个,3个测试用例通过,testSquareRoot测试不通过(因为超时),所以整个的测试结果飘红了。同时,控制台的输出结果为:

  1. global
  2. 一个测试开始。。
  3. 一个测试结束
  4. 一个测试开始。。
  5. 一个测试结束
  6. 一个测试开始。。
  7. 一个测试结束
  8. 一个测试开始。。
  9. teddd
  10. 一个测试结束
  11. global destroy

各种注解的说明:

@Test:

表明该方法是一个测试方法

@BeforeClass 和 @AfterClass:

测试用例初始化时执行 @BeforeClass方法,当所有测试执行完毕之后,执行@AfterClass进行收尾工作。标注、@BeforeClass 和 @AfterClass的方法必须是static的,因为方法将在类被装载的时候就被调用,那时候还没创建测试对象实例。

@Before: 
使用了该元数据的方法在每个测试方法执行之前都要执行一次。

@After: 
使用了该元数据的方法在每个测试方法执行之后要执行一次。

@Test(expected=*.class) :
通过@Test元数据中的expected属性验证是否抛出期望的异常,expected属性的值是一个异常的类型,如果抛出了期望的异常,则测试通过,否则不通过。

@Test(timeout=xxx):
该元数据传入了一个时间(毫秒)给测试方法,如果测试方法在制定的时间之内没有运行完,则测试也失败。

@Ignore: 
该元数据标记的测试方法在测试中会被忽略。同时可以为该标签传递一个String的参数,来表明为什么会忽略这个测试方法。比如:@lgnore("该方法还没有实现"),在执行的时候,仅会报告该方法没有实现,而不会运行测试方法。

在test方法内除了使用Assert的assertEquals()方法外,还能使用assertFalse()、assertTrue()、assertNull()、assertNotNull()、assertSame()、assertNotSame()等断言函数。而且如果使用的是Junit4,结合Hamcrest,使用

assertThat([value], [matcher statement])方法可以实现更灵活的断言判断(前提是引入hamcrest的jar包)。

例如:

// is匹配符表明如果前面待测的object等于后面给出的object,则测试通过

assertThat( testedObj, is( object) );

// containsString匹配符表明如果测试的字符串包含指定的子字符串则测试通过

assertThat( testedString, containsString( "developerWorks" ) );

// greaterThan匹配符表明如果所测试的数值testedNumber大于16.0则测试通过

assertThat( testedNumber, greaterThan(16.0) );

// closeTo匹配符表明如果所测试的浮点型数testedDouble在20.0±0.5范围之内则测试通过

assertThat( testedDouble, closeTo( 20.0, 0.5 ) );

//hasItem匹配符表明被测的迭代对象含有元素element项则测试通过assertThat(iterableObject, hasItem (element));

更多更详细的Hamcrest提供的断言判断参考:

http://hi.baidu.com/shenhuanyu09/item/2bcfcb981aa3188e581461b4

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////分割线

上面的Caculator待测试类里,现在我如果想给square方法多弄几个测试用例,按照上面的方法,我应该写好几个@Test方法来测试,或者每次测完再改一下输入的值和期望得到的值,好麻烦。JUnit提供如下的测试:

  1. import java.util.Arrays;
  2. import java.util.Collection;
  3. import org.junit.Assert;
  4. import org.junit.Test;
  5. import org.junit.runner.RunWith;
  6. import org.junit.runners.Parameterized;
  7. import org.junit.runners.Parameterized.Parameters;
  8. @RunWith(Parameterized.class)
  9. public class CalculatorTest2{
  10. private Calculator cal = new Calculator();
  11. private int param;
  12. private int result;
  13. //构造函数,对变量进行初始化
  14. //定义一个待测试的类,并且定义两个变量,一个用于存放参数,一个用于存放期待的结果。
  15. public CalculatorTest2(int param, int result) {
  16. this.param = param;
  17. this.result = result;
  18. }
  19. @Parameters
  20. public static Collection data(){
  21. return Arrays.asList(new Object[][]{
  22. {2, 4},
  23. {0, 0},
  24. {-3, 9},
  25. });
  26. }
  27. @Test
  28. public void squareTest() {
  29. int temp = cal.square(param);
  30. Assert.assertEquals(result, temp);
  31. }
  32. }

Eclipse里JUnit的运行结果显示为:

       测试通过了,CalculatorTest2类里的parameter是每次的测试输入,result就是测试的结果。所有的测试输入和期望结果都在@Parameters标注的data函数的返回的Collection集合里,2的期望得到的平方结果值是4,0期望得到0,-3期望得到9。

把测试代码提交给JUnit框架后,框架如何来运行代码呢?答案就是——Runner。在JUnit中有很多个 Runner,他们负责调用测试代码,每一个Runner都有各自的特殊功能,要根据需要选择不同的Runner来运行测试代码。JUnit中有一个默认Runner,如果没有指定,那么系统自动使用默认 Runner来运行你的代码。这里参数化测试就没有再用默认的Runner了。

再看看打包测试测例子:

  1. import org.junit.runner.RunWith;
  2. import org.junit.runners.Suite;
  3. /**
  4. * 大家可以看到,这个功能也需要使用一个特殊的Runner,
  5. * 因此我们需要向@RunWith标注传递一个参数Suite.class。
  6. * 同时,我们还需要另外一个标注@Suite.SuiteClasses,
  7. * 来表明这个类是一个打包测试类。我们把需要打包的类作为参数传递给该标注就可以了。
  8. * 有了这两个标注之后,就已经完整的表达了所有的含义,因此下面的类已经无关紧要,
  9. * 随便起一个类名,内容全部为空既可
  10. *
  11. */
  12. @RunWith(Suite.class)
  13. @Suite.SuiteClasses({ CalculatorTest.class, CalculatorTest2.class })
  14. public class AllCalculatorTests {
  15. }

这个测试类包含了上面的CalculatorTest.class和CalculatorTest2.class里面所有的测试函数,它的目的就是进行打包所有的测试。

参考:

http://blog.csdn.net/zhuangxiu/article/details/6256893

http://blog.csdn.net/songyinan1989/article/details/7445921

http://www.jb51.net/article/15797.htm

http://jingbo2759.blog.163.com/blog/static/983753152009711103710146/

用JUnit4进行单元测试的更多相关文章

  1. J2EE 第二阶段项目之JUnit4进行单元测试(五)

    今天学习了JUnit4进行单元测试.这样就可以不写页面直接进行过功能模块测试.也不是很深入的了解. JUnit4和自己写的代码可以分割开来. 首先呢准备两个jar包: 可以对mapper进行测试,当然 ...

  2. 在Eclipse中使用JUnit4进行单元测试

    在Eclipse中使用JUnit4进行单元测试(初级篇) 在Eclipse中使用JUnit4进行单元测试(中级篇) 在Eclipse中使用JUnit4进行单元测试(高级篇)

  3. 【Java】在Eclipse中使用JUnit4进行单元测试(初级篇)

    本文绝大部分内容引自这篇文章: http://www.devx.com/Java/Article/31983/0/page/1 我们在编写大型程序的时候,需要写成千上万个方法或函数,这些函数的功能可能 ...

  4. springMVC整合Junit4进行单元测试

    springMVC整合Junit4进行单元测试 标签: springMVC整合Junit4junit单元测试教程springMVC入门教程   spring(10)  版权声明:本文为博主原创文章,未 ...

  5. (转)用JUnit4进行单元测试

    场景:从开始写代码至今,对于单元测试一直没有重视,但是也厌倦了了程序中的额System.out和log日志输出.单元测试使我看到了在开发过程中的安全性和便捷性,所以下决心好好整理下. 有感而发——&l ...

  6. 在Eclipse中使用JUnit4进行单元测试(图文教程一)

    在Eclipse中使用JUnit4进行单元测试 单元测试,JUnit4. 这两个有什么关系呢?这就好比(草)单元测试和(割草机).用这个JUnit4工具去辅助我们进行测试.其实不理解这个也没关系,听多 ...

  7. 在eclipse中使用JUnit4,以及使用JUnit4进行单元测试的技巧

    一 在eclipse中使用JUnit4 首先在工程上右键,选择属性,找到Java Builder Path,添加JUnit4的lib,如下图:   在要测试的类上右键新建 Junit test cas ...

  8. Idea 使用 Junit4 进行单元测试

    目录 Idea 使用 Junit4 进行单元测试 1. Junit4 依赖安装 2. 编写测试代码 3. 生成测试类 4. 运行 Idea 使用 Junit4 进行单元测试 1. Junit4 依赖安 ...

  9. [转]在Eclipse中使用JUnit4进行单元测试(初级篇)

    首先,我们来一个傻瓜式速成教程,不要问为什么,Follow Me,先来体验一下单元测试的快感! 首先新建一个项目叫JUnit_Test,我们编写一个Calculator类,这是一个能够简单实现加减乘除 ...

  10. 在Eclipse中使用JUnit4进行单元测试(初级篇)

    首先,我们来一个傻瓜式速成教程,不要问为什么,Follow Me,先来体验一下单元测试的快感! 首先新建一个项目叫JUnit_Test,我们编写一个Calculator类,这是一个能够简单实现加减乘除 ...

随机推荐

  1. getMeasuredHeight() 与 getHeight() 的区别

    http://www.cnblogs.com/x-dev/p/3767538.html?utm_source=tuicool&utm_medium=referral public final ...

  2. js阻止冒泡事件及默认操作

    1. 事件目标 现在,事件处理程序中的变量event保存着事件对象.而event.target属性保存着发生事件的目标元素.这个属性是DOM API中规定的,但是没有被所有浏览器实现 .jQuery对 ...

  3. hdu 5755 2016 Multi-University Training Contest 3 Gambler Bo 高斯消元模3同余方程

    http://acm.hdu.edu.cn/showproblem.php?pid=5755 题意:一个N*M的矩阵,改变一个格子,本身+2,四周+1.同时mod 3;问操作多少次,矩阵变为全0.输出 ...

  4. linux c 验证登录密码

    #define _XOPEN_SOURCE #include <stdio.h> #include <unistd.h> int main(int argc, char *ar ...

  5. c++中string类的详解

    ,<时返回-1,==时返回0  string的子串:string substr(int pos = 0,int n = npos) const;//返回pos开始的n个字符组成的字符串strin ...

  6. C# 时间戳

    C# 时间与时间戳互转 13位 /// <summary> /// 将c# DateTime时间格式转换为Unix时间戳格式 /// </summary> /// <pa ...

  7. iOS/Objective-C开发 字典NSDictionary的深复制(使用category)

    目标:把NSDictionary对象转换成NSMutableDictionary对象,对象内容是字符串数组,需要实现完全复制(深复制). 如果调用NSDictionary的mutableCopy方法, ...

  8. phpstorm8 设置及license key

    phpstorm8 license key Learn Programming ===== LICENSE BEGIN ===== 63758-12042010 00000Ryqh0NCC73lpRm ...

  9. matlab实现高斯牛顿法、Levenberg–Marquardt方法

    高斯牛顿法: function [ x_ans ] = GaussNewton( xi, yi, ri) % input : x = the x vector of 3 points % y = th ...

  10. c语言关于二进制的输出

    c语言中的二进制输出是没有占位符的,不像八进制:%o: 和十六进制:x%: c中二进制的输出 //右移31位,从最高为开始和1做&运算,得到每一位的二进制数值 void printbinry( ...