锁定老帖子 主题:关于JUNIT的多线程测试问题
精华帖 (0) :: 良好帖 (0) :: 新手帖 (5) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2008-01-16
skydream 写道 具体分析吧,如果这个private 方法有被其他public方法直接调用,而且逻辑清晰,则直接测试这个public方法。
如果这个private方法隐藏的很深,而且逻辑复杂,其他public方法离这个private的"距离"非常远。那就要考虑一下这个类的设计了,不容易测试的类,往往是功能过多,代码太大的类,建议拆分。 比如一个业务处理类,在复杂的业务逻辑处理过程中通过调用一个private方法做加密,而这个加密算法需要测试。类似这种情况,最好的办法就是将加密算法单独提取出一个类,功能非常单一的类,不要献小。然后对它进行junit测试,原来的类只要直接调用这个类就可以了。 这个也就是junit带来的一个推动力,为了达到测试友好,就必须保证代码清晰,相互耦合小。 说的很有道理啊,测试驱动。。。。 |
|
返回顶楼 | |
发表时间:2008-01-18
red008说的用thread.join应该可以
或者在tes方法最后system.read.in() --当然这就不是自动化测试了. |
|
返回顶楼 | |
发表时间:2008-01-26
skydream 写道 具体分析吧,如果这个private 方法有被其他public方法直接调用,而且逻辑清晰,则直接测试这个public方法。
如果这个private方法隐藏的很深,而且逻辑复杂,其他public方法离这个private的"距离"非常远。那就要考虑一下这个类的设计了,不容易测试的类,往往是功能过多,代码太大的类,建议拆分。 比如一个业务处理类,在复杂的业务逻辑处理过程中通过调用一个private方法做加密,而这个加密算法需要测试。类似这种情况,最好的办法就是将加密算法单独提取出一个类,功能非常单一的类,不要献小。然后对它进行junit测试,原来的类只要直接调用这个类就可以了。 这个也就是junit带来的一个推动力,为了达到测试友好,就必须保证代码清晰,相互耦合小。 有道理,如果实在不想写,可以考虑用反射方式来调用该方法。 |
|
返回顶楼 | |
发表时间:2008-01-27
似乎多线程测试主要问题还不是怎么在junit下跑起来,
而是如何设计测试能够暴露出并发问题。。。 |
|
返回顶楼 | |
发表时间:2008-01-27
Godlikeme 写道 似乎多线程测试主要问题还不是怎么在junit下跑起来,
而是如何设计测试能够暴露出并发问题。。。 如何设计测试能够暴露出并发问题,呵呵,这个,基本上,很难 并发问题要想展现出来,除非程序写的实在是漏洞太大,否则基本上不要指望一般的单元测试案例能测试出问题了。 而且我个人意见,不建议用一般的测试去验证并发的正确性,很容易使得某些人走入另一个极端,即简单的跑一下单元测试,就下结论说这里的并发没有问题,后果是灾难性的 我就遇到过类似的场景:某人的多线程访问的代码不做同步,然后起两个线程测试,没有发现问题,ok,下结论测试通过...... |
|
返回顶楼 | |
发表时间:2008-01-27
没错,除非问题是显而易见的。
|
|
返回顶楼 | |
发表时间: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()); } } |
|
返回顶楼 | |