使用ConTest进行多线程单元测试

并行程序易于产生 bug 不是什么秘密。编写这种程序是一种挑战,并且在编程过程中悄悄产生的 bug 不容易被发现。许多并行 bug 只有在系统测试、功能 测试时才能被发现或由用户发现。到那时修复它们需要高昂的费用 -- 假设能够 修复它们 -- 因为它们是如此难于调试。

在本文中,我们介绍了 ConTest,一种用于测试、调试和测量并行程序范围 的工具。正如您将很快看到的,ConTest 不是单元测试的取代者,但它是处理并 行程序的单元测试故障的一种补充技术。

为什么单元测试还不够

当问任何 Java 开发者时,他们都会告诉您单元测试是一种好的实践。 在单元测试上做适当的投入,随后将得到回报。通过单元测试,能较早地发现 bug 并且能比不进行单元测试更容易地修复它们。但是普通的单元测试方法(即 使当彻底地进行了测试时)在查找并行 bug 方面不是很有效。这就是为什么它 们能逃到程序的晚期 。

为什么单元测试经常遗漏并行 bug?通常的说法是并行程序(和 bug)的问 题在于它们的不确定性。但是对于单元测试目的而言,荒谬性在于并行程序是非 常 确定的。下面的两个示例解释了这一点。

无修饰的 NamePrinter

第一个例子是一个类,该类除了打印由两部分构成的名字之 外,什么也不做。出于教学目的,我们把此任务分在三个线程中:一个线程打印 人名,一个线程打印空格,一个线程打印姓和一个新行。一个包括对锁进行同步 和调用 wait() 和 notifyAll() 的成熟的同步协议能保证所有事情以正确的顺 序发生。正如您在清单 1 中看到的,main() 充当单元测试,用名字 "Washington Irving" 调用此类:

清单 1. NamePrinter

public class NamePrinter {
   private final String firstName;
   private final String surName;
   private final Object lock = new Object();
   private boolean printedFirstName = false;
   private boolean spaceRequested = false;
   public NamePrinter(String firstName, String surName) {
    this.firstName = firstName;
    this.surName = surName;
   }
   public void print() {
    new FirstNamePrinter().start();
    new SpacePrinter().start();
    new SurnamePrinter().start();
   }
   private class FirstNamePrinter extends Thread {
    public void run() {
      try {
       synchronized (lock) {
         while (firstName == null) {
          lock.wait();
         }
         System.out.print(firstName);
         printedFirstName = true;
         spaceRequested = true;
         lock.notifyAll();
       }
      } catch (InterruptedException e) {
       assert (false);
      }
    }
   }
   private class SpacePrinter extends Thread {
    public void run() {
      try {
       synchronized (lock) {
         while ( ! spaceRequested) {
          lock.wait();
         }
         System.out.print(' ');
         spaceRequested = false;
         lock.notifyAll();
       }
      } catch (InterruptedException e) {
       assert (false);
      }
    }
   }
   private class SurnamePrinter extends Thread {
    public void run() {
      try {
       synchronized(lock) {
         while ( ! printedFirstName || spaceRequested ||  surName == null) {
          lock.wait();
         }
         System.out.println(surName);
       }
      } catch (InterruptedException e) {
       assert (false);
      }
    }
   }
   public static void main(String[] args) {
    System.out.println();
    new NamePrinter("Washington", "Irving").print();
   }
}

时间: 2024-09-15 07:54:28

使用ConTest进行多线程单元测试的相关文章

轻松构建和运行多线程的单元测试

简介:随着多核处理器成为主流,开发并行程序随之成为一种必然要求.但是我们都知道并行程序存 在着很大的不确定性,这使得开发和测试并行程序有一定的难度,因此对于并行程序的单元测试变得尤为 重要.但是,创建多线程的单元测试并不容易,测试需要考虑测试线程间的同步,数据共享等.针对 Java 并行程序的测试,结合扩展 JUnit 的多线程测试工具,本文介绍了一种在集成开发环境中,创建符 合用户要求的多线程单元测试用例的完整过程,使得用户只用关心测试本身的逻辑和结果,而不用去了解 测试用例并行执行的琐碎细节

java多线程编程测试笔记

首先,需要明确的是,用Java通常构建多线程安全的程序"非常"困难,如果还没有体会到"非常"的话,阅读<Java Concurrency in Practice>(中文名叫做<Java并发编程实战>,在我的书单里面,我认为它基本是最好的系统介绍Java并发的书了)可能可以改变你的看法. 多线程的基础 基础是王道.对于任何一门语言都是如此,有的基础部分是和语言无关的,也有一部分是和Java语言相关的.这里我不过多展开,但是我想提一提对于JSR规

