转载: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. margin的BUG

    在进行简单的div盒子嵌套时,发现设置margin-top时存在bug,然后就去谷歌搜索了一下,发现margin确实存在bug. bug的现象是父子元素嵌套时,如果子元素是块元素时,对块元素设置mar ...

  2. PHP学习之数组的定义和填充

    数组就是把一组数据按顺序放在一起.PHP的数组和其它的语言数组有一点点不同:第一,保存的数据是可以是任何类型的:第二,数组的索引可以是数字,也可以是字符串. PHP的数组,说白了,就是关联数据每一条数 ...

  3. java 高精度

    package BigDecimal; import java.math.BigDecimal; import java.lang.Object; public class BigDecimalTes ...

  4. fast_recovery_area无剩余空间(ORA-19815)

    一.问题现象 --执行日志切换时,夯住 SQL ('/u01/oradata/oracle/redo04.log') size 50m; SQL> alter system switch log ...

  5. Oracle 表的连接方式(2)-----HASH JOIN的基本机制2

    Hash算法原理 对于什么是Hash算法原理?这个问题有点难度,不是很好说清楚,来做一个比喻吧:我们有很多的小猪,每个的体重都不一样,假设体重分布比较平均(我们考虑到公斤级别),我们按照体重来分,划分 ...

  6. 如何在SAE上使用DjangoUeditor

    之前的一个项目是部署到SAE上的,其中富文本编辑器使用到了Ueditor,对于Django有一个开源项目DjangoUeditor可以简化继承过程,直接引用app就可以使用.但是不支持SAE的文件上传 ...

  7. Python标准库之urllib,urllib2自定义Opener

    urllib2.urlopen()函数不支持验证.cookie或者其它HTTP高级功能.要支持这些功能,必须使用build_opener()函数创建自定义Opener对象. 1. build_open ...

  8. 全民wifi钓鱼来临----agnes安卓wifi钓鱼神器介绍

    断断续续搞了一些无线的东西,从bt5的aircrack-ng的破无线(没怎么成功过)其实EWSA这个用GPU跑还算不错,可惜了我这显卡也只能每秒2500,到用c118在OsmocomBB基础上进行gs ...

  9. System V信号量

    信号量对比 二值信号量:其值要么0要么1,比如互斥锁就是这种类型 计数信号量:其值为0或某个正整数,比如POSIX 信号量 计数信号量:一个或多个信号量构成一个集合,每个都是计数信号量,比如Syste ...

  10. NET

    NET狂官方面试题-数据库篇答案   题目:http://www.cnblogs.com/dunitian/p/6028838.html 汇总:http://www.cnblogs.com/dunit ...