JUnit是由 Erich Gamma 和 Kent Beck 编写的一个回归测试框架(regression testing framework)。Junit测试是程序员测试,即所谓白盒测试,因为程序员知道被测试的软件如何(How)完成功能和完成什么样(What)的功能。Junit是一套框架,继承TestCase类,就可以用Junit进行自动测试了。
更多JUnit信息
Cactus
Cactus是一个基于JUnit框架的简单测试框架,用来单元测试服务端Java代码。Cactus框架的主要目标是能够单元测试服务端的使用Servlet对象的Java方法如HttpServletRequest,HttpServletResponse,HttpSession等
更多Cactus 信息
Abbot
Abbot是一个用来测试Java GUIs的框架。用简单的基于XML的脚本或者Java代码,你就可以开始一个GUI。
更多Abbot信息
JUnitPerf
Junitperf实际是junit的一个decorator,通过编写用于junitperf的单元测试,我们也可使测试过程自动化。
更多JUnitPerf信息
DbUnit
DbUnit是为数据库驱动的项目提供的一个对JUnit 的扩展,除了提供一些常用功能,它可以将你的数据库置于一个测试轮回之间的状态。
更多DbUnit信息
Mockrunner
Mockrunner用在J2EE环境中进行应用程序的单元测试。它不仅支持Struts actions, servlets,过滤器和标签类还包括一个JDBC和一个JMS测试框架,可以用于测试基于EJB的应用程序。
更多Mockrunner信息
DBMonster
DBMonster是一个用生成随机数据来测试SQL数据库的压力测试工具。
更多DBMonster信息
MockEJB
MockEJB是一个不需要EJB容器就能运行EJB并进行测试的轻量级框架。
更多MockEJB信息
StrutsTestCase
StrutsTestCase 是Junit TestCase类的扩展,提供基于Struts框架的代码测试。StrutsTestCase同时提供Mock 对象方法和Cactus方法用来实际运行Struts ActionServlet,你可以通过运行servlet引擎来测试。因为StrutsTestCase使用ActionServlet控制器来测试你的代码,因此你不仅可以测试Action对象的实现,而且可以测试mappings,from beans以及forwards声明。StrutsTestCase不启动servlet容器来测试struts应用程序(容器外测试)也属于Mock对象测试,但是与EasyMock不同的是,EasyMock是提供了创建Mock对象的API,而StrutsTest则是专门负责测试Struts应用程序的Mock对象测试框架。
更多StrutsTestCase信息
JFCUnit
JFCUnit使得你能够为Java偏移应用程序编写测试例子。它为从用代码打开的窗口上获得句柄提供了支持;为在一个部件层次定位部件提供支持;为在部件中发起事件(例如按一个按钮)以及以线程安全方式处理部件测试提供支持。
更多JFCUnit信息
JTestCase
JTestCase 使用XML文件来组织多测试案例数据,声明条件( *** 作和期望的结果),提供了一套易于使用的方法来检索XML中的测试案例,按照数据文件的定义来声明结果。
更多JTestCase信息
SQLUnit
SQLUnit是一个单元测试框架,用于对数据库存储过程进行加归测试。用 Java/JUnit/XML开发。
更多SQLUnit信息
JTR
JTR (Java Test Runner)是一个开源的基于反转控制(IOC)的J2EE测试框架。它允许你构建复杂的J2EE测试套件(Test Suites)并连到应用服务器执行测试,可以包括多个测试实例。JTR的licensed是GPL协议。
更多JTR信息
Marathon
Marathon是一个针对使用Java/Swing开发GUI应用程序的测试框架,它由recorder, runner 和 editor组成,测试脚本是python代码。Marathon的焦点是放在最终用户的测试上。
更多Marathon信息
TestNG
TestNG是根据JUnit 和 NUnit思想而构建的一个测试框架,但是TestNG增加了许多新的功能使得它变得更加强大与容易使用比如:
*支持JSR 175注释(JDK 1.4利用JavaDoc注释同样也支持)
*灵活的Test配置
*支持默认的runtime和logging JDK功能
*强大的执行模型(不再TestSuite)
*支持独立的测试方法。
更多TestNG信息
Surrogate Test framework
Surrogate Test framework是一个值得称赞单元测试框架,特别适合于大型,复杂Java系统的单元测试。这个框架能与JUnit,MockEJB和各种支持模拟对象(mock object )的测试工具无缝给合。这个框架基于AspectJ技术。
更多Surrogate Test framework信息
MockCreator
MockCreator可以为给定的interface或class生成模拟对象(Mock object)的源码。
更多MockCreator信息
jMock
jMock利用mock objects思想来对Java code进行测试。jMock具有以下特点:容易扩展,让你快速简单地定义mock objects,因此不必打破程序间的关联,让你定义灵活的超越对象之间交互作用而带来测试局限,减少你测试地脆弱性。
更多jMock信息
EasyMock
EasyMock为Mock Objects提供接口并在JUnit测试中利用Java的proxy设计模式生成它们的实例。EasyMock最适合于测试驱动开发。
更多EasyMock信息
Grinder
Grinder是一个开源的Java负载测试框架,它通过很多负载注射器来为分布式测试提供了便利。
支持用于执行测试脚本的Jython脚本引擎
HTTP测试可通过HTTP代理进行管理。
更多Grinder信息
XMLUnit
XMLUnit不仅有Java版本的还有.Net版本的。Java开发的XMLUnit提供了两个JUnit 扩展类XMLAssert和XMLTestCase,和一组支持的类。这些类可以用来比较两张XML之间的不同之处,展示XML利用XSLT来,校验XML,求得XPath表达式在XML中的值,遍历XML中的某一节点利DOM展开,
更多XMLUnit信息
Jameleon
Jameleon一个自动化测试工具。它被用来测试各种各样的应用程序,所以它被设计成插件模式。为了使整个测试过程变得简单Jameleon提供了一个GUI,因此Jameleon实现了一个Swing 插件。
更多Jameleon信息
J2MEUnit
J2MEUnit是应用在J2ME应用程序的一个单元测试框架。它基于JUnit.
更多J2MEUnit信息
Jetif
Jetif是一个用纯Java实现的回归测试框架。它为Java程序单元测试以及功能测试提供了一个简单而且可 伸缩的架构,可以用于个人开发或企业级开发的测试。它容易使用,功能强大,而且拥有一些企业级测试的 重要功能。Jetif来源于JUnit, JTestCase以及TestNG的启发,有几个基本的概念直接来自于JUnit, 比如说断言机制,Test Listener的概念,因此从JUnit转到Jetif是非常容易的。
更多Jetif信息
GroboUtils
GroboUtils使得扩展Java测试变得可能。它包括用在Java不同方面测试的多个子项目。在GroboUtils中最常被到的工具是:多线程测试(multi-threaded tests),整体单元测试(hierarchial unit tests),代码覆盖工具(code coverage tool)。
更多GroboUtils信息
Testare
TESTARE是用来简化分布式应用程序(比如:在SERVLETS,JMS listeners, CORBA ORBs或RMI环境下)测试开发过程的一个测试框架.
更多Testare信息
MockLib
MockLib是一个很小的包所以可容易地动态创建一个模拟对象.你可以从模拟的系统中抛出异常来确保你的系统能够正确处理错误.它同样也是一个线程安全的模拟对象库.
更多MockLib信息
JellyUnit
JellyUnit是一个基于Jelly的JUnit测试机制.它允许用Jelly脚本来完成单元测试.尤其是对于XML,XPath,SQL,HTTP,JMS和SOAP交互的测试特别有用.
更多JellyUnit信息
Pisces
这个项目继承于JUnit目的是提供一个分布式的测试环境.它给开发者/测试人员一个运行远程JUnits和复杂测试案例的能力,这个案例由几个并行运行的远程JUnit测试组成。
更多Pisces信息
JUnitEE
JUnitEE是对JUnit的一个简单扩展,可以支持在一个J2EE应用程序服务器上执行标准的测试案例。它主要由一个把测试结果输出为html的servlet组成。
更多JUnitEE信息
关于junit单元测试工具的安装请参看第二课的内容(其实就是导入一个junit的jar包就行了)首先认识几个注解标签
@Test:测试方法
@Before:初始化方法
@After:释放资源
执行顺序:@Before->@Test->@After
第一步新建测试文件夹(目的就是用来存放测试类,使项目更整洁,分类明确,好管理)
选中项目右键new->Source Folder 输入文件夹的名称例如test
在测试文件夹下创建测试类(就是创建个普通的类)
如下在测试类中使用junit进行单元测试
下面只是先搭建一个测试框架
搭建好之后测试hibernate访问数据库的代码注意:导入的包不要弄错,都是hibernate的包
public class StudentTest { private SessionFactory sessionFactory private Session session private Transaction transaction @Before public void init(){ //创建配置对象 Configuration config = new Configuration() //创建服务注册对象 ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(config.getProperties()).buildServiceRegistry() //创建会话工厂对象 sessionFactory = config.buildSessionFactory(serviceRegistry) //会话对象 session = sessionFactory.openSession() //开启事务 transaction = session.beginTransaction() } @Test public void testSaveStudents(){ Student s = new Student(1, "小明", new Date(), "北京xxxx街道5号楼201") session.save(s)//保存对象到数据库 } @After public void destory(){ transaction.commit()//提交事务 session.close()//关闭会话 sessionFactory.close()//关闭会话工厂 }}
进行测试如下: 选中测试方法右键run as ->junit test就行了
执行成功控制台打印信息:
查看数据库表
可以看到增加了一条信息,测试成功
首先我们需要先下载相应的 JUnit 相关的 JAR 包,下载的过程可以去 JUnit 的官方网站,也可以直接通过 Maven 资源仓库来完成。使用简单的 @Test 注解实现我们的测试方法的编写和执行
准备工作做好之后,接下来我们就可以开始尝试编写壹个简单的测试代码了。首先,我们编写了壹个 Calculator 类,并提供五个方法分别完成加减乘除以及求平方的运算。代码如下:
package net.oschina.bairrfhoinn.main
public class Calculator {
public void add(int n){
result += n
}
public void substract(int n){
result -= n
}
public void multiply(int n){
result *= n
}
public void divide(int n){
result /= n
}
public void square(int n){
result = n * n
}
public int getReuslt(){
return result
}
public void clear(){
result = 0
}
private static int result
}
在测试类中用到了JUnit4框架,自然要把相应地Package包含进来。最主要地一个Package就是org.junit.*。把它包含进来之后,绝大部分功能就有了。还有一句话也非常地重要“import static org.junit.Assert.*”,我们在测试的时候使用的壹系列assertEquals()方法就来自这个包。大家注意壹下,这是壹个静态包含(static),是JDK5中新增添的壹个功能。也就是说,assertEquals是Assert类中的壹系列的静态方法,壹般的使用方式是Assert. assertEquals(),但是使用了静态包含后,前面的类名就可以省略了,使用起来更加的方便。
另外要注意的是,我们的测试类是壹个独立的类,没有任何父类。测试类的名字也可以任意命名,没有任何局限性。所以我们不能通过类的声明来判断它是不是一个测试类,它与普通类的区别在于它内部的方法的声明,我们接着会讲到。在测试类中,并不是每壹个方法都是用于测试的,所以我们必须使用“注解”来明确表明哪些是测试方法。“注解”也是JDK5的壹个新特性,用在此处非常恰当。我们可以看到,在某些方法的前有@Before、@Test、@Ignore等字样,这些就是注解,以壹个“@”作为开头。这些注解都是JUnit4自定义的,熟练掌握这些注解的含义,对于编写恰当的测试类非常重要。
接下来我们创建壹个测试类 CalculatorTest.java,代码如下:
package net.oschina.bairrfhoinn.test
import static org.junit.Assert.*
import org.junit.Test
import net.oschina.bairrfhoinn.main.Calculator
public class CalculatorTest {
private static Calculator calculator = new Calculator()
@Test
public void testAdd(){
calculator.add(7)
calculator.add(8)
assertEquals(15, calculator.getReuslt())
}
}
首先,我们要在方法的前面使用@Test标注,以表明这是壹个测试方法。对于方法的声明也有如下要求:名字可以随便取,没有任何限制,但是返回值必须为void,而且不能有任何参数。如果违反这些规定,会在运行时抛出壹个异常。至于方法内该写些什么,那就要看你需要测试些什么了。比如上述代码中,我们想测试壹下add()方法的功能是否正确,就在测试方法中调用几次add函数,初始值为0,先加7,再加8,我们期待的结果应该是15。如果最终实际结果也是15,则说明add()方法是正确的,反之说明它是错的。assertEquals(15, calculator.getResult())就是用来判断期待结果和实际结果是否相等,其中第壹个参数填写期待结果,第二个参数填写实际结果,也就是通过计算得到的结果。这样写好之后,JUnit 会自动进行测试并把测试结果反馈给用户。
如果想运行它,可以在 eclipse 的资源管理器中选择该类文件,然后点击右键,选择 Run As->JUnit Test 即可看到运行结果。
使用@Test 的属性 Ignore 指定测试时跳过这个方法
如果在写程序前做了很好的规划,那么哪些方法是什么功能都应该实现并且确定下来。因此,即使该方法尚未完成,他的具体功能也是确定的,这也就意味着你可以为他编写测试用例。但是,如果你已经把该方法的测试用例写完,但该方法尚未完成,那么测试的时候无疑是“失败”。这种失败和真正的失败是有区别的,因此 JUnit 提供了壹种方法来区别他们,那就是在这种测试函数的前面加上 @Ignore 标注,这个标注的含义就是“某些方法尚未完成,暂不参与此次测试”。这样的话测试结果就会提示你有几个测试被忽略,而不是失败。壹旦你完成了相应函数,只需要把@Ignore标注删去,就可以进行正常的测试。
比如说上面的测试类 Calculator.java 中,假设我们的 Calculator 类的 multiply() 方法没有实现,我们可以在测试类 CalculatorTest 中先写如下测试代码:
package net.oschina.bairrfhoinn.test
import static org.junit.Assert.*
import org.junit.Ignore
import org.junit.Test
import net.oschina.bairrfhoinn.main.Calculator
public class CalculatorTest {
private static Calculator calculator = new Calculator()
... //此处代码省略
@Ignore("method square() not implemented, please test this later...")
@Test
public void testSquare(){
calculator.square(3)
assertEquals(9, calculator.getReuslt())
}
}
我们再运行壹次测试,会看到如下结果,从图中可以很明显的看出,方法testSquare() 上的 @Ignore 注解已经生效了,运行时直接跳过了它,而方法testAdd()仍然正常的运行并通过了测试。
使用注解 @Before 和 @After 来完成前置工作和后置工作
前置工作通常是指我们的测试方法在运行之前需要做的壹些准备工作,如数据库的连接、文件的加载、输入数据的准备等需要在运行测试方法之前做的事情,都属于前置工作;类似的,后置工作则是指测试方法在运行之后的壹些要做的事情,如释放数据库连接、输入输出流的关闭等;比如我们上面的测试,由于只声明了壹个 Calculator 对象,他的初始值是0,但是测试完加法 *** 作后,他的值就不是0了;接下来测试减法 *** 作,就必然要考虑上次加法 *** 作的结果。这绝对是壹个很糟糕的设计!我们非常希望每壹个测试方法都是独立的,相互之间没有任何耦合度。因此,我们就很有必要在执行每壹个测试方法之前,对Calculator对象进行壹个“复原” *** 作,以消除其他测试造成的影响。因此,“在任何壹个测试方法执行之前必须执行的代码”就是壹个前置工作,我们用注解 @Before 来标注它,如下例子所示:
package net.oschina.bairrfhoinn.test
...
import org.junit.After
import org.junit.Before
import org.junit.Ignore
import org.junit.Test
public class CalculatorTest {
...//这里省略部分代码
@Before
public void setUp() throws Exception {
calculator.clear()
}
@After
public void tearDown() throws Exception {
System.out.println("will do sth here...")
}
...//这里省略部分代码
}
另外要说的是,注解 @Before 是定义在 org.junit.Before 这个类中的,因此使用时需要将其引入我们的代码中。这样做了之后,每次我们运行测试方法时,JUnit 都会先运行 setUp() 方法将 result 的值清零。不过要注意的是,这里不再需要 @Test 注解,因为这并不是壹个 test,只是壹个前置工作。同理,如果“在任何测试执行之后需要进行的收尾工作,我们应该使用 @After 来标注,方法与它类似。由于本例比较简单,不需要用到此功能,所以我们只是简单了给它添加了壹个 tearDown() 方法并在收尾时打印壹句话到控制台,并且使用 @After 来注解这个方法。
使用@BeforeClass 和 @AfterClass 来完成只需要执行壹次的前置工作和后置工作
上面我们提到了两个注解 @Before 和 @After ,我们来看看他们是否适合完成如下功能:有壹个类负责对大文件(超过500 MB)进行读写,他的每壹个方法都是对文件进行 *** 作。换句话说,在调用每壹个方法之前,我们都要打开壹个大文件并读入文件内容,这绝对是壹个非常耗费时的 *** 作。如果我们使用 @Before 和 @After ,那么每次测试都要读取壹次文件,效率及其低下。所以我们希望的是,在所有测试壹开始读壹次文件,所有测试结束之后释放文件,而不是每次测试都读文件。JUnit的作者显然也考虑到了这个问题,它给出了@BeforeClass 和 @AfterClass 两个注解来帮我们实现这个功能。从名字上就可以看出,用这两个注解标注的函数,只在测试用例初始化时执行 @BeforeClass 方法,当所有测试执行完毕之后,执行 @AfterClass 进行收尾工作。在这里要注意壹下,每个测试类只能有壹个方法被标注为 @BeforeClass 或 @AfterClass,而且该方法必须是 public static 类型的。
使用@Test 的属性 timeout 来完成限时测试,以检测代码中的死循环
现在假设我们的 Calculator 类中的 square() 方法是个死循环,那应该怎么办呢,比如说像下面这样:
public void square(int n){
for(){}
}
如果测试的时候遇到死循环,你的脸上绝对不会露出笑容的。因此,对于那些逻辑很复杂,循环嵌套比较深的、有可能出现死循环的程序,因此壹定要采取壹些预防措施。限时测试是壹个很好的解决方案。我们给这些测试函数设定壹个预期的执行时间,超过了这壹时间,他们就会被系统强行终止,并且系统还会向你汇报该函数结束的原因是因为超时,这样你就可以发现这些 Bug 了。要实现这壹功能,只需要给 @Test 标注加壹个参数timeout即可,代码如下:
@Test(timeout=2000L)
public void testSquare() {
calculator.square(3)
assertEquals(9, calculator.getReuslt())
}
timeout参数表明了你预计该方法运行的时长,单位为毫秒,因此2000就代表2秒。现在我们让这个测试方法运行壹下,看看失败时是什么效果。
使用@Test 的属性expected来监控测试方法中可能会抛出的某些异常
JAVA中的异常处理也是壹个重点,因此你经常会编写壹些需要抛出异常的函数。如果你觉得壹个函数应该抛出异常,但是它没抛出,这算不算 Bug 呢?这当然是Bug,JUnit 也考虑到了这壹点,并且可以帮助我们找到这种 Bug。例如,我们写的计算器类有除法功能,如果除数是壹个0,那么必然要抛出“除0异常”。因此,我们很有必要对这些进行测试。代码如下:
@Test(expected=java.lang.ArithmeticException.class)
public void testDivide(){
calculator.divide(0)
}
如上述代码所示,我们需要使用@Test注解中的expected属性,将我们要检验的异常(这里是 java.lang.ArithmeticException)传递给他,这样 JUnit 框架就能自动帮我们检测是否抛出了我们指定的异常。
指定 JUnit 运行测试用例时的 Runner
大家有没有想过这个问题,当你把测试代码提交给JUnit框架后,框架是如何来运行你的代码的呢?答案就是Runner。在JUnit中有很多个Runner,他们负责调用你的测试代码,每壹个Runner都有其各自的特殊功能,你要根据需要选择不同的Runner来运行你的测试代码。可能你会觉得奇怪,前面我们写了那么多测试,并没有明确指定壹个Runner啊?这是因为JUnit中有壹个默认的Runner,如果你没有指定,那么系统会自动使用默认Runner来运行你的代码。换句话说,下面两段代码含义是完全壹样的:
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
@RunWith(JUnit4.class)
public class CalculatorTest {
...//省略此处代码
}
//用了系统默认的JUnit4.class,运行效果完全壹样
public class CalculatorTest {
...//省略此处代码
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)