JUnit多线程

时间:2024.4.20

有关Junit的多线程测试

Junit和许多开源软件项目集成在一起,但是Junit执行多线程的单元测试有一些问题。这篇文章介绍Junit的一个扩展类库———GroboUtils,这个类库被设计为来解决这些问题,并且使在Junit中进行单元测试成为可能。对Junit和线程有一个基本的理解是有好处的,但对于本篇文章的读者来说不是必需的。

介绍

如果你已经在一个开源的Java项目上工作,或者读了许多有关“极限编程”和其它“快速开发模式”的书籍,那么,你很有可能已经听说过有关Junit的事情。它是由Erich Gamma和Kent Beck编写的,Junit是一个Java的自动测试的框架,它允许你为你的软件定义的“单元测试”———不管是测试程序还是功能代码,通常都是基于方法调用方法的。

Junit能在很多方面帮助你的开发团队———在一些文章中已经包含了很多这方面的介绍。但从一个开者到另一个开发者,Junit实际上只专注于两件事:

1、它强制你使用自己的代码。你的测试代码只是作为你的产品代码的客户端,从客户端的描述所获得的对你的软件的了解,能够帮助你标识出在API中的错误以及怎样改进代码,使其最终达到可以使用的目的。

2、它会给你对软件中改变带来信心,如果你的测试用例被中断,你就是立刻知道错误。在一天工作结束的时候,如果测试提示是绿色的,则代码是正确,你可以自信的检查它。

但是Junit不是解决所有软件测试中问题,第三方的扩展类库,例如HttpUnit,JwebUnit,XMLUnit等,已经认识到这些框架中不足,并且通过添加功能弥补不足,这些不足之一就是Junit不包含多线程的单元测试。

在这篇文章中,我们会看到一个很少有人知道的解决这个问题的扩展类库。我们通过建立Junit框架开始,并且运行一个例子来展示Junit在线程没试中的不足。在我们认识了Junit在线程测试方面的不足之后,我们通过一个使用GroboUtils框架的例子来讨论GroboUnitls

线程回顾

对于那些不熟悉线程的人来说,在这一点上是非常不安的(一点都不夸大),离开你的系统,我们将对线做一个简单的介绍。线程允许你的软件有多个任务,也就是说可以同时可做两件事情。

