Junit4_单元测试

不多说,直接练习学习。

1、将Junit4单元测试包引入项目:项目右键——“属性”,选择“Java Build Path”,然后到右上选择“Libraries”标签,之后在最右边点击“Add Library…”按钮,选择JUnit4并点击确定。

2.新建一个项目叫JUnit_Test,我们编写一个Calculator待测试类

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

3.编写单元测试类

New>"Junit Test Case",选择New Junit 4 test ,勾选which method stubs would you like to create?

选择Class under test,点击Next,选择方法,Finish。

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

Run As->JUnit Test,显示如图

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

global
一个测试开始..
一个测试结束..
一个测试开始..
teddd
一个测试结束..
一个测试开始..
一个测试结束..
一个测试开始..
一个测试结束..
global destory

注解说明:

@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));

4、参数化测试

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

 1 package com.test;
 2
 3 import static org.junit.Assert.assertEquals;
 4
 5 import java.util.Arrays;
 6 import java.util.Collection;
 7 import org.junit.Test;
 8 import org.junit.runner.RunWith;
 9 import org.junit.runners.Parameterized;
10 import org.junit.runners.Parameterized.Parameters;
11
12 @RunWith(Parameterized.class)
13 public class Test2 {
14
15     private Calculator2 calculator2 = new Calculator2();
16     private int param;
17     private int result;
18
19     public Test2(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 = calculator2.square(param);
36         assertEquals(result, temp);
37     }
38 }

运行结果显示:

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

下面我们对上述代码进行分析。首先,你要为这 种测试专门生成一个新的类,而不能与其他测试共用同一个类,此例中我们定义了一个Test2类。然后,你要为这个类指定一个Runner,而不 能使用默认的Runner了,因为特殊的功能要用特殊的Runner嘛。@RunWith(Parameterized.class)这条语句就是为这个 类指定了一个ParameterizedRunner。第二步,定义一个待测试的类,并且定义两个变量,一个用于存放参数,一个用于存放期待的结果。接下 来,定义测试数据的集合,也就是上述的data()方法,该方法可以任意命名,但是必须使用@Parameters标注进行修饰。这个方法的框架就不予解 释了,大家只需要注意其中的数据,是一个二维数组,数据两两一组,每组中的这两个数据,一个是参数,一个是你预期的结果。比如我们的第一组{2, 4},2就是参数,4就是预期的结果。这两个数据的顺序无所谓,谁前谁后都可以。之后是构造函数,其功能就是对先前定义的两个参数进行初始化。在这里你可 要注意一下参数的顺序了,要和上面的数据集合的顺序保持一致。如果前面的顺序是{参数,期待的结果},那么你构造函数的顺序也要是“构造函数(参数,期待的结果)”,反之亦然。最后就是写一个简单的测试例了,和前面介绍过的写法完全一样,在此就不多说。

五、Runner(运行器)

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

1 import org.junit.internal.runners.TestClassRunner;
2 import org.junit.runner.RunWith;
3 //使用了系统默认的TestClassRunner,与下面代码完全一样
4 public class CalculatorTest …{…}
5 @RunWith(TestClassRunner.class)
6 public class CalculatorTest …{…}

六、打包测试

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

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

参考:

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

http://tips1000.com/archives/189.html

时间: 2024-10-05 04:25:54

Junit4_单元测试的相关文章

单元测试Junit

###<center> 单元测试Junit </center>###- - -1.**单元测试**:> ==单元测试==是软件之中对于最小的功能模块的的测试,其可以对最基本的软件构成单元来测试.> 需要注意的是:> >**测试用例是用来达到测试想要的预期结果,而不能测试出程序的逻辑错误**. 2.**JUnit**:>1.**Junit是基于断言机制的**.是用于编写可复用测试集的简单框架,是xUnit的一个子集.xUnit是一套基于测试驱动开发的测试

MVC与单元测试实践之健身网站(四)-动作管理

