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


目录
相关文章
|
16天前
|
Java 测试技术
SpringBoot整合单元测试&&关于SpringBoot单元测试找不到Mapper和Service报java.lang.NullPointerException的错误
SpringBoot整合单元测试&&关于SpringBoot单元测试找不到Mapper和Service报java.lang.NullPointerException的错误
19 0
|
1月前
|
jenkins 测试技术 持续交付
提升软件测试效率与准确性的策略分析
【2月更文挑战第28天】 在快速迭代的软件发展周期中,高效的测试流程是确保产品质量和用户满意度的关键。本文旨在探讨提高软件测试效率和准确性的策略,包括自动化测试工具的选择、测试用例的优化设计以及持续集成的实践。通过分析当前软件测试领域面临的挑战,提出了相应的解决方案,并通过案例分析来展示这些策略的实际应用效果。文章的目的是为软件测试工程师提供实用的指导和参考,帮助他们在保证测试质量的同时,缩短测试周期,降低成本。
42 1
|
15天前
|
Java 测试技术 程序员
junit单元测试
junit单元测试
|
1天前
|
测试技术 数据安全/隐私保护
深入理解与应用软件测试中的边界值分析法
【4月更文挑战第23天】在软件测试的诸多技术中,边界值分析法因其简洁性和高效性而备受青睐。本文旨在探讨边界值分析法的核心原理及其在实际测试场景中的应用。通过对边界条件进行系统的识别、分类和测试,该方法能够有效地发现软件缺陷。我们将详细讨论如何确定边界值,设计测试用例,以及如何处理复杂数据类型的边界情况。此外,文章还将展示通过案例研究来验证边界值分析法在提升测试覆盖率和发现潜在错误方面的实际效益。
|
Java 测试技术
Java 中的单元测试和集成测试策略
【4月更文挑战第19天】本文探讨了Java开发中的单元测试和集成测试。单元测试专注于单一类或方法的功能验证,使用测试框架如JUnit,强调独立性、高覆盖率和及时更新测试用例。集成测试则验证模块间交互,通过逐步集成或模拟对象来检测系统整体功能。两者相辅相成,确保软件质量和降低修复成本。
|
7天前
R语言估计多元标记的潜过程混合效应模型(lcmm)分析心理测试的认知过程
R语言估计多元标记的潜过程混合效应模型(lcmm)分析心理测试的认知过程
26 0
|
12天前
|
缓存 自动驾驶 测试技术
如何进行有效的Apollo测试:单元测试和集成测试指南
如何进行有效的Apollo测试:单元测试和集成测试指南
40 13
|
12天前
|
Web App开发 前端开发 Java
框架分析(11)-测试框架
框架分析(11)-测试框架
|
23天前
|
机器学习/深度学习 人工智能 算法
提升软件测试效率与质量的策略分析
在快速发展的信息技术时代,软件产品已成为日常生活和工作的核心组成部分。随着软件系统的复杂度日益增加,确保其功能性、稳定性及安全性的软件测试工作变得尤为重要。本文针对如何提升软件测试的效率与质量进行了深入探讨,分析了当前软件测试面临的挑战,并提出了一系列创新策略。这些策略包括采用自动化测试工具、实施持续集成和持续部署(CI/CD)、利用人工智能进行测试用例生成以及强化测试团队的技能培训等。通过综合运用这些策略,可以显著提高软件测试的质量和效率,减少人工成本,同时加速产品的上市时间。
|
1月前
|
测试技术 持续交付 UED
提升软件测试效率与准确性的策略分析
【2月更文挑战第29天】 随着软件开发周期的缩短和市场对质量要求的提高,传统的软件测试方法面临诸多挑战。本文针对如何提升软件测试的效率与准确性进行深入探讨,分析了自动化测试、持续集成、测试驱动开发(TDD)等现代测试策略的优势与实施要点。通过案例分析和数据对比,论证了这些策略在确保软件产品质量和加快上市速度方面的积极作用。