Junit4单元测试

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

待测试类:

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

public int add(int a, int b) {
    return a + b;
}

public int minus(int a, int b) {
    return a - b;
}

public int square(int n) {
    return n * n;
}

//Bug : 死循环
public void squareRoot(int n) {
    for(; ;)
        ;
}

public int multiply(int a, int b) {
    return a * b;
}

public int divide(int a, int b) throws Exception {
    if (0 == b) {
        throw new Exception("除数不能为零");
    }
    return a / b;
}

}

单元测试类:

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

public class CalculatorTest {

private Calculator cal = new Calculator();

@BeforeClass // 注意,这里必须是static...因为方法将在类被装载的时候就被调用(那时候还没创建实例)
public static void before()
{
    System.out.println("global");
}

@AfterClass
public static void after() {
    System.out.println("global destroy");
}

@Before
public void setUp() throws Exception {
    System.out.println("一个测试开始。。");
}

@After
public void tearDown() throws Exception {
    System.out.println("一个测试结束");
}

@Test
@Ignore
public void testAdd() {
    int result = cal.add(1, 2);
    Assert.assertEquals(3, result);
}

@Test
public void testMinus() {
    int result = cal.minus(5, 2);
    Assert.assertEquals(3, result);
}

@Test
public void testMultiply() {
    int result = cal.multiply(4, 2);
    Assert.assertEquals(8, result);
}

@Test(timeout = 1000) // 单位为毫秒
public void testSquareRoot() {
    cal.squareRoot(4);
}

@Test(expected = Exception.class)
public void testDivide() throws Exception {
    System.out.println("teddd");
    cal.divide(4, 0);// 很简单的办法.......
}

// @Test
// public void testDivide() {
// int result = 0;
// try {
// result = cal.divide(10, 5);
// } catch (Exception e) {
// e.printStackTrace();
// Assert.fail();// 如果这行没有执行。说明这部分正确。
// }
// Assert.assertEquals(2, result);
// }
} 在Eclipse里Run As -> JUnit Test,运行测试类,Eclipse的JUnit的View显示如:

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

Txt代码
1.global
2.一个测试开始。。
3.一个测试结束
4.一个测试开始。。
5.一个测试结束
6.一个测试开始。。
7.一个测试结束
8.一个测试开始。。
9.teddd
10.一个测试结束
11.global destroy
global
一个测试开始。。
一个测试结束
一个测试开始。。
一个测试结束
一个测试开始。。
一个测试结束
一个测试开始。。
teddd
一个测试结束
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提供如下的测试:

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

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

@RunWith(Parameterized.class)
public class CalculatorTest2{

private Calculator cal = new Calculator();
private int param;
private int result;

//构造函数,对变量进行初始化
//定义一个待测试的类,并且定义两个变量,一个用于存放参数,一个用于存放期待的结果。
public CalculatorTest2(int param, int result) {
       this.param = param;
       this.result = result;
}

@Parameters
public static Collection data(){
    return Arrays.asList(new Object[][]{
        {2, 4},
        {0, 0},
        {-3, 9},
  });
}

@Test
public void squareTest() {
    int temp = cal.square(param);
    Assert.assertEquals(result, temp);
}

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

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



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

再看看打包测试测例子:

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

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

} 这个测试类包含了上面的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/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值