当前位置: 首页 > 面试题库 >

如何使用线程执行单元测试?

柯永福
2023-03-14
问题内容

摘要:
当在线程中引发断言错误时,单元测试不会消失。这是有道理的,因为不应允许一个线程使另一线程崩溃。问题是我该如何1)当第一个帮助程序线程崩溃时使整个测试失败,或者2)遍历并确定每个线程完成后的状态(请参见下面的代码)。后者的一种方法是通过每个线程具有状态变量,例如“
boolean [] statuss”,并具有“ statuses [i] ==
false”表示线程失败(可以扩展以捕获更多信息)。但是,这不是我想要的:抛出断言错误时,我希望它像其他任何单元测试一样失败。这有可能吗?是可取的吗?

我很无聊,所以我决定在单元测试中生成一堆线程,然后让它们调用服务方法,只是为了达到目的。该代码大致类似于:

Thread[] threads = new Thread[MAX_THREADS];
for( int i = 0; i < threads.length; i++ ) {
    threads[i] = new Thread( new Runnable() {
        private final int ID = threadIdSequenceNumber++;
        public void run() {
            try {
                resultRefs[ID] = runTest( Integer.toString( ID ) ); // returns an object
            }
            catch( Throwable t ) { 
                // this code is EVIL - it catches even
                // Errors - don't copy it - more on this below
                final String message = "error testing thread with id => "
                            + ID;
                logger.debug( message, t );
                throw new IllegalStateException( message, t ); 
                // need to wrap throwable in a 
                // run time exception so it will compile
            }
        }
    } );
}

此后,我们将遍历线程数组并开始每个线程。之后,我们将等待它们全部完成。最后,我们将对结果引用进行一些检查。

for( Thread thread : threads )
    thread.start();

logger.debug( "waiting for threads to finish ..." );
boolean done = false;
while( !done ) {
    done = true;
    for( Thread thread : threads )
        if( thread.isAlive() )
            done = false;
}

for( int i = 0; i < resultRefs.length; i++ ) {
    assertTrue( "you've got the world messed, dawg!",
            myCondition(resultRefs[i]) );

这是问题所在。您是否注意到该讨厌的try-catch-
throwable块?我只是将其添加为一个临时hack,所以我可以看到发生了什么。在runTest(String)中进行了一些声明,例如assertNotNull(null),但是由于它位于不同的线程中,因此不会导致单元测试失败!!!

我的猜测是,如果线程以讨厌的方式终止,我们将需要以某种方式遍历线程数组,检查每个线程的状态,并手动导致断言错误。提供此信息的方法的名称是什么(死线程的堆栈跟踪)。


问题答案:

并发是很难进行单元测试的事情之一。如果您只是想测试每个线程中的代码是否正在执行应该测试的内容,也许您应该只测试与上下文隔离的代码。如果在此示例中,线程进行协作以达到结果,则可以在不使用线程的情况下测试该协作。这可以通过顺序执行所有协作部分来完成。如果您要测试比赛条件和此类情况,则单元测试不是最佳方法。您将获得有时会失败有时又不会失败的测试。总而言之,我认为您的问题可能是您的单元测试水平过高。希望这可以帮助



 类似资料:
  • 我正在学习使用TestNG进行单元测试。我想将变量“val”的唯一值传递给线程池中的每个线程,但它没有接收它。 这里是testng类: 和输出: [ThreadUtil]启动执行器超时:1000msworkers:5ThreadPoolSize:5BeForeMethod。线程id为:15 BeforeMethod。线程id为:12 BeforeMethod。线程id为:14 BeforeMeth

  • 在使用maven运行单元测试时,我遇到了这个异常。我的所有测试都没有执行。我的测试类的格式是 我正在运行以下命令来运行此命令: 使用的surefire插件是: 有人知道为什么我的测试没有执行吗?我用的是jUnit 4.8.2和surefire 2.14.1

  • 问题内容: 我有一个直接依赖RestTemplate的类。我希望我可以离线进行JUnit测试。 如何在单元测试中模拟RestTemplate? 问题答案: 我建议重构您的客户端代码,以 消除 对的直接依赖,并用对的引用替换它,该引用是由实现的。和您应该编码的那个。 然后,您可以在代码中插入存根或模拟对象以进行单元测试,并在将其用于实际时注入。

  • 我有以下测试: 这是好的,它可以运行,但是我想知道有没有一种方法可以将它作为单元测试而不是集成测试运行,并且仍然使用@mockbean@autowired。还是我错过了什么? 我试着只保留@ExtendWith(SpringExtension.class),但我得到一个关于找不到BookServiceImpl bean的异常。 我知道如何使用MockitoExtension和@mock、@inje

  • 问题内容: 到目前为止,我似乎避免了测试多线程代码的噩梦,因为它似乎太多了。我想问一下人们如何去测试依赖于线程的代码才能成功执行,或者人们如何去测试那些仅在两个线程以给定方式交互时才会出现的问题? 对于当今的程序员来说,这似乎是一个非常关键的问题,将我们的知识集中在这一恕我直言上将很有用。 问题答案: 看,没有简单的方法可以做到这一点。我正在开发一个本质上是多线程的项目。事件来自操作系统,我必须同

  • 6.7.1.单线程执行 Android程序默认运行在单线程之下。单线程顺序执行所有的操作,这一操作完成之前,下一个操作绝不会执行。这一行为被称作“阻塞”(blocking)。 图6.8. 单线程执行 这个线程也被称作UI线程,意思是程序中用户界面的相关操作都在这里执行。除处理所有UI元素的渲染之外,事件的响应也由它负责。比如触摸屏幕、点击按钮等等。图6.8 "单线程执行"展示了在只有一个UI线程时