使用GroboUtils进行jUnit的多线程测试
jUnit不支持多线程测试(具体表现为,在@Test标记的方法中启动多线程测试,这是多线程中的Assert方法失效
具体原因是jUnit执行器执行的时候,执行线程很快退出,在多线程中还没有调用Assert的时候主线程就退出了,
而且,貌似jUnit也不会检测其他线程中调用Assert方法,即使其他线程中Assert方法失败了,
总的测试结果往往还是显示成功),
需要借用GroboUtils(http://groboutils.sourceforge.net/downloads.html)
GroboUtils是一个工具集合,里面包含各种测试工具,这里使用的是该工具集中的jUnit扩展.
这里使用的是GroboUtils v5版本,下载 Complete package:GroboUtils-5.zip
解压后 使用 GroboUtils-5\lib\core\GroboTestingJUnit-1.2.1-core.jar 这个即可.
GroboUtils 工具集中的jUnit扩展 的文档页面:
http://groboutils.sourceforge.net/testing-junit/index.html
示例(来自: http://mushiqianmeng.blog.51cto.com/3970029/897786):
/** * 多线程测试用例 * * @author lihzh(One Coder) * @date 2012-6-12 下午9:18:11 * @blog http://www.coderli.com */ @Test public void MultiRequestsTest() { // 构造一个Runner TestRunnable runner = new TestRunnable() { @Override public void runTest() throws Throwable { // 测试内容 // 可以在这里直接调用Assert的各种方法,因为TestRunnable类是继承自Assert的 } }; int runnerCount = 100; //Rnner数组,想当于并发多少个。 TestRunnable[] trs = new TestRunnable[runnerCount]; for (int i = 0; i < runnerCount; i++) { trs[i] = runner; } // 用于执行多线程测试用例的Runner,将前面定义的单个Runner组成的数组传入 MultiThreadedTestRunner mttr = new MultiThreadedTestRunner(trs); try { // 开发并发执行数组里定义的内容 mttr.runTestRunnables(); } catch (Throwable e) { e.printStackTrace(); } }
备忘:
JUnit best practices
http://www.javaworld.com/article/2076265/testing-debugging/junit-best-practices.html?page=3
主要关注3个类:TestRunnable,TestMonitorRunnable,MultiThreadedTestRunner,全部来自包:
net.sourceforge.groboutils.junit.v1.MultiThreadedTestRunner.
(1) TestRunnable 抽象类,表示一个测试线程,实例需要实现该类的runTest()方法,在该方法中写自己用的测试代码.
该类继承了jUnit的junit.framework.Assert类,所以可以在TestRunnable中使用各种Assert方法
(可惜因为GroboUtils使用的jUnit版本较老,且久未更新,新版本的jUnit中已经不推荐使用这个类的方法了).
该类实现了Runnable,在run方法中调用抽象方法runTest().
Doc中介绍
public abstract class TestRunnable
extends junit.framework.Assert
implements java.lang.Runnable
Instances of this class only execute in the runTestRunnables method of the MultiThreadedTestRunner class.
TestCases should define inner classes as a subclass of this, implement the runTest() method,
and pass in the instantiated class as part of an array to the runTestRunnables method.
Call delay( long ) to easily include a waiting period.
This class allows for all assertions to be invoked,
so that subclasses can be static or defined outside a TestCase.
If an exception is thrown from the runTest() method,
then all other test threads will terminate due to the error.
The runTest() method needs to be responsive to InterruptedException, resulting from the
owning MultiThreadedTestRunner interrupting the thread in order to signal the early
termination of the threads. The InterruptedExceptions may be propigated outside the runTest()
implementation with no harmful effects. Note that this means that InterruptedExceptions
are part of the framework, and as such carry information that your runTest()
implementations cannot override; in other words, don't let your test
propigate an InterruptedException to indicate an error.
Tests which perform a set of monitoring checks on the object-under-test should
extend TestMonitorRunnable, since monitors run until told to stop.
The Thread.stop() command will be sent with a MultiThreadedTestRunner.TestDeathException.
(2) MultiThreadedTestRunner
这个类相当与一个ExecuteService,可以用来执行 TestRunnable,构造函数需要传入TestRunnable数组,
表示需要测试的线程.
调用MultiThreadedTestRunner.runTestRunnables() 方法启动测试线程,开始执行测试.
这个方法默认让测试线程TestRunnable的run方法最多运行1天,也可以调用
MultiThreadedTestRunner.runTestRunnables(long maxTime) 这个方法,然测试线程TestRunnable
最多执行 maxTime 毫秒.如果超过maxTime毫秒之后,TestRunnable还没有执行完毕,则TestRunnable
会被中断,并且MultiThreadedTestRunner 会抛出异常,
导致测试失败fail("Threads did not finish within " + maxTime + " milliseconds.").
每个TestRunnable中runTest需要能够控制自己在什么时间自己结束自己,精确控制测试时间,不要利用
上面的maxTime.
另外,有上面Doc文档中:
If an exception is thrown from the runTest() method,
then all other test threads will terminate due to the error.
可知,假如有一个TestRunnable的runTest()方法中抛出异常,会终止所有TestRunnable的运行,
并导致测试失败.
Doc:
java.lang.Object
extended bynet.sourceforge.groboutils.junit.v1.MultiThreadedTestRunner
public class MultiThreadedTestRunner
extends java.lang.Object
A framework which allows for an array of tests to be run asynchronously.
TestCases should reference this class in a test method.
Update for July 9, 2003: now, you can also register TestRunner instances
as monitors (request 771008); these run parallel with the standard
TestRunner instances, but they only quit when all of the standard
TestRunner instances end.
Fixed bugs 771000 and 771001: spawned threads are now Daemon threads,
and all "wild threads" (threads that just won't stop) are Thread.stop()ed.
All these changes have made this class rather fragile, as there are many
threaded timing issues to deal with. Expect future refactoring with backwards compatibility.
3.TestMonitorRunnable
表示监控线程,可以让每一个TestRunnable对应一个TestMonitorRunnable,在TestMonitorRunnable中监控
TestRunnable.TestMonitorRunnable是TestRunnable的子类,提供了一些方便使用的方法.
TestMonitorRunnable使用示例参考:http://blog.csdn.net/wodestudy/article/details/17119741
附 TestMonitorRunnable 源码:
public abstract class TestMonitorRunnable extends TestRunnable { public TestMonitorRunnable() { super(true); } public abstract void runMonitor() throws Throwable; public void runTest() throws Throwable { for(; !isDone() && !Thread.interrupted(); yieldProcessing()) runMonitor(); runMonitor(); } protected void yieldProcessing() throws InterruptedException { Thread.yield(); } }
相关推荐
首先,GroboUtils为JUnit提供了一种名为`ThreadControl`的接口,它允许开发者暂停、恢复或终止测试线程。这样,我们可以在特定时刻检查测试对象的状态,确保它们在预期的时间点完成了预期的操作,避免了由于线程间的...
在多线程环境中使用JUnit进行测试会面临一些挑战,比如如何确保测试的线程安全,避免测试结果的不确定性,以及如何有效地模拟并发情况。GroboUtils-5可能就是为了解决这些问题而设计的工具集,它可能包含了用于创建...
它能够与JUnit、TestNG等主流的测试框架无缝对接,让多线程测试成为现有测试流程的一部分,而不是孤立的存在。 在实际使用中,groboutils的文档详尽且易懂,提供了丰富的示例代码,帮助开发者快速上手。同时,其...
总之,GroboUtils-5-core.jar是Java开发者进行多线程测试时的得力助手,它以丰富的功能、简洁的API和深度的Junit集成,降低了多线程测试的复杂性和难度,提高了测试的覆盖率和可靠性。无论你是经验丰富的测试工程师...
总的来说,groboutils是一个专注于多线程和测试的Java工具集,它提供了高级的多线程管理功能,并且集成了JUnit,增强了测试能力。通过这个单一的JAR文件,开发者可以轻松地在其项目中引入这些实用工具,提高代码的...
6. **性能测试**:除了基本的功能测试,GroboUtils 还支持进行性能测试,衡量在多线程环境下代码的运行效率,帮助优化代码性能。 7. **定制化测试**:GroboUtils 允许用户根据自己的需求定义测试规则和逻辑,提供...
GroboUtils-3 是一个专为进行多线程测试而设计的工具包,它提供了丰富的功能和接口,帮助开发者在复杂的应用场景下测试并优化多线程程序的性能和稳定性。在多线程编程中,确保并发执行的正确性和效率至关重要,因为...
本文将深入探讨`groboutils-core-5`的主要特性和使用方法,以及其如何支持多线程测试。 首先,`groboutils-core-5`的核心在于其对Java单元测试的全面支持。单元测试是验证软件最小可独立运行单元的过程,如方法或类...
这种测试通常会模拟多个用户同时访问系统,以检测潜在的线程安全问题、资源管理问题以及在高压力环境下的性能瓶颈。这一步对于确保软件在生产环境中能够可靠运行至关重要。 “自测jar包没有问题”意味着发布者已经...
描述中的"亲测可用"意味着有人已经实际测试过这个版本的Groboutils-core,并确认它在预期环境中能够正常工作。这给其他开发者提供了信心,他们可以相对放心地在自己的项目中使用这个库,而不用担心兼容性或功能性...
groboutils-core-5.jar 单元测试多线程
7. **线程优先级**:测试线程优先级对程序行为的影响,确保优先级较高的线程能得到合理的调度。 8. **异常处理**:检查在并发环境中异常的处理逻辑,确保线程中断或者抛出异常时,系统能正常恢复。 `GroboUtils-5-...
包含:groboutils-core-5.jar、fastdfs-client、kaptcha-2.3.2.jar、pinyin4j-2.5.0.jar、proton-jms-0.3.0-fuse-2.jar等