Junit学习总结.docx
- 文档编号:3862895
- 上传时间:2022-11-26
- 格式:DOCX
- 页数:13
- 大小:134.34KB
Junit学习总结.docx
《Junit学习总结.docx》由会员分享,可在线阅读,更多相关《Junit学习总结.docx(13页珍藏版)》请在冰豆网上搜索。
Junit学习总结
Junit学习
(一)TDD简介:
许多书上都讨论了自动测试,但是只有很少的著作注意到这么一个问题,那就是怎样把这些测试组织起来。
随着测试的增加,放置和调用这些测试却变得更加麻烦。
这将成为一个重要问题,以至于出现了TDD,极限编程(XP)使TDD得以普及。
另外,你可以这样理解TDD:
通过测试来开发。
TDD(Test-DrivenDevelopment:
测试驱动开发)本质和优势
测试驱动开发不是一种测试技术,它是一种分析技术、设计技术,更是一种组织所有开发活动的技术。
相对于传统的结构化开发过程方法,它具有以下优势:
1)TDD根据客户需求编写测试用例,对功能的过程和接口都进行了设计,而且这种从使用者角度对代码进行的设计通常更符合后期开发的需求。
因为关注用户反馈,可以及时响应需求变更,同时因为从使用者角度出发的简单设计,也可以更快地适应变化。
2)出于易测试和测试独立性的要求,将促使我们实现松耦合的设计,并更多地依赖于接口而非具体的类,提高系统的可扩展性和抗变性。
而且TDD明显地缩短了设计决策的反馈循环,是我们几秒或几分钟之内就能获得反馈。
3)将测试工作提到编码之前,并频繁地运行所有测试,可以尽量地避免和尽早地发现错误,极大地降低了后续测试及修复的成本,提高了代码的质量。
在测试的保护下,不断重构代码,以消除重复设计,优化设计结构,提高了代码的重用性,从而提高了软件产品的质量。
4)TDD提供了持续的回归测试,使我们拥有重构的勇气,因为代码的改动导致系统其他部分产生任何异常,测试都会立刻通知我们。
完整的测试会帮助我们持续地跟踪整个系统的状态,因此我们就不需要担心会产生什么不可预知的副作用了。
5)TDD所产生的单元测试代码就是最完美的开发者文档,它们展示了所有的API该如何使用以及是如何运作的,而且它们与工作代码保持同步,永远是最新的。
6)TDD可以减轻压力、降低忧虑、提高我们对代码的信心、使我们拥有重构的勇气,这些都是快乐工作的重要前提。
TDD现状
由于发展时间不长,相关应用并不是很成熟。
现今越来越多的公司都在尝试实践测试驱动开发,但由于测试驱动开发对开发人员要求比较高,更与开发人员的传统思维习惯相违背,因此实践起来有一定困难。
(二)Junit的简单介绍
简单的说,junit是用来做单元测试的一个工具。
用其主页上的话来说就是:
“JUnit是由ErichGamma和KentBeck编写的一个回归测试框架(regressiontestingwork)。
在www.junit.org上可以下载到最新版本的junit包。
单元测试是一种白箱测试。
目的是验证一个或若干个类是否按所设计的那样正常工作。
集成测试则是验证所有的类是否能互相配合,协同完成特定的任务。
需要强调的是:
测试是一个持续的过程。
也就是说测试贯穿与开发的整个过程中,单元测试尤其适合于迭代增量式(iterativeandincremental)的开发过程。
因为我们是测试新手,我们也不理会那些复杂的测试原理,先说一说最简单的:
测试就是比较预期的结果是否与实际执行的结果一致。
如果一致则通过,否则失败。
(三)回归测试框架-JUnit
回归测试就是你不断地对所编写的代码进行测试:
编写一些,测试一些,调试一些,然后循环这一过程,你会不断地重复先前的测试,哪怕你正编写其他的类,由于软件熵的存在,你可能在编写第五个类的时候发现,第五个类的某个操作会导致第二个类的测试失败。
通过回归测试我们抓住了这条大Bug。
(四)junit中的几个关键点
Junit4与junit3相比,做了比较大的改动。
具体不细讲了,有兴趣可在网上查找些资料进行了解。
1.下面通过一个简单的实例对junit框架(函数结构)做个简单的介绍。
比如下面一个类:
publicclassAddOperation{
publicintadd(intx,inty){
returnx+y;
}
}
我们要测试add这个方法,我们在junit4中写单元测试得这么写:
importjunit.framework.TestCase;
importorg.junit.After;
importorg.junit.Before;
importorg.junit.Test;
importstaticorg.junit.Assert.*;
/**
*
*@authorbean
*/
publicclassAddOperationTestextendsTestCase{
publicAddOperationTest(){
}
@Before
publicvoidsetUp()throwsException{
}
@After
publicvoidtearDown()throwsException{
}
@Test
publicvoidadd(){
System.out.println(\"add\");
intx=0;
inty=0;
AddOperationinstance=newAddOperation();
intexpResult=0;
intresult=instance.add(x,y);
assertEquals(expResult,result);
}
}
几个元数据的介绍:
@Before:
使用了该元数据的方法在每个测试方法执行之前都要执行一次。
@After:
使用了该元数据的方法在每个测试方法执行之后要执行一次。
注意:
@Before和@After标示的方法只能各有一个。
这个相当于取代了JUnit以前版本中的setUp和tearDown方法,当然你还可以继续叫这个名字,不过JUnit不会霸道的要求你这么做了。
@Test(expected=*.class)
在JUnit4.0之前,对错误的测试,我们只能通过fail来产生一个错误,并在try块里面assertTrue(true)来测试。
现在,通过@Test元数据中的expected属性。
expected属性的值是一个异常的类型
@Test(timeout=xxx):
该元数据传入了一个时间(毫秒)给测试方法,
如果测试方法在制定的时间之内没有运行完,则测试也失败。
@ignore:
该元数据标记的测试方法在测试中会被忽略。
当测试的方法还没有实现,或者测试的方法已经过时,或者在某种条件下才能测试该方法(比如需要一个数据库联接,而在本地测试的时候,数据库并没有连接),那么使用该标签来标示这个方法。
同时,你可以为该标签传递一个String的参数,来表明为什么会忽略这个测试方法。
比如:
@lgnore(“该方法还没有实现”),在执行的时候,仅会报告该方法没有实现,而不会运行测试方法。
另外还有一些其他的元数据,具体请自己查资料。
setUp与tearDown,这两个函数是junitframework中提供初始化和反初始化每个测试方法的。
setUp在每个测试方法调用前被调用,负责初始化测试方法所需要的测试环境;tearDown在每个测试方法被调用之后被调用,负责撤销测试环境。
它们与测试方法的关系可以描述如下:
测试开始->setUp->testXXXX->tearDown->测试结束
2.另一个实例说明建立测试的流程(步骤):
假设我们要写一个整数除法和乘法的类,并且给他写测试用例:
1)建立Math类
Java代码
1./**
2. * @author bimingwei
3. * @描述:
一个整数除法和乘法的工具类
4. */
5.public class Math {
6. public static int divide(int x,int y) {
7. return x/y;
8. }
9.
10. public static int multiple(int x,int y) {
11. return x*y;
12. }
13.}
2)建立测试用例
选中需要建立测试用例的包,选择new->other->JUnitTestCase。
有5个方法可以选择:
setUp()方法在测试方法前调用,一般用来做测试准备工作。
tearDown()方法在测试方法后调用,一般作测试的清理工作。
setUpBeforeClass()方法在整个类初始化之后调用,一般用来做测试准备工作。
tearDownAfterClass()方法在整个类结束之前调用,一般作测试的清理工作。
constructor()为是否包含构造方法。
自动生成的代码如下:
Java代码
1./**
2. * @authorbimingwei
3. * @描述:
4. */
5.public class MathTest {
6.
7. @BeforeClass
8. public static void setUpBeforeClass() throws Exception {
9. }
10.
11. @AfterClass
12. public static void tearDownAfterClass() throws Exception {
13. }
14.
15. @Test
16. public void testDivide() {
17. fail("Not yet implemented"); (注意重写该方法时,要将该语句删除)
18. }
19.
20. @Test
21. public void testMultiple() {
22. fail("Not yet implemented");
23. }
24.}
说明:
@BeforeClass标签注释的方法用于在整个类测试过程的初始化后调用一次,@AfterClass标签注释的方法则是整个测试类结束之前调用一次。
这2个标签的搭配可以避免使用@Before、@After标签组合在每个测试方法前后都调用的弊端,减少系统开销,提高系统测试速度。
(不过对环境独立性要求较高的测试还是应当使用@Before、@After来完成)
@Test标签用来标注待测试的方法,按照类中声明的顺序执行。
我们在testDivide方法加入测试代码,分别测试三种情况:
a.完全正确也没有可能出错的数据,如:
9除3 结果必须等于3
b.可能有问题的边缘数据,如:
10除3结果也必须等于3
c.错误的数据,如:
10除0必须抛出异常
忽略testMultiple方法
代码如下:
Java代码
1.@Test(expected=ArithmeticException.class)
2.public void testDivide() {
3. assertEquals(3,Math.divide(9,3));
4. assertEquals(3,Math.divide(10,3));
5. Math.divide(10,0); //除数不能为0,会抛出异常
6.}
7.
8.@Ignore("忽略乘法测试")
9.@Test
10.public void testMultiple() {
11.}
说明:
Junit4为测试方法增加了判断异常的方式,避免了以前还要通过try/catch块捕捉异常再抛出的复杂方式,简单的这样声明“@Test(expected=ArithmeticException.class)”Junit4就会检查此方法是否抛出ArithmeticException异常,如果抛出则测试通过,没抛出则测试不通过(@Test标签还有一些其他参数,例如超时测试@Test(timeout=1)这样,但是由于并不能准确反应实际时间,所以应用较少,经过我测试误差太大绝对不适合拿来做超时测试的)
@Ignore标签会告诉Junit4忽略它所标注的方法,例如数据库不可用时可以用此标注标注一些测试数据库连接的方法来避免测试失败。
3)运行测试
系统会打开JUnit透视图,如果测试全部通过,则显示颜色条为绿色;
我们将assertEquals(3,Math.divide(9,3));改成assertEquals(2,Math.divide(9,3));则显示颜色条为红色,我们可以对错误或者故障的地方进行追踪。
4)创建测试套件
测试套件可以将多个测试用例合在一起测试,将相关的测试用例合成一个测试套件,在做一个修改后,只需要运行测试套件就可以,不需要运行每一个测试用例。
Junit4没有采用以前的套件测试方法,同样使用annotation的方式来进行。
简单在你所要构建测试套件的包里创建一个文件,一般以包名+4Suite
下面我在上面的测试包中复制一下之前的测试类并且一个改名字叫做MathTestAnother,新建一个class类叫做Uitl4Suite,代码如下:
Java代码
1.import org.junit.runner.RunWith;
2.import org.junit.runners.Suite;
3.import org.junit.runners.Suite.SuiteClasses;
4./**
5. * @author bimingwei
6. * @创建时间:
7. * @描述:
util包的测试套件
8. */
9.@RunWith(Suite.class)
10.@SuiteClasses({MathTest.class,
11. MathTestAnother.class})
12.public class Util4Suite {
13.}
说明:
通过@RunWith和@SuiteClasses标签来注释一个空的包含无参数构造函数的类来作为套件类,将需要组成套件运行的类加到@SuiteClasses的属性中即可。
可以看到运行套件类的结果是2个测试类都进行了测试。
5)参数测试
修改testMultiple
Java代码
1.//@Ignore("忽略乘法测试")
2.@Test
3.public void testMultiple() {
4. assertEquals(result,Math.multiple(faciend,multiplicator));
5.}
编写参数方法:
Java代码
1.@Parameters
2. public static Collection multipleValues() {
3. return Arrays.asList(new Object[][] {
4. {3, 2, 6 },
5. {4, 3, 12 },
6. {21, 5, 105 },
7. {11, 22, 242 },
8. {8, 9, 72 }});
9. }
说明:
需要使用@Parameters标签注解一个静态的返回集合对象的方法
增加成员变量和构造函数:
Java代码
1.int faciend;
2.int multiplicator;
3.int result;
4.
5.public MathTest(int faciend, int multiplicator, int result) {
6. this.faciend = faciend;
7. this.multiplicator = multiplicator;
8. this.result = result;
9.}
最后在给测试类增加如下注释:
Java代码
1.@RunWith(Parameterized.class)
完整的循环测试代码如下:
Java代码
1.import static org.junit.Assert.*;
2.
3.import java.util.Arrays;
4.import java.util.Collection;
5.
6.import org.junit.AfterClass;
7.import org.junit.BeforeClass;
8.import org.junit.Ignore;
9.import org.junit.Test;
10.import org.junit.runner.RunWith;
11.import org.junit.runners.Parameterized;
12.import org.junit.runners.Parameterized.Parameters;
13.
14./**
15. * @author bimingwei
16. * @描述:
17. */
18.@RunWith(Parameterized.class)
19.public class MathTest {
20. int faciend;
21. int multiplicator;
22. int result;
23.
24. public MathTest(int faciend, int multiplicator, int result) {
25. this.faciend = faciend;
26. this.multiplicator = multiplicator;
27. this.result = result;
28. }
29.
30. @BeforeClass
31. public static void setUpBeforeClass() throws Exception {
32. }
33.
34. @AfterClass
35. public static void tearDownAfterClass() throws Exception {
36. }
37.
38. @Test(expected=ArithmeticException.class)
39. public void testDivide() {
40. assertEquals(3,Math.divide(9,3));
41. assertEquals(3,Math.divide(10,3));
42. Math.divide(10,0);//除数不能为0,会抛出异常
43.
44. }
45.
46. //@Ignore("忽略乘法测试")
47. @Test
48. public void testMultiple() {
49. assertEquals(result,Math.multiple(faciend,multiplicator));
50. }
51.
52. @Parameters
53. public static Collection multipleValues() {
54. return Arrays.asList(new Object[][] {
55. {3, 2, 6 },
56. {4, 3, 12 },
57. {21, 5, 105 },
58. {11, 22, 242 },
59. {8, 9, 72 }});
60. }
61.
62.}
结果如下图示,程序跑了5次,并通过运行。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Junit 学习 总结