Junit单元测试不支持多线程测试--原因分析和问题解决

简介: Junit单元测试不支持多线程测试--原因分析和问题解决

问题现象


  1. import org.junit.Test;
  2. /**
  3. * @Title:  junit多线程测试
  4. * @ClassName: JunitMultiThreadTest.java
  5. * @Description:
  6. *
  7. * @Copyright2016-2018  - PoweredBy 研发中心
  8. * @author:
  9. * @date:  2018-01-3019:31
  10. * @version V1.0
  11. */
  12. public classJunitMultiThreadTest {
  13.    private int i = 5;
  14.    @Test
  15.    public voidtest() {
  16.        for (int i = 0; i < this.i; i ++) {
  17.            newThread(newRunner(),"JUNIT多线程测试").start();
  18.        }
  19.    }
  20.    classRunner implements Runnable {
  21.        @Override
  22.        public voidrun() {
  23.            System.out.println("【当前线程ID】:"+Thread.currentThread().getId());
  24.        }
  25.    }
  26. }


输出结果


  1. 【当前线程ID】:13
  • 多次运行,要么没有任何输出结果,要么输出补全


原因分析


  • TestRunner源码:
  1. publicstaticfinalintSUCCESS_EXIT=0;
  2.    publicstaticfinalintFAILURE_EXIT=1;
  3.    publicstaticfinalintEXCEPTION_EXIT=2;
  4.    publicstaticvoidmain(String args[]) {
  5.        TestRunner aTestRunner= newTestRunner();
  6.        try {
  7.            TestResult r= aTestRunner.start(args);
  8.            if (!r.wasSuccessful())
  9.                System.exit(FAILURE_EXIT);
  10.            System.exit(SUCCESS_EXIT);
  11.        } catch(Exception e) {
  12.            System.

TestResult类

  1.  /**
  2.     * Returns whether the entire test was successful or not.
  3.     */
  4.    publicsynchronizedbooleanwasSuccessful() {
  5.        return failureCount() == 0 && errorCount() == 0;
  6.    }


  1. 在这里我们明显可以看到:
  2. 当aTestRunner调用start方法后不会去等待子线程执行完毕在关闭主线程,而是直接调用TestResult.wasSuccessful()方法,
  3. 当这个方法返回的是false,主线程接下来就会执行System.exit,
  4. 这个放回会结束当前运行的jvm虚拟机,所以使用junit测试多线程方法的结果异常就正常了;


问题解决

  1. 想要正常输出的话可以让主线程不要结束,等待子线程全部运行结束后在结束主线程,输出结果就会正常


解决方式1

  1. Thread.sleep();
  2. import org.junit.Test;
  3. /**
  4. * @Title:  junit多线程测试
  5. * @ClassName: JunitMultiThreadTest.java
  6. * @Description:
  7. *
  8. * @Copyright2016-2018  - PoweredBy 研发中心
  9. * @author:
  10. * @date:  2018-01-3019:31
  11. * @version V1.0
  12. */
  13. public classJunitMultiThreadTest {
  14.    private int i = 5;
  15.    @Test
  16.    public voidtest() throws InterruptedException {
  17.        for (int i = 0; i < this.i; i ++) {
  18.            newThread(newRunner(),"JUNIT多线程测试").start();
  19.        }
  20.        Thread.sleep(100000);
  21.    }
  22.    classRunner implements Runnable {
  23.        @Override
  24.        public voidrun() {
  25.            System.out.println("【当前线程ID】:"+Thread.currentThread().getId());
  26.        }
  27.    }
  28. }
  29. 【当前线程ID】:11
  30. 【当前线程ID】:15
  31. 【当前线程ID】:12
  32. 【当前线程ID】:14
  33. 【当前线程ID】:13


解决方式2


  1. 线程计数器  CountDownLatch
  2. import org.junit.Test;
  3. import java.util.concurrent.CountDownLatch;
  4. /**
  5. * @Title:  junit多线程测试
  6. * @ClassName: JunitMultiThreadTest.java
  7. * @Description:
  8. *
  9. * @Copyright2016-2018  - PoweredBy 研发中心
  10. * @author:
  11. * @date:  2018-01-3019:31
  12. * @version V1.0
  13. */
  14. public classJunitMultiThreadTest {
  15.    private int i = 5;
  16.    /*
  17. * 线程计数器
  18. * 将线程数量初始化
  19. * 每执行完成一条线程,调用countDown()使计数器减1
  20. * 主线程调用方法await()使其等待,当计数器为0时才被执行
  21. */
  22.    private CountDownLatch latch = newCountDownLatch(i);
  23.    @Test
  24.    public voidtest() throws InterruptedException {
  25.        for (int i = 0; i < this.i; i ++) {
  26.            newThread(newRunner(),"JUNIT多线程测试").start();
  27.        }
  28.        try {
  29.            latch.await(); // 主线程等待
  30.        } catch (InterruptedException e) {
  31.            e.printStackTrace();
  32.        }
  33.    }
  34.    classRunner implements Runnable {
  35.        @Override
  36.        public voidrun() {
  37.            System.out.println("【当前线程ID】:"+Thread.currentThread().getId());
  38.            latch.countDown(); // 执行完毕,计数器减1
  39.        }
  40.    }
  41. }
  42. 【当前线程ID】:12
  43. 【当前线程ID】:13
  44. 【当前线程ID】:11
  45. 【当前线程ID】:15
  46. 【当前线程ID】:14


参考来源:http://blog.csdn.net/weixin_32820639/article/details/71713037


目录
相关文章
|
6天前
|
Java 测试技术 Android开发
课时148:junit测试工具
课时148介绍了JUnit测试工具的使用,包括定义、配置和编写测试程序。JUnit是流行的用例测试工具,用于确保代码稳定性。
|
4月前
|
测试技术 开发者 UED
探索软件测试的深度:从单元测试到自动化测试
【10月更文挑战第30天】在软件开发的世界中,测试是确保产品质量和用户满意度的关键步骤。本文将深入探讨软件测试的不同层次,从基本的单元测试到复杂的自动化测试,揭示它们如何共同构建一个坚实的质量保证体系。我们将通过实际代码示例,展示如何在开发过程中实施有效的测试策略,以确保软件的稳定性和可靠性。无论你是新手还是经验丰富的开发者,这篇文章都将为你提供宝贵的见解和实用技巧。
|
5月前
|
Java 程序员 测试技术
Java|让 JUnit4 测试类自动注入 logger 和被测 Service
本文介绍如何通过自定义 IDEA 的 JUnit4 Test Class 模板,实现生成测试类时自动注入 logger 和被测 Service。
90 5
|
6月前
|
SQL JavaScript 前端开发
基于Java访问Hive的JUnit5测试代码实现
根据《用Java、Python来开发Hive应用》一文,建立了使用Java、来开发Hive应用的方法,产生的代码如下
116 6
|
6月前
|
IDE 测试技术 持续交付
Python自动化测试与单元测试框架:提升代码质量与效率
【9月更文挑战第3天】随着软件行业的迅速发展,代码质量和开发效率变得至关重要。本文探讨了Python在自动化及单元测试中的应用,介绍了Selenium、Appium、pytest等自动化测试框架,以及Python标准库中的unittest单元测试框架。通过详细阐述各框架的特点与使用方法,本文旨在帮助开发者掌握编写高效测试用例的技巧,提升代码质量与开发效率。同时,文章还提出了制定测试计划、持续集成与测试等实践建议,助力项目成功。
130 5
|
7月前
|
测试技术 C# 开发者
“代码守护者:详解WPF开发中的单元测试策略与实践——从选择测试框架到编写模拟对象,全方位保障你的应用程序质量”
【8月更文挑战第31天】单元测试是确保软件质量的关键实践,尤其在复杂的WPF应用中更为重要。通过为每个小模块编写独立测试用例,可以验证代码的功能正确性并在早期发现错误。本文将介绍如何在WPF项目中引入单元测试,并通过具体示例演示其实施过程。首先选择合适的测试框架如NUnit或xUnit.net,并利用Moq模拟框架隔离外部依赖。接着,通过一个简单的WPF应用程序示例,展示如何模拟`IUserRepository`接口并验证`MainViewModel`加载用户数据的正确性。这有助于确保代码质量和未来的重构与扩展。
195 0
|
7月前
|
测试技术 Java Spring
Spring 框架中的测试之道:揭秘单元测试与集成测试的双重保障,你的应用真的安全了吗?
【8月更文挑战第31天】本文以问答形式深入探讨了Spring框架中的测试策略,包括单元测试与集成测试的有效编写方法,及其对提升代码质量和可靠性的重要性。通过具体示例,展示了如何使用`@MockBean`、`@SpringBootTest`等注解来进行服务和控制器的测试,同时介绍了Spring Boot提供的测试工具,如`@DataJpaTest`,以简化数据库测试流程。合理运用这些测试策略和工具,将助力开发者构建更为稳健的软件系统。
94 0
|
7月前
|
测试技术 Java
全面保障Struts 2应用质量:掌握单元测试与集成测试的关键策略
【8月更文挑战第31天】Struts 2 的测试策略结合了单元测试与集成测试。单元测试聚焦于单个组件(如 Action 类)的功能验证,常用 Mockito 模拟依赖项;集成测试则关注组件间的交互,利用 Cactus 等框架确保框架拦截器和 Action 映射等按预期工作。通过确保高测试覆盖率并定期更新测试用例,可以提升应用的整体稳定性和质量。
107 0
|
7月前
|
测试技术 数据库
探索JSF单元测试秘籍!如何让您的应用更稳固、更高效?揭秘成功背后的测试之道!
【8月更文挑战第31天】在 JavaServer Faces(JSF)应用开发中,确保代码质量和可维护性至关重要。本文详细介绍了如何通过单元测试实现这一目标。首先,阐述了单元测试的重要性及其对应用稳定性的影响;其次,提出了提高 JSF 应用可测试性的设计建议,如避免直接访问外部资源和使用依赖注入;最后,通过一个具体的 `UserBean` 示例,展示了如何利用 JUnit 和 Mockito 框架编写有效的单元测试。通过这些方法,不仅能够确保代码质量,还能提高开发效率和降低维护成本。
79 0
|
7月前
|
Java 测试技术 API
SpringBoot单元测试快速写法问题之复杂的业务逻辑设计有效的单元测试如何解决
SpringBoot单元测试快速写法问题之复杂的业务逻辑设计有效的单元测试如何解决

热门文章

最新文章