网站后台负责进行动作的管理,包括动作名称.介绍.训练要点.配图等内容,以便前台能够使用这些内容.在上一篇< Fit项目图片上传和云存储的调通>中已经准备好了这里涉及到的主要技术难点,现在就开始完成该模块了. 一 列表介绍 健身管理模块包括肌群.肌肉的显示以及动作的管理.这儿也算是开始涉及"业务内容"了,还好我之前有储备了一些关于健身的资料,现在是时候派上另一种用场了. a) 肌群和肌肉因为内容相对固定,所以为了减少业务逻辑以及单元测试的代码量,当然最主要是为了偷懒,就只提供

MVC与单元测试实践之健身网站(二)-管理员模块

开始动手做这个项目时,发现无法做到完全的先设计.再编码,于是决定分模块进行,从管理员模块开始设计.编码,而且接口就已经改了好几次了. 管理员模块涉及的功能有登录和后台对管理员的维护,其中也涉及前端的开发.UI模板使用Inspinia,感觉这套模板功能丰富.界面美观,而且基于HTML5和BootStrap,对这两方面的知识也可以多些了解. 在上一篇<如何在单元测试时隔离ORM>中,解决了对Service层进行测试怎样构建伪对象的问题,随后管理员模块的Service层和单元测试在齐头并进中完成了:

单元测试(一)-NUnit基础

单元测试作为提高代码和软件质量的有效途径,其重要性和益处自不必多说,虽然我没有实践过TDD之类,但坚信单元测试的积极作用.作为一种开发方法,单元测试早在上世纪70年代就已经在Smalltalk语言被运用了,这么多年来,单元测试一次又一次证明了自身的价值,在各种开发方式此起彼伏的浪潮中,经受住了时间的考验. 现在,俺也开始学习了,并在以后好好实践.这个系列的学习素材为Roy Osherove所著The Art of Unit Testing with examples in C#, 2nd Edi

OA项目CRUD和单元测试(一)

使用ModeFirst方法生成数据库,EntityFramework5.0. 一:Model层的模型:(根据模型生成数据库) 二:Dal层的UserInfo代码: namespace SunOA.EFDAL { public class UserInfoDal { //crud DataModelContainer db = new DataModelContainer(); public UserInfo GetUserInfoById(int id) { return db.UserInfo

词频统计-单元测试

我自己的单元测试没有弄出来,我用c编的,在visual studio中貌似实现不了单元测试,而李俞寰同学是用c#编写的词频统计,在vs2015中实现单元测试无比的方便,所以我请教了他并借鉴了一下. [TestMethod()] public void DictionarySortTest() { Dictionary<string,int>input=new Dictionary<string,int>() { {"you,1}, {"are",1},

使用Xunit来进行单元测试

不管你爱与不爱,单元测试对于一个软件的长治久安还是必不可少的一环.在Visual Studio 2012后,VS中的测试浏览器也能与第三方的集成了,用起来还是非常方便的.目前在.Net框架下的测试工具主要有Nunit.内置的MSTest以及Xunit这三个工具,本文就简单的介绍一下如何在VS中使用XUnit这个测试框架的后起之秀. 安装Xunit: Xunit的安装现在不需要插件支持了,直接使用NuGet安装如下两个库即可: PM> Install-Package xunit PM> Inst

作业八——单元测试练习(个人练习)

必做一: 针对附录1给出的三角形判断Java 代码,应用等价类划分法设计测试用例,用表格形式列出设计的测试用例: 测试用例如下:(红色字体为错误预言) 序号 测试输入:三条边 测试预言:[Oracle:Illegal(非三角形),Scalene(一般三角形), Isoceles(等腰三角形),Regular(等边三角形)] 1 (5,5,5) Regular 2 (-5,-5,-5) Regular 3 (1,4,5) Illegal 4 (2,3,5) Illegal 5 (3,4,5) Sc

作业8:单元测试练习(个人练习)

要求 [必做题1] 针对附录1给出的三角形判断Java 代码,应用等价类划分法设计测试用例,用表格形式列出设计的测试用例,写到博客中.(10分) [必做题2] 模仿附录2给出的三角形判断Junit测试代码,设计单元测试脚本,测试 [必做题1]设计得到的测试用例.注意测试脚本中测试用例出现顺序与[必做题1]表格所列顺序一致.运行所得的测试脚本,截运行结果图,写到博客中,同时将源代码push到你自己的github.(20分) [必做题3] 心得体会.写下本次练习你收获的知识点(PS:测试用例设计方法