JBuilder0520单元测试体验Word文件下载.docx
《JBuilder0520单元测试体验Word文件下载.docx》由会员分享,可在线阅读,更多相关《JBuilder0520单元测试体验Word文件下载.docx(40页珍藏版)》请在冰豆网上搜索。
![JBuilder0520单元测试体验Word文件下载.docx](https://file1.bdocx.com/fileroot1/2023-1/6/54c44fc6-5054-4005-960b-90acbdc8a356/54c44fc6-5054-4005-960b-90acbdc8a3561.gif)
灵敏度"
完全取决于测试用例的测试规则,框架提供编写和运行测试用例的规范性方法。
在编写一个业务类时,需要相应编写对应的测试用例,一开始挺招"
惯性定律"
抵触的,因为它要求你将创建一个测试用例类,似乎需要更多的工作。
但你的付出是会得到加倍回报的,随着软件类规模的增大你会发现,当传统测试方法越来越捉襟见肘,穷于应付时,基于测试框架的测试技术依然"
谈笑自如"
。
当然别人这么说,我们也不应当马上就深信不疑,疑惑永远是值得推崇的科学精神,我们应该通过自己的实践却真真切切地体会这种改进所带来的快乐。
JUnit测试框架
JUnit是由ErichGamma和KentBeck开发的开源测试框架,JBuilder集成了这个框架并做了扩展。
JUnit之所以流行并为广大的开发人员所推崇,一是它实战性强,功能强大,二是它实在简单。
一个产品或框架要能有生命力,最好都具备这样的特点。
简单的框架
JUnit是由ErichGamma和KentBeck开发的开源测试框架,JBuilder集成了这个框架并对此做了扩展。
JUnit之所以流行并为广大的开发人员所推崇,一是因为它实战性强,功能强大,二是因为它实在简单。
简单地讲这个框架提供了许多断言(assert)方法,允许你设置测试的规则,如:
assertEquals()、assertNull()、assertNotSame()、assertTrue()等方法,一个测试用例包括了多个断言,当运行测试用例后,JUnit运行器会报告哪些断言没有通过,开发人员就可顺藤摸瓜搞个水落石出了。
而传统的测试方法需要将期望的结果用诸如System.out.println()等语句将过程信息打印到控制台或日志中,由开发人员观察输出信息以判断是否正确,现在这种"
观察"
的工作由JUnit的那些assertXxx()方法自动完成。
JUnit的测试框架类结构很简单,主要由3个类组成,其类图关系如下图所示:
图错误!
文档中没有指定样式的文字。
JUnit测试框架类结构
·
junit.framework.Test:
测试接口。
junit.framework.TestCase:
测试用例类,业务类的测试用例类只需要承继这个TestCase,根据情况编写若干个publicvoidtestXxx()方法,在方法中通过assertYyy()定制若干测试规则就可以了。
junit.framework.TestSuite:
测试套件类,它可以将多个测试用例类捆绑在一起运行,也可以捆绑另一个测试套件。
测试固件(Fixture)
一个测试用例可以包含若干个testXxx()测试方法,测试用例测试一个或多个类API接口的正确性,当然在调用类API时,需要事先创建这个类的对象及一些关联的对象,这组对象就称为测试固件(Fixture),相当于测试用例的"
工作对象"
我们在前面说过,一个测试用例类可以包含多个testXxx()方法,在运行时,每个测试方法都对应一个测试用例类的实例。
当然,你可以在具体的testXxx()方法里声明并实例化业务类的实例,在测试完成后再销毁它们。
但是,这么一来你就要在每个testXxx()方法中都重复这些代码,因为TestCase实例被运行时,依照以下步骤运行:
1.创建测试用例的实例。
2.调用setUp()方法,执行一些初始化工作。
3.运行testXxx()测试方法。
4.调用tearDown()方法,执行销毁对象的工作。
如果测试用例类中有多个testXxx()方法,且它们都需要使用到相同的一组对象,我们可以在setUp()中实例化这组对象,并在tearDown()中销毁它们。
要编写测试固件,依照以下步骤进行:
1.创建TestCase类的子类。
2.在子类中声明若干个测试所用的对象。
3.覆盖setUp()方法,在方法中实例化这些对象。
4.覆盖tearDown()方法,释放这些对象的资源。
如下面即是一个简单的测试固件:
代码清单错误!
测试固件
1.publicclassMoneyTestextendsTestCase
2.{
3. privateMoneyf12CHF;
//12瑞士法郎
4. privateMoneyf14CHF;
//14瑞士法郎
5. privateMoneyf28USD;
//28美国美元
6. protectedvoidsetUp(){
7. f12CHF=newMoney(12,"
CHF"
);
8. f14CHF=newMoney(14,"
9. f28USD=newMoney(28,"
USD"
10. }
11. protectedvoidtearDown(){}
12.}
第3~5行声明了3个Money类对象(测试固件),在setUp()方法中实例化这3个对象(第7~9行),由于这些对象可以被垃圾进行直接回收,所以在tearDown()中不做任何操作。
测试用例(TestCase)
有了测试固件,就可以开始编写测试用例的测试方法了。
当然你也可不需要测试固件而直接编写测试用例方法。
下面我们在测试固件的基础上添加测试用例方法testMoneyBag(),代码如下所示:
代码清单测试用例方法
10. }
11. publicvoidtestMoneyBag()
12. {
13. Moneybag[]={f26CHF,f28USD};
14. MoneyBagexpected=newMoneyBag(bag);
15. assertEquals(expected,f12CHF.add(f28USD.add(f14CHF)));
16. }
17. protectedvoidtearDown(){}
18.}
测试方法都必须以test为前缀,且必须是publicvoid的,运行器以此为反射查找规则找到这些测试用例方法。
在一个方法中可以包括多个assertYyy()方法,每个assertYyy()方法都是一个测试规则。
像第15行的assertYyy()断言方法即为测试Money的add()方法和MoneyBag类正确性的测试规则。
你可以在MoneyTest中添加多个publicvoidtestXxx()方法,运行器为每个方法生成一个测试用例实例,分别运行。
测试套件(TestSuite)
如果每次只能运行一个测试用例,那么又陷入了我们前面所谈到的传统测试的窘境:
手工去运行一个个测试用例,测试套件专门为解决这一问题而来。
它通过TestSuite对象将多个测试用例组装成到一个测试套件,则测试套件批量运行。
需要特殊指出的是,可以把一个测试套件整个添加到另一个测试套件中,就象小筐装进大筐里变成一个箧一样。
测试套件类也通过承继TestCase类实现,只不过它提供了一个publicstaticTestsuite()静态方法,在该方法中将多个测试用例捆绑组装在一起。
一个典型的测试套件代码如下所示:
测试套件
1.publicclassMoneyTestSuiteextendsTestCase
2.{
3. publicTestSuite1(Strings)
4. {
5. super(s);
6. }
7. publicstaticTestsuite()
8. {
9. TestSuitesuite=newTestSuite();
10. suite.addTestSuite(MoneyTest.class);
11. suite.addTestSuite(MoneyBag.class);
12. returnsuite;
13. }
14.}
在第9行中声明并实例化了一个TestSuite,在第10、11行分别加入一个测试用例。
你可以通过suite.addTest(Testt)方法添加一个套件。
这样运行这个套件就可以自动运行所有测试用例的测试方法了。
测试运行器
JUnit提供了3个标准的测试运行器运行这些测试用例或测试套件,这3个测试运行器分别是:
junit.textui.TestRunner:
文本测试运行器。
junit.awtui.TestRunner:
使用AWT组件界面的测试运行器。
junit.swingui.TestRunner:
使用Swing组件界面的测试运行器。
下面是基于AWT组件的测试运行器,如下图所示:
AWT测试运行器
Testclassname:
指定测试用例类和测试套件类。
一个进度条:
表示运行测试的执行进度,进度条下是正确、错误、失败的测试统计数。
ErrorandFailures:
列出了测试错误和失败的列表,点选其中的一个选项时,JUnit在窗口底部列出错误跟踪迹。
提示:
JBuilder提供了方便的运行测试用例和测试套件类的方法,你只须点击鼠标右键就可直接调用了。
此外,JBuilder提供了一个JBTestRunner测试运行器,在功能和易用性上非JUnit提供的测试运行器所能媲美。
JBuilder支持JUnit所提供的两个测试运行器:
junit.textui.TestRunner和junit.swingui.TestRunner。
业务类介绍
为了便于讲解,拟通过两个简单的业务类引出测试用例,一个是分段函数类,另一个是字符串处理类,在这节里我们先来熟悉这两个业务类。
为了便于讲解,拟通过两个简单的业务类引出测试用例,一个是分段函数类,另一个是字符串处理类,在这节里我们先来熟悉这两个业务类。
分段函数类
分段函数Subsection类有两个函数,sign()是一个符号函数,而getValue(intd)函数功能如下:
当d<
-2时,值为abs(d);
当-2≤d<
2且d!
=0时,值为d*d;
当d=0时,值为100;
当2≤d时,值为d*d*d。
其代码如下图所示:
分段函数
1.packagechapter25;
2.
3.publicclassSubsection
4.{
5. publicstaticintgetValue(intd){
6. if(d==0){
7. return100;
8. }elseif(d<
-2){
9. returnMath.abs(d);
10. }elseif(d>
=-2&
&
d<
2){
11. returnd*d;
12. }else{//d>
=2
13. //if(d>
32){
14. //returnInteger.MAX_VALUE;
15. //}
16. returnd*d*d;
17. }
19.
20.publicstaticintsign(doubled){
21. if(d<
0){
22. return-1;
23. }elseif(d>
24. return1;
25. }else{
26. return0;
27. }
28.}
29.}
在getValue()方法中,当d>
32时,d*d*d的值将超过int数据类型的最大值(32768),所以当d>
32时,理应做特殊的处理,这里我们特意将这个特殊处理的代码注释掉(第13~15行),模拟一个潜在的Bug。
字符串处理类
由于标准JDK中所提供的String类对字符串操作功能有限,而字符串处理是非常常用的操作,所以一般的系统都提供了一个自己的字符串处理类。
下面就是一个字符串处理类,为了简单,我们仅提供了一个将字符串转换成数组的方法string2Array(),其代码如下所示:
字符串处理类
2.publicclassStringUtils
3.{
4. publicstaticString[]string2Array(Stringstr,charsplitChar,booleantrim){
5. if(str==null){
6. returnnull;
7. }else{
8. StringtempStr=str;
9. intarraySize=0;
//数组大小
10. String[]resultArr=null;
11. if(trim){//如果需要删除头尾多余的分隔符
12. tempStr=trim(str,splitChar);
13. }
14. arraySize=getCharCount(tempStr,splitChar)+1;
15. resultArr=newString[arraySize];
16. intfromIndex=0,endIndex=0;
17. for(inti=0;
i<
resultArr.length;
i++){
18. endIndex=tempStr.indexOf(splitChar,fromIndex);
19. if(endIndex==-1){
20. resultArr[i]=tempStr.substring(fromIndex);
21. break;
22. }
23. resultArr[i]=tempStr.substring(fromIndex,endIndex);
24. fromIndex=endIndex+1;
25. }
26. returnresultArr;
27. }
28. }
29.
30. //将字符串前面和后面的多余分隔符去除掉。
31. privatestaticStringtrim(Stringstr,charsplitChar){
32. intbeginIndex=0,endIndex=str.length();
33. for(inti=0;
str.length();
34. if(str.charAt(i)!
=splitChar){
35. beginIndex=i;
36. break;
37. }
38. }
39. for(inti=str.length();
i>
0;
i--){
40. if(str.charAt(i-1)!
41. endIndex=i;
42. break;
43. }
44. }
45. returnstr.substring(beginIndex,endIndex);
46. }
47.
48. //计算字符串中分隔符中个数
49. privatestaticintgetCharCount(Stringstr,charsplitChar){
50. intcount=0;
51. for(inti=0;
52. if(str.charAt(i)==splitChar){
53. count++;
54. }
55. }
56. returncount;
57. }
58.}
除对外APIstring2Array()外,类中还包含了两个支持方法。
trim()负责将字符前导和尾部的多余分隔符删除掉(第31~46行);
而getCharCount()方法获取字符中包含分隔符的数目,以得到目标字符串数组的大小(第49~57行)。
创建测试用例
JBuilder为测试用例类指定了一个默认的类名,即Test<
业务类名>
,包名和业务类包名一致。
接受默认的值,直接按Finish创建TestSubsection测试用例类。
我们先为Subsection类创建测试用例。
1.在编辑器中打开Subsection.java文件,使其处理激活态。
2.File->
New...->
Test->
在Test页的对象库中双击TestCase图标,启动创建测试用例的向导,如下图所示:
文档
中没有指定样式的文字。
指定测试的方法
Selectclass:
测试的目标类,默认为当前编辑器中打开的类,也可以通过其后的…按钮选择工程中其他的类。
Avaiablemethods:
列出了测试目标类的所有public、protected和默认可视域的方法,private方法不列出。
只要你测试了前三者的方法,private也被间接测试到了。
这里,我们选择getValue()和sign()方法。
点击Next到下一步。
3.设置测试用例类的类名。
指定测试用例类的名称
JBuilder为测试用例类指定了一个默认的类名,即Test<
实战经验:
虽然在物理上,业务类和测试用例类被放在不同目录下,但在工程窗格的资源树中,业务类和测试用例还是挤在了一起。
如果一个包下有多个业务类,加上它们相应的测试用例类,将显得更加拥挤不堪。
所以最好将测试用例放到不同的包中,如com.super.bdbj包中的所有业务类的测试用例放到test.super.bdbj目录下,这样将彻底解决测试用例和业务类的物理和逻辑上的分离,使工程窗格中的资源树更加整洁明了。
TestSubsection类的代码如下所示:
向导生成的TestSubsection类
3.importjunit.framewor