- 浏览: 232953 次
- 性别:
最新评论
-
nechiy:
maidongdong 写道请教一下:1.不能全是数学和特殊字 ...
正则表达式(必须包含字母.数字和特殊字符) -
nechiy:
bruce,你的解决方法让我眼前一亮,最起码思维方式值得眼前一 ...
正则表达式(必须包含字母.数字和特殊字符) -
zgcy123456:
...
Calendar获取时间的月和日 -
zgcy123456:
谢谢了,lz,:idea:
Calendar获取时间的月和日 -
yan0133:
这个显然不对了,老兄你有没有试验过,随便写个纯字母的就通过了
正则表达式(必须包含字母.数字和特殊字符)
修订者:黄 凯 <o:p></o:p>
E_mail:hk_sz@163.com<o:p></o:p>
三、安装 <o:p></o:p>
1. 获取JUnit的软件包,从Junit(http://www.junit.org/index.htm或http://download.sourceforge.net/junit/)下载最新的软件包。这里我使用的是http://download.sourceforge.net/junit/junit2.zip。<o:p></o:p>
2. 将其在适当的目录下解包(我安装在D:\junit2)。这样在安装目录(也就是你所选择的解包的目录)下你找到一个名为junit.jar的文件。将这个jar文件加入你的CLASSPATH系统变量。(IDE的设置会有所不同,参看你所喜爱的IDE的配置指南)JUnit就安装完了。<o:p></o:p>
<o:p> </o:p>
四、运行<o:p></o:p>
通过前面的介绍,我们对JUnit有了一个大概的轮廓。知道了它是干什么的。现在让我们动手改写上面的测试类testCar使其符合Junit的规范--能在JUnit中运行。
- //执行测试的类(JUnit版)
- import junit.framework.*;
- public class testCar extends TestCase
- {
- protected int expectedWheels;
- protected Car myCar;
- public testCar(String name)
- {
- super(name);
- }
- protected void setUp()
- {
- expectedWheels = 4;
- myCar = new Car();
- }
- public static Test suite()
- {
- /** the type safe way */
- /*
- TestSuite suite= new TestSuite();
- suite.addTest(
- new testCar("Car.getWheels")
- {
- protected void runTest()
- {
- testGetWheels();
- }
- }
- );
- return suite;
- */
- /** the dynamic way */
- return new TestSuite(testCar.class);
- }
- public void testGetWheels()
- {
- assertEquals(expectedWheels, myCar.getWheels());
- }
- }
改版后的testCar已经面目全非。先让我们了解这些改动都是什么含义,再看如何执行这个测试。 <o:p></o:p>
1>import语句,引入JUnit的类。(没问题吧) <o:p></o:p>
2>继承 TestCase 。可以暂时将一个TestCase看作是对某个类进行测试的方法的集合。详细介绍请参看JUnit资料 <o:p></o:p>
3>setUp()设定了进行初始化的任务。我们以后会看到setUp会有特别的用处。 <o:p></o:p>
4>testGetWheeels()对预期的值和myCar.getWheels()返回的值进行比较,并打印比较的结果。assertEquals是junit.framework.Assert中所定义的方法,junit.framework.TestCase继承了junit.framework.Assert。 <o:p></o:p>
5>suite()是一个很特殊的静态方法。JUnit的TestRunner会调用suite方法来确定有多少个测试可以执行。上面的例子显示了两种方法:静态的方法是构造一个内部类,并利用构造函数给该测试命名(test name, 如 Car.getWheels),其覆盖的runTest()方法,指明了该测试需要执行那些方法--testGetWheels()。动态的方法是利用内省(reflection)来实现runTest(),找出需要执行那些测试。此时测试的名字即是测试方法(test method,如testGetWheels)的名字。JUnit会自动找出并调用该类的测试方法。 <o:p></o:p>
6>将TestSuite看作是包裹测试的一个容器。如果将测试比作叶子节点的话,TestSuite就是分支节点。实际上TestCase,TestSuite以及TestSuite组成了一个composite Pattern。JUnit的文档中有一篇专门讲解如何使用Pattern构造Junit框架。有兴趣的朋友可以查看JUnit资料。 <o:p></o:p>
如何运行该测试呢?手工的方法是键入如下命令: <o:p></o:p>
[Windows] D:\>java junit.textui.TestRunner testCar<o:p></o:p>
[Unix] % java junit.textui.TestRunner testCar <o:p></o:p>
别担心你要敲的字符量,以后在IDE中,只要点几下鼠标就成了。运行结果应该如下所示,表明执行了一个测试,并通过了测试: <o:p></o:p>
. <o:p></o:p>
Time: 0 <o:p></o:p>
OK (1 tests) <o:p></o:p>
如果我们将Car.getWheels()中返回的的值修改为3,模拟出错的情形,则会得到如下结果: <o:p></o:p>
.F<o:p></o:p>
Time: 0.16<o:p></o:p>
<o:p> </o:p>
FAILURES!!!<o:p></o:p>
Test Results:<o:p></o:p>
Run: 1 Failures: 1 Errors: 0<o:p></o:p>
There was 1 failure:<o:p></o:p>
1) testCar.testGetWheels "expected:<3> but was:<4>"<o:p></o:p>
注意:Time上的小点表示测试个数,如果测试通过则显示OK。否则在小点的后边标上F,表示该测试失败。注意,在模拟出错的测试中,我们会得到详细的测试报告“expected:<3> but was:<4>”,这足以告诉我们问题发生在何处。下面就是你调试,测试,调试,测试...的过程,直至得到期望的结果。 <o:p></o:p>
<o:p> </o:p>
五、Design by Contract(这句话我没法翻译) <o:p></o:p>
Design by Contract本是Bertrand Meyer(Eiffel语言的创始人)开发的一种设计技术。我发现在JUnit中使用Design by Contract会带来意想不到的效果。Design by Contract的核心是断言(assersion)。断言是一个布尔语句,该语句不能为假,如果为假,则表明出现了一个bug。Design by Contract使用三种断言:前置条件(pre-conditions)、后置条件(post-conditions)和不变式(invariants)这里不打算详细讨论Design by Contract的细节,而是希望其在测试中能发挥其作用。 <o:p></o:p>
前置条件在执行测试之前可以用于判断是否允许进入测试,即进入测试的条件。如 expectedWheels > 0, myCar != null。后置条件用于在测试执行后判断测试的结果是否正确。如 expectedWheels==myCar.getWheels()。而不变式在判断交易(Transaction)的一致性(consistency)方面尤为有用。我希望JUnit可以将Design by Contract作为未来版本的一个增强。 <o:p></o:p>
<o:p> </o:p>
六、Refactoring(这句话我依然没法翻译) <o:p></o:p>
Refactoring本来与测试没有直接的联系,而是与软件熵有关,但既然我们说测试能解决软件熵问题,我们也就必须说出解决之道。(仅仅进行测试只能发现软件熵,Refactoring则可解决软件熵带来的问题。)软件熵引出了一个问题:是否需要重新设计整个软件的结构?理论上应该如此,但现实不允许我们这么做。这或者是由于时间的原因,或者是由于费用的原因。重新设计整个软件的结构会给我们带来短期的痛苦。而不停地给软件打补丁甚至是补丁的补丁则会给我们带来长期的痛苦。(不管怎样,我们总处于水深火热之中) <o:p></o:p>
Refactoring是一个术语,用于描述一种技术,利用这种技术我们可以免于重构整个软件所带来的短期痛苦。当你refactor时,你并不改变程序的功能,而是改变程序内部的结构,使其更易理解和使用。如:该变一个方法的名字,将一个成员变量从一个类移到另一个类,将两个类似方法抽象到父类中。所作的每一个步都很小,然而1-2个小时的Refactoring工作可以使你的程序结构更适合目前的情况。Refactoring有一些规则: <o:p></o:p>
1> 不要在加入新功能的同时refactor已有的代码。在这两者间要有一个清晰的界限。如每天早上1-2个小时的Refactoring,其余时间添加新的功能;<o:p></o:p>
2> 在你开始Refactoring前,和Refactoring后都要保证测试能顺利通过,否则Refactoring没有任何意义;<o:p></o:p>
3> 进行小的Refactoring,大的就不是Refactoring了。如果你打算重构整个软件,就没有必要Refactoring了。只有在添加新功能和调试bug时才又必要Refactoring。不要等到交付软件的最后关头才Refactoring。那样和打补丁的区别不大。Refactoring 用在回归测试中也能显示其威力。要明白,我不反对打补丁,但要记住打补丁是应该最后使用的必杀绝招。(打补丁也需要很高的技术,详情参看微软网站) <o:p></o:p>
<o:p> </o:p>
七、IDE对JUnit的支持 <o:p></o:p>
目前支持JUnit的Java IDE 包括 <o:p></o:p>
IDE<o:p></o:p> |
方式<o:p></o:p> |
分数(1-5,满分5)<o:p></o:p> |
Forte for Java 3.0 Enterprise Edition<o:p></o:p> |
plug-in<o:p></o:p> |
3<o:p></o:p> |
Jbuilder 9 Enterprise Edition<o:p></o:p> |
integrated with IDE<o:p></o:p> |
4<o:p></o:p> |
Visual Age for Java<o:p></o:p> |
support<o:p></o:p> |
N/A<o:p></o:p> |
在IDE中如何使用JUnit,是非常具体的事情。不同的IDE有不同的使用方法。一旦理解了JUnit的本质,使用起来就十分容易了。所以我们不依赖于具体的IDE,而是集中精力讲述如何利用JUnit编写单元测试代码。心急的人可参看资料。 <o:p></o:p>
<o:p> </o:p>
八、小结<o:p></o:p>
你一旦安装完JUnit,就有可能想试试我们的Car和testCar类,没问题,我已经运行过了,你得到的结果应该和我列出的结果类似。接下来,你可能会先写测试代码,再写工作代码,或者相反,先写工作代码,再写测试代码。我更赞成使用前一种方法:先写测试代码,再写工作代码。因为这样可以使我们编写工作代码时清晰地了解工作类的行为。 <o:p></o:p>
要注意编写一定能通过的测试代码(如文中的例子)并没有任何意义,只有测试代码能帮助我们发现bug,测试代码才有其价值。此外测试代码还应该对工作代码进行全面的测试。如给方法调用的参数传入空值、错误值和正确的值,看看方法的行为是否如你所期望的那样。 <o:p></o:p>
你现在已经知道了编写测试类的基本步骤: <o:p></o:p>
1> 扩展TestCase类; <o:p></o:p>
2> 覆盖runTest()方法(可选); <o:p></o:p>
3> 写一些testXXXXX()方法。<o:p></o:p>
<o:p> </o:p>
Fixture <o:p></o:p>
接下来的问题是,如果你要对一个或若干个的类执行多个测试,该怎么办?JUnit对此有特殊的解决办法。如果需要在一个或若干个的类执行多个测试,这些类就成为了测试的context。在JUnit中被称为Fixture(如testCar类中的 myCar 和 expectedWheels )。当你编写测试代码时,你会发现你花费了很多时间配置/初始化相关测试的Fixture。将配置Fixture的代码放入测试类的构造方法中并不可取,因为我们要求执行多个测试,我并不希望某个测试的结果意外地(如果这是你要求的,那就另当别论了)影响其他测试的结果。通常若干个测试会使用相同的Fixture,而每个测试又各有自己需要改变的地方。为此,JUnit提供了两个方法,定义在TestCase类中。 <o:p></o:p>
protected void setUp() throws java.lang.Exception <o:p></o:p>
protected void tearDown() throws java.lang.Exception <o:p></o:p>
覆盖setUp()方法,初始化所有测试的Fixture(你甚至可以在setUp中建立网络连接),将每个测试略有不同的地方在testXXX()方法中进行配置。覆盖tearDown()(我总想起一首叫雨滴的吉他曲),释放你在setUp()中分配的永久性资源,如数据库连接。当JUnit执行测试时,它在执行每个testXXXXX()方法前都调用setUp(),而在执行每个testXXXXX()方法后都调用tearDown()方法,由此保证了测试不会相互影响。 <o:p></o:p>
<o:p> </o:p>
TestCase <o:p></o:p>
需要提醒一下,在junit.framework.Assert类中定义了相当多的assert方法,主要有assert(),assertEquals(), assertNull(), assertSame(), assertTrue(), fail()等方法。如果你需要比较自己定义的类,如Car。assert方法需要你覆盖Object类的equals()方法,以比较两个对象的不同。实践表明:如果你覆盖了Object类的equals()方法,最好也覆盖Object类的hashCode()方法。再进一步,连带Object类的toString()方法也一并覆盖。这样可以使测试结果更具可读性。 <o:p></o:p>
当你设置好了Fixture后,下一步是编写所需的testXXX()方法。一定要保证testXXX()方法的public属性,否则无法通过内省(reflection)对该测试进行调用。每个扩展的TestCase类(也就是你编写的测试类)会有多个testXXX()方法。一个testXXX()方法就是一个测试。要想运行这个测试,你必须定义如何运行该测试。如果你有多个testXXX()方法,你就要定义多次。JUnit支持两种运行单个测试的方法:静态的和动态的方法。 <o:p></o:p>
静态的方法就是覆盖TestCase类的runTest()方法,一般是采用内部类的方式创建一个测试实例: <o:p></o:p>
<o:p></o:p>
采用静态的方法要注意要给每个测试一个名字(这个名字可以任意起,但你肯定希望这个名字有某种意义),这样你就可以区分那个测试失败了。 <o:p></o:p>- TestCase test01 = new testCar("test getWheels")
- {
- public void runTest()
- {
- testGetWheels();
- }
- }
动态的方法是用内省(Introspection,检查标准管理构件接口和应用设计模式的过程)来实现runTest()以创建一个测试实例。这要求测试的名字就是需要调用的测试方法的名字: <o:p></o:p>
TestCase test01 = new testCar("testGetWheels"); <o:p></o:p>
JUnit会动态查找并调用指定的测试方法。动态的方法很简洁,但如果你键入了错误的名字就会得到一个令人奇怪的NoSuchMethodException异常。动态的方法和静态的方法都很好,你可以按照自己的喜好来选择。(先别着急选择,后面还有一种更酷的方法等着你呢。) <o:p></o:p>
<o:p> </o:p>
TestSuite <o:p></o:p>
一旦你创建了一些测试实例,下一步就是要让他们能一起运行。我们必须定义一个TestSuite。在JUnit中,这就要求你在TestCase类中定义一个静态的suite()方法。suite()方法就像main()方法一样,JUnit用它来执行测试。在suite()方法中,你将测试实例加到一个TestSuite对象中,并返回这个TestSuite对象。一个TestSuite对象可以运行一组测试。TestSuite和TestCase都实现了Test接口(interface),而Test接口定义了运行测试所需的方法。这就允许你用TestCase和TestSuite的组合创建一个TestSuite。这就是为什么我们前面说TestCase,TestSuite以及TestSuite组成了一个composite Pattern的原因。例子如下: <o:p></o:p>
<o:p></o:p>
从JUnit 2.0开始,有一种更简单的动态定义测试实例的方法。你只需将类传递给TestSuite,JUnit会根据测试方法名自动创建相应的测试实例。所以你的测试方法最好取名为testXXX()。例子如下: <o:p></o:p>- public static Test suite()
- {
- TestSuite suite= new TestSuite();
- suite.addTest(new testCar("testGetWheels"));
- suite.addTest(new testCar("testGetSeats"));
- return suite;
- }
<o:p></o:p>
从JUnit的设计我们可看出,JUnit不仅可用于单元测试,也可用于集成测试。关于如何用JUnit进行集成测试请参考相关资料。 <o:p></o:p>- public static Test suite()
- {
- return new TestSuite(testCar.class);
- }
为了兼容性的考虑,下面列出使用静态方法的例子: <o:p></o:p>
<o:p></o:p>
<o:p></o:p>- public static Test suite()
- {
- TestSuite suite= new TestSuite();
- suite.addTest(
- new testCar("Car.getWheels")
- {
- protected void runTest()
- {
- testGetWheels();
- }
- }
- );
- return suite;
- }
TestRunner <o:p></o:p>
有了TestSuite我们就可以运行这些测试了,JUnit提供了三种界面来运行测试 <o:p></o:p>
[Text UI] junit.textui.TestRunner <o:p></o:p>
[AWT UI] junit.awtui.TestRunner <o:p></o:p>
[Swing UI] junit.swingui.TestRunner <o:p></o:p>
我们前面已经看过文本界面了,下面让我们来看一看图形界面: <o:p></o:p>
界面很简单,键入类名-testCar。或在启动UI的时候键入类名: <o:p></o:p>
[Windows] D:\>java junit.swingui.TestRunner testCar <o:p></o:p>
[Unix] % java junit.swingui.TestRunner testCar <o:p></o:p>
从图形UI可以更好的运行测试可查单测试结果。还有一个问题需要注意:如果JUnit报告了测试没有成功,JUnit会区分失败(failures)和错误(errors)。失败是一个期望的被assert方法检查到的结果。而错误则是意外的问题引起的,如ArrayIndexOutOfBoundsException。 <o:p></o:p>
由于TestRunner十分简单,界面也比较直观,故不多介绍。朋友们可自行参考相关资料。 <o:p></o:p>
<o:p> </o:p>
JUnit最佳实践 <o:p></o:p></
发表评论
-
数字金额转大写
2011-03-13 02:57 1749public class ConverChMoney ... -
读取资源文件
2008-07-16 16:14 1183package mainTest; import jav ... -
java正则表达式应用举例
2008-01-17 10:06 1839/** * @author 作者 Bruce * @v ... -
Cookie 操作
2007-09-17 10:37 2925Cookie是当你浏 ... -
Eclipse中设置在创建新类时自动生成注释
2007-08-23 14:15 1532windows-->preference Java--& ... -
关于serialVersionUID
2007-08-02 17:26 1545Eclipse到3.1及以后的版本,在类中要加上:privat ... -
Document对象详解 (JS)
2007-07-02 11:12 2066Document对象详解 document ... -
(转)JUnit实战篇 (二) 续
2007-06-12 16:43 1388JUnit最佳实践 <o:p></o:p&g ... -
(转)JUnit实战篇 (一)
2007-06-12 16:25 1243出处:http://blog.csdn.net/k ... -
Srping读书笔记
2007-06-12 13:26 1541术语: IoC(Inversion of Co ... -
javaScript:Escape()
2007-06-07 17:09 1984escape 返回以 ISO-Latin-1 字符集书写的参数 ... -
tbody的解释及用法
2007-06-06 14:21 1853写html代码的时候,遇到了Tbody这个 ... -
Java语言的Calendar和Date类
2007-06-05 11:38 2114Java 语言的Calendar(日 ... -
Calendar获取时间的月和日
2007-06-05 11:14 18431开始使用new Date()测试,并用通过da ... -
JAVA中获得本地系统时间的方法
2007-06-05 10:59 7056import java.util.*; ... -
JAVA Calendar详解
2007-06-05 10:54 19311(在文章的最后,将会介绍Date类,如果有兴趣,可以直接翻到最 ... -
java中的时间操作
2007-06-05 10:41 3066java中的时间操作不外乎这四种情况: 1、获取当前时间 2、 ... -
文件的压缩和解压
2007-06-01 15:06 1338java 代码 //文件名:myZip.jav ... -
JAVA中用接口实现多继承和多态的方法
2007-06-01 15:01 18341.JAVA里没有多继承,一个类之能有一个父类。而继承的表现就 ... -
Ajax应用场景
2007-06-01 12:48 1157适用场景 ...
相关推荐
JUnit知识点滴集合笔记,这个包里面包括了好几篇文档,一定会让你对JUNIT有一个全新的认识。 JUnit 4 抢先看.doc JUnit in java 真正的测试用例实战.doc JUnit起步.doc junit实现过程.doc JUnit中如何测试异常.doc ...
第5篇 测试及实战 第16章 实战型单元测试 16.1 单元测试概述 16.1.1 为什么需要单元测试 16.1.2 单元测试之误解 16.1.3 单元测试之困境 16.1.4 单元测试基本概念 16.2 JUnit 4快速进阶 16.2.1 JUnit 4概述 16.2.2 ...
第5篇 测试及实战 第16章 实战型单元测试 16.1 单元测试概述 16.1.1 为什么需要单元测试 16.1.2 单元测试之误解 16.1.3 单元测试之困境 16.1.4 单元测试基本概念 16.2 JUnit 4快速进阶 16.2.1 JUnit 4概述 16.2.2 ...
1、25个经典Spark算子的JAVA实现。2、含有详细的注释。3、全部通过junit测试。
1.1ant项目构建工具 1.2junit单元测试 1.3cactus单元测试 1.4clover测试覆盖率计算 1.5statcvs项目度量工具 1.6velocity模版系统 2文档书写辅助工具 参考资料 关于作者本文是实战每晚构建系列的第二篇,...
《JUnit5学习》系列旨在通过实战提升SpringBoot环境下的单元测试技能,一共八篇文章,链接如下: MyBatis学习(初级版) Spring领域 Spring基础 Spring扩展实战专题 畅游Spring源码世界 SpringBoot基础 SpringBoot...
《 JUnit5学习》系列预测通过实战提升SpringBoot环境下的单元测试技能,一共八篇文章,链接如下: MyBatis学习(初级版) Spring领域 Spring基础 Spring扩展实战专题 畅游Spring源码世界 SpringBoot基础 ...
关于作者 ...前腾讯、前阿里员工,从事Java后台工作; 对Docker和Kubernetes充满热爱;...《JUnit5学习》系列旨在通过实战提升SpringBoot环境下的单元测试技能,一共八篇文章,链接如下: jetcd学习特
《JUnit5学习》系列旨在通过实战提升SpringBoot环境下的单元测试技能,一共八篇文章,链接如下: MyBatis学习(初级版) Spring领域 Spring基础 Spring扩展实战专题 畅游Spring源码世界 SpringBoot基础 SpringBoot...
当然这本书也讲解了语法,是从实战的角度讲解的。 目录回到顶部↑第1章 进驻爪哇岛——JAVA的基本语法. 1 1.1 讲解 2 1.1.1 爪哇岛的历史与演变 2 1.1.2 爪哇岛基本生存规则 4 1.1.3 爪哇岛上新人新风尚 11 1.2...
Google.Android开发入门与实战,Android 精通Android游戏开发,3G应用开发之Android,15个Android很有用的代码片 段,Android 图像处理篇,Android_CTS测试研,GoogleMaps基础开发教程,Android_GPS架构分析,android_JNI...
Google.Android开发入门与实战,Android 精通Android游戏开发,3G应用开发之Android,15个Android很有用的代码片 段,Android 图像处理篇,Android_CTS测试研,GoogleMaps基础开发教程,Android_GPS架构分析,android_JNI...
[全网最详细的一篇SpringCloud总结] () [feign] () [Spring Security 真正的前后分离实现] () [Spring Cloud Gateway] () [SpingCloud Gateway网关核心概念和原理] () [基于Redis实现Spring Cloud Gateway] () ...
最近一段时间接触到了spock这个可以用于java和groovy项目的单元测试框架,写了一段时间单测之后认为这个框架不错,值得写一篇文章推广一下。 2 单元测试 很多人一谈到单元测试就会想到xUnit框架。对于一些java新人来...