银行取款[多线程]{未进行线程同步}(junit不适合多线程并发单元测试)

        由于计算机多任务.多进程.多线程的支持,使得计算机资源的服务效率提高,服务器对请求的也使用线程来相应,所有,代码中涉及到同时对共享数据的操作,将在 多线程环境中操作数据,导致数据安全问题.      经典例子:老婆(朱丽叶)老公(罗密欧),使用银行卡和存折,或者网银等,同时对同一账户操作的安全问题.      如果要保证多线程下数据安全,就要实现线程同步(例如:一间小厕所,就得有一个锁,保证同一时间为一个人服务).其他文章讲: 此处用多线程实现,同时取款的模拟实现,未进行线程同步

多线程环境下单元测试的问题

问题描述 多线程环境下单元测试的问题 某个函数worker是在多线程环境下运行的,如果要对其进行"单元测试",是不是也要在相应的多线程环境下测试?还是在单线程环境下测试? 解决方案 多线程肯定要在多线程环境下测试,这样才能正确的模拟它的行为 解决方案二: 既然是多线程的,你就要在多线程的一个环境下对它进行测试才是真实的结果. 解决方案三: 首先,你还是需要在单线程下测试,单线程的单元测试对于多线程工况下的代码同样有意义. 其次,你应该做多线程测试,这个可以借助mock一类的框架构造仿真

c++网络程序怎么做单元测试,涉及到多线程

问题描述 c++网络程序怎么做单元测试,涉及到多线程 急!谢谢!c++网络程序怎么做单元测试,涉及到多线程,而且测试的类内部还调用了其他类来创建线程. 解决方案 就是测试对应的函数好了,比如程序发送数据API,UT测试这个,看是否数据发送过去 解决方案二: 既然都说明了是单元测试,那么就按单元测试的方法来进行. 单元测试是开发者编写的一小段代码,用于检验被测代码的一个很小的.很明确的功能是否正确.通常而言,一个单元测试是用于判断某个特定条件(或者场景)下某个特定函数的行为.例如,你可能把一个很大

使用Contest分析测试用例的代码覆盖率

解决什么问题 问题的提出时这样的:对于测试人员来说,首先面临的问题就是无法度量测试用例的质量,如果测 试工程师花费大量时间写的测试用例不能有效地覆盖重要的实现代码,那么可以表明这样的测试用例不是优良的.同时可以 根据测试覆盖了的报表来分析为什么没有覆盖到重要的代码,接着需要进行改进测试用例的代码覆盖率达到满意的结果.代 码覆盖率高低根据产品的不同而不同:70%,80% 甚至 100% 都是可能的.对于测试工程师来讲,可以遵循这样的流程 : 获 取覆盖率 – > 发现未覆盖的代码 – > 添加新

Java ME下的单元测试开发之JMUnit篇

摘要 不能因为Java Micro Edition缺乏反射能力就说Java Micro Edition开发者无法利用JUnit风格测试的优点.其实,借助于具有JUnit风格的其它一些框架和工具,Java ME开发人员仍然能够改进Java ME应用程序的开发质量.本系列文章(两篇)正是想详细探讨J2MEUnit和JMUnit这两个开源框架在Java ME单元测试开发中的应用. 一.引言 如今,JUnit测试正在逐渐成为大多数Java标准版(SE)和企业版(EE)应用程序开发中的基本组成部分-对于那

单元性能测试之使用JUnitPerf测试多线程并发

简介: 单元测试和性能测试在测试领域属于要求相对较高的测试活动,也是测试工程师成长.向上发展的反向.单元测试评测我们的代码实现功能的情况,性能测试则企图分析应用程序的性能表现和负载能力.那么"单元性能测试"能做什么?我们可以这样说,单元性能测试以单元测试的形式对代码进行性能测试.单元性能测试像单元测试一样,需要测试人员编写测试代码,但现在关注的不是代码的功能实现情况了,而是想得到被测试代码的性能数据,包括执行方法耗时.多线程并发是否线程安全.内存是否泄漏.是否存在短期循环对象等.单元性

银行取款[多线程]{使用重入锁Lock接口ReentrantLock锁确保线程同步}

经典例子:老婆(朱丽叶)老公(罗密欧),使用银行卡和存折,或者网银等,同时对同一账户操作的安全问题.  此处用多线程实现,同时取款的模拟实现,使用使用Lock接口ReentrantLock锁确保线程同步,查看取款安全隐患问题,代码如下: -----------------------------------------------------------------------------------------------------------------------------------