在Khalid Mugal和Rolf Rasmussen的书(A Programmer's Guide to Java Certification)中,对线程做了下面这样的简短描述:

一个线程是一个程序中的可执行单元,它是被独立执行的。在运行时,在程序中的线程有一个公共的内存空间,因此,能够共享数据和代码;也就是说,它们是轻量级的。它也共享正在运行程序的进程。

Java 线程使运行时环境异步,它允许不同的任务同时被执行。(p.272)

在web应用程序中,许多用户可能同时发请求给你的软件。当你写单元测试对你的代码进行压力测试时,你需要模拟许多并发事件,如果你在开发健壮的中间件,这样做是尤其重要的。对于这些组件,使用线程测试是一个好的想法。

不幸的是,Junit在这方面是不足的。

JUnit多线程

JUnit多线程

JUnit多线程

1、 打印“Hello,World”;

2、 初始化并起动一个支持打印“Delayed Hello World.”线程;

3、 打印“Goodbye,World”。

如果你运行这个测试类,你会注意到一些错误。TextHellWorld()方法像你期望的那样运行和结束。它没有发出任何有关线程的异常,但是你却不会接受到来自线程的返回信息。注意,你不会看到“Delayed Hello World”。为什么?因为线程还在激活状态的时候,Junit已经执行完成。问题发生在下面这行,使线程执行结束的时候,你的测试不能反映出它的执行结果。这个问题行是在Junit的TestRunner中。它没有被设计成搜寻Runnable实例,并且等待这些线程发出报告,它只是执行它们并且忽略了它们的存在。因为这个原因,几乎不可能在Junit中编写和维护多线程的单元测试。

进入GroboUtils

GroboUtils是Matt Albrecht编写的一个开源项目,它的目标是扩展Java的测试可能性。GroboUtils被发布在MIT许可下,这使它可以很友好的包含到其它的开源项目中。

Grobo TestingJUnit 子项目

GroboUtils被列入与同类测试方面有关的试验的子项目。这篇文章的焦点集中在Grobo TestingJUnit 子项目,它为Junit引入了一个支持多线程测试的扩展类库。(这个子项目还引入了集成测试和严重错误的概念,但是这些特征超出了这篇文章所讨论的范围。)

在GroboTestingJUnit子项目内是BroboTestingJUnit-1.1.0-core.jar类库,它包含了MultiThreadedTestRunner和TestRunnable类,这两个类是对Junit进行扩展处理多线程测试所必须的。

TestRunnable类

TestRunnalbe类扩展了junit.framework.Assert类并且实现了java.lang.Runnable接口。你可以在你的测试类内定义TestRunnable对象做为内隐类。虽然,传统的线程类实现一个run()方法,但是你的嵌套TestRunnable类必须实现runTest()方法来替代run()方法。这个方法将被MultiThreadedTestRunner类在运行时调用,因此你不应该在构造器中调用它。

MultiThreadedTestRunner类

MultiThreadedTestRunner是一个允许把异步运行的线程数组放入Junit内一个框架。这个类在它的构造器中接受一个TestRunnable实例的数组做为参数。一旦建立了这个类的一个实例,它的runTestRunnables()方法就应该被调用开始执行线程测试。

和标准的JunitTestRunner不一样,MultiThreadedTestRunner将等待,直到所有的线程执行终止退出。这样就强制Junit在线程执行任务的时候进行等待,从而巧妙的解决了我们前面提出的问题。让我们来看一下GroboUtils和Junit是怎样集成的。

编写多线程测试

现在把上面例子中的内隐类扩展自

net.sourceforge.groboutils.junit.vl.TestRunnable包,我们必须像下面这样来重写

JUnit多线程

JUnit多线程

结束语

写一个多线程的单元测试不用感到苦脑,GroboUtils类库为编写多线程的单元测试提供了一个清晰简单的API接口,通过把这个类库添加到你的工具包中,你就可以把单元测试扩展到模拟繁重的WEB网络通讯和并发的数据库处理,以及对你的同步方法进行压力测试。


第二篇:JUnit测试框架


JUnit测试框架

开发过程中进行单元测试,尽可能尽早的将BUG找出,是开发者应该做的。JUNIT为JAVA开发者提供了一个很好的测试机制

JUnit的主要功能:

管理测试用例;

定义测试代码;

定义测试环境;

检测测试结果;

JUnit的各种断言:

assertEquals([String message], expected, actual)——这是使用得最多的断言形式。expected-是你的期望值(通常要硬编码),actual-被测代码实际产生的值,message-可选的消息,如果提供的话,将会在发生错误的时候报告这个消息。

assertNotNull(a)

测试a是否非空,a是一个对象或者null

assertNull([String message],java.lang.Object object)——验证一个给定的对象是否为Null(或者为非Null),如果答案为否,则将会失败。message参数是可选的。

assertSame( [String message], expected,actual)——验证expected参数和actual参数所引用的是否为同一对象,如果不是的话,将会失败。Message参数是可选的。

assertTrue( [String message],boolean condition)——验证给定的二元条件是否为真,如果为假的话,将会失败。Message参数是可选的。

assertFalse( [String message],boolean condition)——验证给定的二元条件是否为假,如果不为假的话,将会失败。Message参数是可选的

fail( String message )——使测试立即失败,其中message参数使可选的。这种断言通常被用于标记某个不应该到达的分支(例如,在一个预期发生的异常之后)

setUpBeforeClass()【注:静态方法,在测试类执的测试方法执行前被系统调用,只被调用一次】,

tearDownAfterClass()【注:静态方法,在测试类的所有测试方法执行完毕后被系统调用,只被调用一次】,

setUp()【注:非静态方法,在每个测试方法执行前,被系统调用,有多少个测试方法,就被调用多少次】,

tearDown()【注:非静态方法,在每个测试方法执行完毕后,被系统调用,有多少个测试方法,就被调用多少次】

JUnit4 注解 ,

@Test: 测试方法

@Ignore: 被忽略的测试方法

@Before: 每一个测试方法之前运行

@After: 每一个测试方法之后运行

@BeforeClass: 所有测试开始之前运行

@AfterClass: 所有测试结束之后运行

JUnit将测试失败的情况分为两种:failure和error。Failure一般由单元测试使用的断言方法判断失败引起,它表示在测试点发现了问题;而error则是由代码异常引起,这是测试目的之外的发现,它可能产生于测试代码本身的错误(测试代码也是代码,同样无法保证完全没有缺陷),也可能是被测试代码中的一个隐藏的bug。

结合主要功能,举个简单的例子分析如下:

源代码:

public class SampleCalculator

{

public int add(int augend , int addend)

{return augend + addend ;}

public int subtration(int minuend , int subtrahend)

{ return minuend – subtrahend ;}

}

测试用例(TestCase):

import junit.framework.TestCase;

public class TestSample extends TestCase

{

private int a;

private int b;

private int r1,r2;

void setUp() /*开始测试当前用例–初始化测试环境*/

{

a = 50;

b = 20;

r1 = 70;

r2 = 30;

}

void tearDown()/*当期用例测试结束*/

{}

public void testAdd()/*测试SampleCalculator 类的Add函数*/

{

SampleCalculator calculator = new SampleCalculator();

int result = calculator.add(a , b);

assertEquals(r1 , result);/*检测测试结果*/

}

public void testSubtration()/*测试SampleCalculator 类的Subtration函数*/

{

SampleCalculator calculator = new SampleCalculator();

int result = calculator.subtration(a , b);

assertEquals(r2 , result);/*检测测试结果*/

}

}

以上TestSample测试用例中就对SampleCalculator进行了完整的单元测试,并对测试结果做了预期说明。

JUnit的测试步骤

JUnit测试框架

:

一步:写一个简单的方法,作为测试的方法。

第二步

JUnit测试框架

将JUnit加入到工程里面。

第三步,创建测试的class

JUnit测试框架

JUnit测试框架

第四步。选中要测试的方法。

如果你的工程已经自动加载了Junit用的jar包,可跳过 5 6 这两步。

JUnit测试框架

第五步

JUnit测试框架

向工程中添加Junit jar包

第六步。选择Junit jar包

JUnit测试框架

第七步,编写测试方法体,并运行。

JUnit测试框架

第八步 查看结果。

绿色 表示测试通过。

更多相关推荐:
Java多线程总结

基本概念:并发性和并行性:并发性指的是同一时刻只能有一条指令执行,但是多个进程指令被快速轮换执行并行性是指同一时刻,有多条指令在多个处理器上同时执行,使得在宏观上具有多个进程同时执行的结果临界区:修改共享资源的…

java多线程总结(含代码)

Java多线程总结Java多线程总结目标:理解程序、线程和进程的概念理解多线程的概念掌握线程的各种状态熟练使用Thread类、Runnable接口创建线程熟练使用线程各种方法1、程序、线程、进程进程:调度和和独…

Java多线程总结

Java多线程总结线程的四种状态:就绪Runable——运行中Running——阻塞Blocked——死亡Dead(结束)线程的状态转换图线程在一定条件下,状态会发生变化。线程变化的状态转换图如下:1、新建状态…

JAVA中实现多线程总结

我们知道,在操作系统级别上软件的运行一般都是以进程为单位,而在每个进程的运行过程中允许同时并发执行多个不同线程,这就使得一个程序能同时执行不同的操作。使用多线程的目的是为了最大限度地利用计算机CPU资源。JAV…

Java多线程总结

多线程总结在学习编程的过程中,我觉得不止要获得课本的知识,更多的是通过学习技术知识提高解决问题的能力,这样我们才能走在最前方,更多Java学习,请登陆疯狂java官网。1.重写线程Thread,Runnable…

C++多线程总结

C线程总结目录1使用CreateThread函数生成的线程211CreateThread函数原型212线程线程句柄线程ID的区别3121线程与线程句柄的区别3122线程句柄与线程ID的区别313线程的管理和终止...

多线程编程知识总结

多线程编程一问题的提出11问题的引出编写一个耗时的单线程程序新建一个基于对话框的应用程序SingleThread在主对话框IDDSINGLETHREADDIALOG添加一个按钮ID为IDCSLEEPSIXSEC...

JAVA多线程与并发学习总结

JAVA多线程与并发学习总结1计算机系统使用高速缓存来作为内存与处理器之间的缓冲将运算需要用到的数据复制到缓存中让计算能快速进行当运算结束后再从缓存同步回内存之中这样处理器就无需等待缓慢的内存读写了缓存一致性多...

java-线程总结

Java线程概念与原理Java线程创建与启动Java线程线程栈模型与线程的变量Java线程线程状态的转换Java线程线程的同步与锁Java线程线程的交互Java线程线程的调度休眠Java线程线程的调度优先级Ja...

Java多线程编程总结

Java线程概念与原理一操作系统中线程和进程的概念现在的操作系统是多任务操作系统多线程是实现多任务的一种方式进程是指一个内存中运行的应用程序每个进程都有自己独立的一块内存空间一个进程中可以启动多个线程比如在Wi...

Java多线程编程总结

Java多线程编程总结下面是Java线程系列博文的一个编目Java线程概念与原理Java线程创建与启动Java线程线程栈模型与线程的变量Java线程线程状态的转换Java线程线程的同步与锁Java线程线程的交互...

Java_多线程与并发编程总结

Java多线程与并发编程总结认识多任务多进程单线程多线程要认识多线程就要从操作系统的原理说起以前古老的DOS操作系统V622是单任务的还没有线程的概念系统在每次只能做一件事情比如你在copy东西的时候不能ren...

多线程总结(31篇)