以前在公司有写过junit的文档,比较浅显,贴上来,希望对楼主有点帮助,我想也有不对之处,还请包涵~:)
JUnit是一个常用于自动化单元测试的java测试工具.
其中有一些概念,测试案例(Test Case),测试固定设备(Test Fixture),以及测试套件(Test Suite).测试案例定义了一个固定设备,相关测试可共享些设备;测试固定设备则提供资料:执行测试所需的原始变量以及对象;测试套件是一些相关的测试案例的集合.编写测试案例有如下步骤:
首先要引入待测试的类import junit.samples.userClass;
接着引入Junit框架import junit.framework.*;。从junit.framework.TestCase继承一个子类;
第二步建立测试固定设备(TestFixture),并在setUp()方法中实例化待测的userClass,供后面的测试方法使用;suite()是一个特殊的静态方法,它会创建一个包含所有的testXxxx方法的测试套件,确定有多少个测试可以执行;testCon()方法对userClass的Con方法进行测试,并断言(Assert)结果是"Connection Success!",并在Assert.assertEquals()方法中验证;testGogo()方法和testCon()方法类似。
最后:把TestuserClass、userClass类编译成*.class文件,在Junit的控制台上选择刚才定义的TestuserClass类,并运行。如果一切正确,就会显示绿条,证明测试正确。如果显示红色,在Results中会有相应显示,根据提示检查userClass类中的错误。一般的,只要断言符合userClass类的规范,TestuserClass类几乎不可能出错。JUnit的框架成员逻辑分析
1.被测试的对象(类,多个类,子系统)(Object be Tested)
2.对测试目标进行测试的方法与过程集合,可将其称为测试容器。(TestCase)
3.测试事务的集合,可容纳多个测试容器(TestCase),将其称作测试事务包。(TestSuite)
4.测试结果的描述与记录。(TestResult)
5.每一个测试方法所发生的与预期不一致状况的描述,称其测试失败元素。(TestFailure)
6. JUnit Framework中的出错异常。(AssertionFailedError)JUnit框架功能以及原理描述(junit.framework.*)
Test接口与TestCase、TestSuite形成了Composite结构,Run(TestResult) 则是Composite Methode。Test为Component,派生出的TestCase为Leaf,是测试的执行元素;TestSuite为Composite,其可通过addTest(Test)来容纳Test组合(TestCase or TestSuite)形成测试包。 TestCase可在框架中视为测试单元的运行实体。用户可以通过它派生自定义的测试过程与方式(单元),利用Command Pattern与Composite Pattern使其形成可组合装配的可扩展的测试批处理。TestCase本身的运作操作为run(TestResult),其中分别执行setUp(),runTest(),tearDown()来架构测试过程。Template Mothod Pattern使用户无须了解执行框架的过程细节,而只需重定义特性化的测试预处理,测试单元过程,以及测试完毕测试三个Template Mothod就能使测试正确工作。 用户层可通过Java的匿名内部类(Anonymous Inner Classes)来集成化重载runTest()形成特性测试类,同时JUnit3.0版本以后则支持利用Java的Class属性来动态框架后台生成这些特性测试单元类,而用户只需在TestCase派生类的testXXX()即可,在suite中使用return new TestSuite(MyTestCase.class);后该TestSuite就包含了所有testXXX为测试过程的TestCase类对象集合。 Assert类包含了assertEqual(..),assertSame(..),assertTrue(.)等静态工具方法(static tools methods),为使用户对系统所了解的类型尽可能少,JUnit框架将Assert作为了TestCase的超类,TestCase同时继承了Assert的实现与Test接口(class Adepter pattern)。用户可在TestCase中直接调用这些assertXXX(..)等静态工具方法。 TestResult描述了整个测试执行过程的测试结果,JUnit框架将其作为参数传递与Test的run(.)间,当测试任务执行完毕后,TestResult内则包含了所有TestCase的测试结果。框架默认的TestResult为TextTestResult,用户也可以自定义其TestResult的回显格式,譬如HTMLTestResult。TestFailure描述了测试过程中的错误信息,TestResult通过Vector容纳了测试过程中生成的TestFailure,将其作为测试结果参数依据。个人对于JUnit测试框架的看法:
用JUnit做为单元测试的工具,一般都必须先写测试,再写代码,这样的好处在于从技术上强制你先考虑一个类的功能,也就是这个类提供给外部的接口,而不至于太早陷入它的细节。这是面向对象提倡的一种设计原则。好的测试其实就是一个好的文档,这个类使用者往往可以通过查看这个类的测试代码了解它的功能。
从需求文档上来看,项目在开发过程中往往处于变动中,使得文档编写工作复杂,不定,导致以后维护的问题。但如果有了测试,并已经建立了一个好的测试框架,对于需求的变动,修改完代码后,只要重新运行测试代码,如果测试通过,也就保证了修改的成功,如果测试中出现错误,也会马上发现错在哪里,修改相应的部分,再运行测试,直至测试完全通过。
JUnit是一个常用于自动化单元测试的java测试工具.
其中有一些概念,测试案例(Test Case),测试固定设备(Test Fixture),以及测试套件(Test Suite).测试案例定义了一个固定设备,相关测试可共享些设备;测试固定设备则提供资料:执行测试所需的原始变量以及对象;测试套件是一些相关的测试案例的集合.编写测试案例有如下步骤:
首先要引入待测试的类import junit.samples.userClass;
接着引入Junit框架import junit.framework.*;。从junit.framework.TestCase继承一个子类;
第二步建立测试固定设备(TestFixture),并在setUp()方法中实例化待测的userClass,供后面的测试方法使用;suite()是一个特殊的静态方法,它会创建一个包含所有的testXxxx方法的测试套件,确定有多少个测试可以执行;testCon()方法对userClass的Con方法进行测试,并断言(Assert)结果是"Connection Success!",并在Assert.assertEquals()方法中验证;testGogo()方法和testCon()方法类似。
最后:把TestuserClass、userClass类编译成*.class文件,在Junit的控制台上选择刚才定义的TestuserClass类,并运行。如果一切正确,就会显示绿条,证明测试正确。如果显示红色,在Results中会有相应显示,根据提示检查userClass类中的错误。一般的,只要断言符合userClass类的规范,TestuserClass类几乎不可能出错。JUnit的框架成员逻辑分析
1.被测试的对象(类,多个类,子系统)(Object be Tested)
2.对测试目标进行测试的方法与过程集合,可将其称为测试容器。(TestCase)
3.测试事务的集合,可容纳多个测试容器(TestCase),将其称作测试事务包。(TestSuite)
4.测试结果的描述与记录。(TestResult)
5.每一个测试方法所发生的与预期不一致状况的描述,称其测试失败元素。(TestFailure)
6. JUnit Framework中的出错异常。(AssertionFailedError)JUnit框架功能以及原理描述(junit.framework.*)
Test接口与TestCase、TestSuite形成了Composite结构,Run(TestResult) 则是Composite Methode。Test为Component,派生出的TestCase为Leaf,是测试的执行元素;TestSuite为Composite,其可通过addTest(Test)来容纳Test组合(TestCase or TestSuite)形成测试包。 TestCase可在框架中视为测试单元的运行实体。用户可以通过它派生自定义的测试过程与方式(单元),利用Command Pattern与Composite Pattern使其形成可组合装配的可扩展的测试批处理。TestCase本身的运作操作为run(TestResult),其中分别执行setUp(),runTest(),tearDown()来架构测试过程。Template Mothod Pattern使用户无须了解执行框架的过程细节,而只需重定义特性化的测试预处理,测试单元过程,以及测试完毕测试三个Template Mothod就能使测试正确工作。 用户层可通过Java的匿名内部类(Anonymous Inner Classes)来集成化重载runTest()形成特性测试类,同时JUnit3.0版本以后则支持利用Java的Class属性来动态框架后台生成这些特性测试单元类,而用户只需在TestCase派生类的testXXX()即可,在suite中使用return new TestSuite(MyTestCase.class);后该TestSuite就包含了所有testXXX为测试过程的TestCase类对象集合。 Assert类包含了assertEqual(..),assertSame(..),assertTrue(.)等静态工具方法(static tools methods),为使用户对系统所了解的类型尽可能少,JUnit框架将Assert作为了TestCase的超类,TestCase同时继承了Assert的实现与Test接口(class Adepter pattern)。用户可在TestCase中直接调用这些assertXXX(..)等静态工具方法。 TestResult描述了整个测试执行过程的测试结果,JUnit框架将其作为参数传递与Test的run(.)间,当测试任务执行完毕后,TestResult内则包含了所有TestCase的测试结果。框架默认的TestResult为TextTestResult,用户也可以自定义其TestResult的回显格式,譬如HTMLTestResult。TestFailure描述了测试过程中的错误信息,TestResult通过Vector容纳了测试过程中生成的TestFailure,将其作为测试结果参数依据。个人对于JUnit测试框架的看法:
用JUnit做为单元测试的工具,一般都必须先写测试,再写代码,这样的好处在于从技术上强制你先考虑一个类的功能,也就是这个类提供给外部的接口,而不至于太早陷入它的细节。这是面向对象提倡的一种设计原则。好的测试其实就是一个好的文档,这个类使用者往往可以通过查看这个类的测试代码了解它的功能。
从需求文档上来看,项目在开发过程中往往处于变动中,使得文档编写工作复杂,不定,导致以后维护的问题。但如果有了测试,并已经建立了一个好的测试框架,对于需求的变动,修改完代码后,只要重新运行测试代码,如果测试通过,也就保证了修改的成功,如果测试中出现错误,也会马上发现错在哪里,修改相应的部分,再运行测试,直至测试完全通过。
解决方案 »
- 底层的一段代码,好像是错了,请大家帮忙看一下
- java 读取图片时报异常
- JSP中使用JS输出提示问题
- jsp 页面传值问题,等大家来回答啊!
- hibernate 同一个类中出现 一对多 多对一 怎么处理啊
- MiddleGen for Hibernate
- 我太笨了,为什么JBoss运行不需要j2ee.jar
- 请教如何用cache
- J2EE 安装的时候需要安装下面的那些内容?
- super() 感觉很多都没有意义但是为什么要这么写呢??~
- 高手们帮帮忙啊!我在JB2005下做了一个简单的Struts,可怎么调不通啊?
- 有用过james的吗 请过来看看!! 为什么我运行james/bin/run.bat出现如下问题~~;
JUnit概述:
测试分类:白箱测试、黑箱测试、单元测试、集成测试、功能测试...。白箱测试是指在知道被测试的软件如何(How)完成功能和完成什么样(What)的功能的条件下所作的测试,一般是由开发人员完成,单元测试是一种白箱测试,因为开发人员最了解自己编写的软件。JUnit是由 Erich Gamma 和 Kent Beck 编写的一个回归测试框架,回归测试就是你不断地对所编写的代码进行测试(如单元测试):编写一些,测试一些,调试一些,然后循环这一过程,你会不断地重复先前的测试,哪怕你正编写其他的类。
JUnit是为编写单元测试所发布的一个框架,在实现之前先介绍一些概念:测试案例(TestCase),测试固定设备(TestFixture)及测试套件(TestSuite).测试案例定义了一个固定设备,相关的测试可以共享些测试固定设备.测试固定设备则提供资料:执行测试所需的原始变量以及对象.测试套件是一些相关的测试案例的集合.编写一个测试案例(TestCase):
测试代码AccountTest.java
------------------------------------------------------------------------------
/** *
* 这是一个测试银行帐户管理程序的例子
* 2004-08-05
*/
package Account;import junit.framework.*;public class AccountTest extends TestCase { //继承TestCase子类;
//构造被测试的对象;
private Account AccountA;
private Account AccountB;
public AccountTest(String name) {
super(name);
}
//进行初始化;
public void setUp(){
AccountA = new Account("Sasser",1000);
AccountB = new Account("Worm",2000);
}
public static void main(String args[]) {
junit.textui.TestRunner.run(suite()); //测试套设定;
}
public static Test suite() { //测试类;
return new TestSuite(AccountTest.class);
}
//测试帐户;
public void testAccount() {
Assert.assertEquals("Sasser", AccountA.Owner); //测试帐户所有人是否相等;
Assert.assertEquals(1000, AccountA.Balance,0); //帐户存款是否相等;
Assert.assertEquals("Worm", AccountB.Owner);
Assert.assertEquals(2000, AccountB.Balance,0);
}
//测试往帐户上存款;
public void testCredit(){
AccountA.Credit(500); //1000+500=1500;
Assert.assertEquals(1500,AccountA.Balance,0); //断言,判断结果是否相等;
AccountB.Credit(300); //2000+300=2300;
Assert.assertEquals(2300,AccountB.Balance,0); //断言,判断结果是否相等;
}
//测试银行取款;
public void testFetch(){
AccountA.Fetch(800); //取出800;
Assert.assertEquals(200,AccountA.Balance,0); //断言,判断是否相等;
AccountB.Fetch(700); //取出700;
Assert.assertEquals(1300,AccountB.Balance,0); //断言;
}
//测试银行转帐;
public void testTransfer(){
AccountA.Transfer(AccountB,600);
Assert.assertEquals(1600,AccountA.Balance,0); //断言;
Assert.assertEquals(1400,AccountB.Balance,0); //断言;
}
}
被测试的程序Account.java
/**
* 这是一个待测的银行帐户管理程序,它实现了帐户的增加
* 或减少存款,以及帐户之间的转帐业务.
* 2004-08-05
*/
package Account;public class Account {
String Owner;
double Balance;
//银行帐户;
public Account(String aOwner, double aBalance) { //构造函数;
Owner = aOwner;
Balance = aBalance;
}
//银行存款;
public void Credit(double aMoney){
Balance+= aMoney;
}
//银行取款;
public void Fetch(double aMoney){
Balance-= aMoney;
}
//银行转帐;
public void Transfer(Account aAccount,double aBalance){
this.Credit(aBalance); //调用帐户存款;
aAccount.Fetch(aBalance); //调用帐户取款;
}
}
案例说明:
对于xp编程而言,要求在编写代码之前先写测试,这样可以强制你在写代码之前好好的思考代码(方法)的功能和逻辑.此案例,是一个实现银行帐户存款,取款及转帐的帐户管理程序.首先在编写测试程序的开头,就是定义一个类来继承junit.framework.TestCase.
import junit.framework.*;
public class AccountTest extends TestCase{…}
然后定义一个固定设备:
public void setUp(){
AccountA = new Account("Sasser",1000);
AccountB = new Account("Worm",2000);
}
先写测试代码,就要先构思好先实现什么,这样才能写出对于特定对象的测试代码.在此案例中,第一个现实的就是要知道一个帐户的持有人和该帐户所拥有的存款,如是测试代码如下:
public void testAccount() {
Assert.assertEquals("Sasser", AccountA.Owner); //测试帐户所有人是否相等;
Assert.assertEquals(1000, AccountA.Balance,0); //帐户存款是否相等;
Assert.assertEquals("Worm", AccountB.Owner);
Assert.assertEquals(2000, AccountB.Balance,0);
}
以上代码是无法编译的,因为并没有Account类.需要编写一个这样的类,程序如下:
public class Account {
String Owner;
double Balance;
//银行帐户;
public Account(String aOwner, double aBalance) { //构造函数;
Owner = aOwner;
Balance = aBalance;
}
…
}
这样程序就可以通过编译了,测试程序也能得出预想的结果.
程序第二个实现的是帐户上存款的增加与减少,先写public void testCredit()和public void testFetch(),测试程序代码如下:
//测试往帐户上存款;
public void testCredit(){
AccountA.Credit(500); //1000+500=1500;
Assert.assertEquals(1500,AccountA.Balance,0); //断言,判断结果是否相等;
AccountB.Credit(300); //2000+300=2300;
Assert.assertEquals(2300,AccountB.Balance,0); //断言,判断结果是否相等;
}
//测试银行取款;
public void testFetch(){
AccountA.Fetch(800); //取出800;
Assert.assertEquals(200,AccountA.Balance,0); //断言,判断是否相等;
AccountB.Fetch(700); //取出700;
Assert.assertEquals(1300,AccountB.Balance,0); //断言;
}
同样上述两段代码无法通过编译,需要在Account.java中编写Credit()和Fetch()方法:
//银行存款;
public void Credit(double aMoney){
Balance+= aMoney;
}
//银行取款;
public void Fetch(double aMoney){
Balance-= aMoney;
}
程序最后还在实现帐户之间的转帐业务.其实帐户转帐,就是调用一个帐户的存款方法和另一个帐户的取款方法,测试代码和程序代码如下:
//测试银行转帐;
public void testTransfer(){
AccountA.Transfer(AccountB,600);
Assert.assertEquals(1600,AccountA.Balance,0); //断言;
Assert.assertEquals(1400,AccountB.Balance,0); //断言;
}
//银行转帐;
public void Transfer(Account aAccount,double aBalance){
this.Credit(aBalance); //调用帐户存款;
aAccount.Fetch(aBalance); //调用帐户取款;
}
到这里,一个简单的用JUnit测试用例就完成了.另外,案例中每一个测试方法都成为一个测试,JUnit框架使用映射(reflection)机制寻找名称开头是test的方法作为测试案例.当在静态方法suite()中调用TestSuite的构造函数时将会发生这些事情,如程序中所示:
public static Test suite() {
//测试类;
return new TestSuite(AccountTest.class);
}
一个测试套件(TestSuite)是多个测试案例的集合,而测试案例本身可以是其他测试套件,因此测试套件是一种测试的合成.