论坛首页 Java企业应用论坛

关于JUNIT的多线程测试问题

浏览 11263 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (5) :: 隐藏帖 (0)
作者 正文
   发表时间:2008-01-16  
skydream 写道
具体分析吧,如果这个private 方法有被其他public方法直接调用,而且逻辑清晰,则直接测试这个public方法。

如果这个private方法隐藏的很深,而且逻辑复杂,其他public方法离这个private的"距离"非常远。那就要考虑一下这个类的设计了,不容易测试的类,往往是功能过多,代码太大的类,建议拆分。

比如一个业务处理类,在复杂的业务逻辑处理过程中通过调用一个private方法做加密,而这个加密算法需要测试。类似这种情况,最好的办法就是将加密算法单独提取出一个类,功能非常单一的类,不要献小。然后对它进行junit测试,原来的类只要直接调用这个类就可以了。

这个也就是junit带来的一个推动力,为了达到测试友好,就必须保证代码清晰,相互耦合小。

说的很有道理啊,测试驱动。。。。
0 请登录后投票
   发表时间:2008-01-18  
red008说的用thread.join应该可以
或者在tes方法最后system.read.in() --当然这就不是自动化测试了.
0 请登录后投票
   发表时间:2008-01-26  
skydream 写道
具体分析吧,如果这个private 方法有被其他public方法直接调用,而且逻辑清晰,则直接测试这个public方法。

如果这个private方法隐藏的很深,而且逻辑复杂,其他public方法离这个private的"距离"非常远。那就要考虑一下这个类的设计了,不容易测试的类,往往是功能过多,代码太大的类,建议拆分。

比如一个业务处理类,在复杂的业务逻辑处理过程中通过调用一个private方法做加密,而这个加密算法需要测试。类似这种情况,最好的办法就是将加密算法单独提取出一个类,功能非常单一的类,不要献小。然后对它进行junit测试,原来的类只要直接调用这个类就可以了。

这个也就是junit带来的一个推动力,为了达到测试友好,就必须保证代码清晰,相互耦合小。

有道理,如果实在不想写,可以考虑用反射方式来调用该方法。
0 请登录后投票
   发表时间:2008-01-27  
似乎多线程测试主要问题还不是怎么在junit下跑起来,
而是如何设计测试能够暴露出并发问题。。。
0 请登录后投票
   发表时间:2008-01-27  
Godlikeme 写道
似乎多线程测试主要问题还不是怎么在junit下跑起来,
而是如何设计测试能够暴露出并发问题。。。


如何设计测试能够暴露出并发问题,呵呵,这个,基本上,很难

并发问题要想展现出来,除非程序写的实在是漏洞太大,否则基本上不要指望一般的单元测试案例能测试出问题了。

而且我个人意见,不建议用一般的测试去验证并发的正确性,很容易使得某些人走入另一个极端,即简单的跑一下单元测试,就下结论说这里的并发没有问题,后果是灾难性的

我就遇到过类似的场景:某人的多线程访问的代码不做同步,然后起两个线程测试,没有发现问题,ok,下结论测试通过......
0 请登录后投票
   发表时间:2008-01-27  
没错,除非问题是显而易见的。
0 请登录后投票
   发表时间:2008-01-31  
skydream 写道
呵呵,你可以去看看junit的源代码,junit主线程在最后是执行System.exit(0)来退出的。连jvm一起关闭,当然期间启动的其他线程就都没有办法工作了,jvm都关了有什么办法。

除上面几位的方法外,还有一个简单(当然也比较简陋)的方法,就是在覆盖TestCase的teardown(不知道有没有记错,和setup对应的最后执行的方法),在里面循环Sleep,然后检查是否还有其他活动线程,有就继续sleep,如果其他线程都退出了就跳出循环,让teardown方法退出,之后junit再System.exit(0)。

当然这个方法不是很通用,只适合那种简单的启动一个工作线程干点活就退出的那种情况。



是的,我也觉得是这个造成的,我的解决方案

public class MyThreadTest {

	final static private long THREAD_MAX_RUNTIME = 1000;

	final static private long THREAD_WAITTIME = 200;

	private MyThread myThread1 = null;

	private MyThread myThread2 = null;

	@Before
	public void setUp() throws Exception {
		myThread1 = new MyThread();
		myThread2 = new MyThread();
	}

	@Test(timeout = THREAD_MAX_RUNTIME)
	public void testRun() throws Exception {
		Thread t1 = new Thread(myThread1);
		Thread t2 = new Thread(myThread2);
		t1.start();
		t2.start();
		Thread tc = Thread.currentThread();
		synchronized (tc) {
			while (t1.isAlive() || t2.isAlive()) {
				tc.wait(THREAD_WAITTIME);
			}
			tc.notify();
		}
		Assert.assertEquals(100, myThread1.getI());
		Assert.assertEquals(100, myThread2.getI());
	}
}



0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics