转载: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. [大牛翻译系列]Hadoop(2)MapReduce 连接:复制连接(Replication join)

    4.1.2 复制连接(Replication join) 复制连接是map端的连接.复制连接得名于它的具体实现:连接中最小的数据集将会被复制到所有的map主机节点.复制连接有一个假设前提:在被连接的数 ...

  2. UDP HelloWord

    Client.cpp #include <stdio.h> #include <winsock2.h> #pragma comment (lib,"ws2_32&qu ...

  3. 利用Jmeter做接口测试

    本文作者:大道测试团队-孙云 1.在安装jmeter之前先配置好JDK,再配置jmeter环境变量. 2.启动jmeter 启动jmeter: 双击Jmeter解压路径(apache-jmeter-3 ...

  4. oracle11g RAC添加节点

    OS: [root@rac ~]# more /etc/oracle-releaseOracle Linux Server release 5.7 DB: SQL> SELECT * FROM ...

  5. redis使用场景

    Redis应用场景   Redis开创了一种新的数据存储思路,使用Redis,我们不用在面对功能单调的数据库时,把精力放在如何把大象放进冰箱这样的问题上,而是利用Redis灵活多变的数据结构和数据操作 ...

  6. Linux C C语言库的创建和调用

    C语言库的创建和调用 简介: 假如,你有一个庞大的工程,代码量达到数百兆甚至是数G,你经常会遇到好多重复或常用的地方.每次使用到这些地方时如果都重新写一份基本相同的代码,这当然可以,不过这样会大大地降 ...

  7. 【python】网络爬虫抓取图片

    利用python抓取网络图片的步骤: 1.根据给定的网址获取网页源代码 2.利用正则表达式把源代码中的图片地址过滤出来 3.根据过滤出来的图片地址下载网络图片 今天我们用http://www.umei ...

  8. UpdateData(false) and UpdateData(true)

    数据更新函数: UpdateData(false); 控件的关联变量的值传给控件并改变控件状态(程序--->EXE) UpdateData(true); 控件的状态传给其关联的变量(EXE--- ...

  9. Core身份认证

    Core中实现一个基础的身份认证 注:本文提到的代码示例下载地址> How to achieve a basic authorization in ASP.NET Core 如何在ASP.NET ...

  10. .net 科学类型相关问题

    Q:如果我要把使用科学记数法表示的string转换为int又该如何呢? A:你可以通过把NumberStyles.AllowDecimalPoint | NumberStyles.AllowExpon ...