- 浏览: 3500629 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
wanglf1207:
EJB的确是个不错的产品,只是因为用起来有点门槛,招来太多人吐 ...
weblogic-ejb-jar.xml的元素解析 -
qwfys200:
总结的不错。
Spring Web Flow 2.0 入门 -
u011577913:
u011577913 写道也能给我发一份翻译文档? 邮件437 ...
Hazelcast 参考文档-4 -
u011577913:
也能给我发一份翻译文档?
Hazelcast 参考文档-4 -
songzj001:
DbUnit入门实战
p-unit 是一款开放源码的性能测试框架,和 JUnit 不同,JUnit 关注的是测试案例的正确性,而 p-unit 不仅关注测试案例的正确性,还收集测试案例的性能参数,默认情况下,p-unit 收集测试案例的时间和内存消耗情况,可以产生文件,图片,和 PDF 格式的报表。此外,p-unit 还支持参数化测试,多线程测试以及不同 Java 虚拟机性能之间的比较。
或许我们已经习惯了使用 JUnit 来写单元测试来保证代码质量(我也一直这么做),但可能经常碰到这样的问题:
- 程序多线程下正确性如何?
- 如何测试程序的性能?
- 当有多个方案可以选择时,技术上如何比较不同方案的性能?
对 于问题 1,我们或许听天由命?或是凭借人工分析,或是根据用户反馈?很多软件单线程下的单元测试覆盖率相当高,从而保证了代码的健壮性。然而多线程测试时常被忽 略,这并不代表多线程测试不重要,相反,修正一个用户报告的多线程 BUG 往往比单线程的要高出很多,因为测试案例经常不是 100% 可重现的。这更要求程序员在开发阶段充分的重视。目前多线程单元测试力度不够的一个重要原因是没有一个像 JUnit 那样易用的测试工具,另外重复写测试案例往往不被程序员接受。
对于问题 2,一个成熟的关心性能的产品往往有一个性能测试平台。这个测试平台应该关注的是测试业务逻辑本身,而无需关心如何运行测试案例。你是否为写这样的测试平台痛苦过?以及花费时间在产生一些直观的报表上面?
对于问题 3,我们往往写一个原型来比较不同产品之间的性能,如何比较执行速度和内存消耗?或是选择最适合你的虚拟机?
p-unit 就是这么一款开源的性能测试软件,它能帮助你很好的解决上述问题。p-unit 可以:
- 多线程支持:同一个测试案例可以单线程执行,也可以多线程执行,测试案例开发者只需写一套测试案例。
- 参数化测试案例:很多测试案例,需要测试同一功能在不同数量级上的性能表现。
- 不同虚拟机性能测试:只需指定虚拟机路径,即可测试同一个测试案例在不同虚拟机上的表现,报表上可以非常直观显示性能差别。
- 事件机制构架:punit 是基于事件机制构架的,如果用户想定制报表,只需实现事件响应器,并注册该响应器到 punit 核心即可。
在 了解如何多线程执行测试案例之前,我们先了解一下如何利用 p-unit 单线程执行测试案例。不同于 JUnit, p-unit 测试用例无需继承任何测试类或是实现接口,即可执行 test 开始的方法。尽管 JUnit 4 中加入了注释(Annotation) 的特性,但测试方法前缀为 "test" 仍然是测试者们的首选。因此如果你的 JUnit 测试案例遵循的是 test 命名规则,那么 p-uni t可以兼容运行 JUnit 测试案例。
下面的代码清单 1 是一个最为普通的测试案例:
public class SimpleTestClass { public void setUp() { SampleUtil.doSomething(); } public void tearDown() { SampleUtil.doSomething(); } public void testA() { System.out.println("testA"); SampleUtil.doSomething(); } public void testB() { SampleUtil.doSomething(); } public void testC() { SampleUtil.doSomething(); } } public class SampleUtil { private static Random _random = new Random(); public static void consumeMemory(int length) { byte[] data = new byte[length]; for(int i = 0, j = 0; i < data.length; ++i) { ++j; } } public static void consumeTime(int time) { ThreadUtil.sleepIgnoreInterruption(time); } public static void doSomething() { consumeTime(Math.abs(_random.nextInt()) % 500); consumeMemory(Math.abs(_random.nextInt()) % 100000); } } |
这是做为普通的测试案例,但是注意到
这仅仅是一个测试案例,不包含其他任何逻辑,这也是 p-unit
追求的业务逻辑和测试运行环境分离的一个理念。同一个测试案例,用户可以选择不同的测试环境去运行,而不是绑定在某一个特定的测试软件工具上。现在我们来
看 p-unit 是如何运行这个测试案例的。你只需要在 main
函数中写一行代码来运行它:
public static void main(String[] args) { new PUnitSoloRunner().run(SimpleTestClass.class); } |
[solo] Started running samples.SimpleTestClass samples.SimpleTestClass testA testA() - [287.0ms] testB() - [27.0ms] testC() - [213.0ms] total: 3, failures:0 (GREEN) - 2025.0ms |
是否和想象中的一样?下面我们来看如何多线程执行这个测试案例。或许从上面的例子你已经猜到了,在 main
函数还是只需一句代码,只用把 PUnitSoloRunner
换成 PUnitConcurrentRunner
即可!
public static void main(String[] args) { new PUnitConcurrentRunner().run(SimpleTestClass.class); } |
[concurrent] Started running samples.SimpleTestClass samples.SimpleTestClass testA testA testA testA testA testA testA testA testA testA testA() - [405.0ms] testB() - [469.0ms] testC() - [503.0ms] total: 3, failures:0 (GREEN) - 1447.0ms |
是否和想象中的一样?默认情况 p-unit 启动 10 个线程来执行,要指定不同的线程数,只需将线程数做为参数传入 PUnitConcurrentRunner
即可。p-unit 甚至支持不同的测试案例有不同的线程数,这要求测试案例实现 p-unit 中定义的 Concurrent
接口,该接口的定义为:
public interface Concurrent { public int concurrentCount(); } |
该接口的意思,相信无需再多做解释了,返回该测试案例需要的线程数。
性能测试,不同于单元测试,经常要求测试不同数量级在同一个测试场景中的表现,JUnit 是一款非常优秀的单元测试工具,但没覆盖到这个方面。比如我们比较类库 Foo1
的方法 bar()
和类库 Foo2
的方法 bar()
哪个更符合自己的应用程序,我们需要测试该函数在应用程序可能的数量级的范围内的表现。有经验的开发者知道经常碰到在小数量级 A 更好大数量级 B
更好的局面,因此全面的测试对于代码的性能理解非常重要,能帮助开发者做出正确的决定。p-unit 支持将参数传给测试方法,测试案例需要实现
p-unit 的 parameterizable
接口,该接口的主要方法是返回一组参数列表,这组列表的参数将会一一传给测试方法。
public class ParamTestClass implements Parameterizable { public static void main(String[] args) { new PUnitSoloRunner().run(ParamTestClass.class); } public Parameter[] parameters() { return new Parameter[] { new ParameterImpl(10), new ParameterImpl(20) }; } public void testA(ParameterImpl param) { SampleUtil.doSomething(); } public void testB(ParameterImpl param) { SampleUtil.doSomething(); } public void testC(ParameterImpl param) { SampleUtil.doSomething(); } public void setUpAfterWatchers(Parameter param) throws Exception { } public void setUpBeforeWatchers(Parameter param) throws Exception { } public void tearDownAfterWatchers(Parameter param) throws Exception { } public void tearDownBeforeWatchers(Parameter param) throws Exception { } static class ParameterImpl implements Parameter { private int _count; ParameterImpl(int count) { _count = count; } public int count() { return _count; } public String toString() { return String.valueOf(_count); } } } |
上述代码的执行结果为:
[solo] Started running samples.ParamTestClass samples.ParamTestClass testA(10) - [57936.0bytes,447.0ms] testA(20) - [33128.0bytes,61.0ms] testB(10) - [24832.0bytes,137.0ms] testB(20) - [0.0bytes,63.0ms] testC(10) - [83560.0bytes,468.0ms] testC(20) - [16528.0bytes,47.0ms] total: 6, failures:0 (GREEN) 1450.0ms |
从上述结果看出,每个方法被执行了 2 次,每次传入不同的参数。多线程运行参数化测试程序?相信读者已经明白怎么去实现了,只需将 PUnitSoloRunner 替换成 PUnitConcurrentRunner。
随
着 Java 开源,出现了更多的 Java 运行环境,除了 SUN 的参考实现外,BEA、IBM 均有自己的 Java 运行环境,更有如
Apache Harmony 的开源运行环境(尽管现在 Apache Harmony 尚不能称为 Java
运行环境)。运行环境测试案例,为运行环境开发者以及选择运行环境,都能提供一定的帮助。比如说下面的例子就是测试 java.util.ArrayList
和 java.util.Vector
在两个不同运行环境的表现。测试案例写法和普通的测试案例完全一样,我们只需告诉 p-unit 不同的运行环境的 Java 路径以及正确的 classpath,然后调用 runVMs
函数即可:
public static void main(String[] args) { PUnitSoloRunner runner = new PUnitSoloRunner(); runner.addPUnitEventListener(new OverviewReporter(new ImageRender())); runner.runVMs(ListTestClass.class, new VM[] { VMConfig.HARMONY, VMConfig.SUN }); } public class VMConfig { private static String CLASSPATH = " -cp correct_classpath_including_all_jars_and_path"; |-------10--------20--------30--------40--------50--------60--------70--------80--------9| |-------- XML error: The previous line is longer than the max of 90 characters ---------| private static String HARMONY_PATH = "harmony_path\\bin\\java" + CLASSPATH; private static String SUN_PATH = "sun_path\\bin\\java" + CLASSPATH; public static VM HARMONY = new VM(HARMONY_PATH, "HARMONY"); public static VM SUN = new VM(SUN_PATH, "SUN"); } public class ListTestClass { private static final int LIST_COUNT = 100000; private static Object element = new Object(); private Random indexGenerator = new Random();; public void testInsertArrayList() { ArrayList arrayList = new ArrayList(LIST_COUNT); insertSequence(arrayList); insertRandom(arrayList); } public void testInsertVector() { Vector vector = new Vector(LIST_COUNT); insertSequence(vector); insertRandom(vector); } public void insertSequence(List list) { for (int i = 0; i < LIST_COUNT; ++i) { list.add(element); } } public void insertRandom(List list) { for (int i = 0; i < LIST_COUNT; ++i) { list.add(indexGenerator .nextInt(LIST_COUNT),element); } } } |
上述代码的运行结果如下:
从上图中可以很直观的看出,笔者使用的 HARMONY 版本在该测试案例中速度更快(左图),但内存消耗更多(右图)。下一节将讲述如何输出报表,但或许你已经注意到了,代码非常简单。
从 上面的实例中我们已经看到 p-unit 的输出结果的两种形式,控制台和报表图片。默认情况下,p-unit 将输出到控制台。p-unit 采用事件机制,在运行器的每个节点都会提供通知事件。所有的输出都是通过注册事件响应器来实现的。这也表明了结果输出和运行器完全隔离,用户也可以定制自 己的报表。p-unit 有 4 种内建输出,分别为控制台、文件、图片报表以及 PDF 报表。上一节的例子中我们已经看到图片报表,其代码为:
runner.addPUnitEventListener(new OverviewReporter(new ImageRender())); |
p-unit 内建的报表有分三种不同的粒度:总体级别(OverviewReporter),TestSutie 级别(TestSuiteReporter),以及测试案例类级别(TestClassReporter)。这三种级别都可以输出图片格式或是 PDF 格式,因此,总共有六种类型的输出。上述的代码就是输出总体级别的图片。由于事件监听器是互相独立的,因此你可以既选择输出图片又选择输出 PDF 文件,只需再添加事件监听器即可:
runner.addPUnitEventListener(new OverviewReporter(new ImageRender())); runner.addPUnitEventListener(new OverviewReporter(new PDFRender())); |
至此,你是否基本理解了 p-unit 的概念呢?简单,易用,关注多线程,关注性能,这就是 p-unit。此外 p-unit 还有很多很好的小特性,如 Alphabetical 接口来保证执行测试函数的先后顺序等。使用 p-unit,让你的代码更健壮!
学习
-
p-unit 系列开发教程
:学习如何利用 p-unit 对应用程序进行性能测试。
-
p-unit 相关技术文章
:更多关于 p-unit 的技术资源。
获得产品和技术
-
p-unit 官方网站
:获得 p-unit 开源项目更多信息及相关下载。
讨论
- 订阅 p-unit 开发者邮件列表 :参与项目开发讨论。
发表评论
-
字符串分割--java中String.split()用法
2013-03-06 14:25 74147在java.lang包中有String.sp ... -
用 HttpServletResponseWrapper 实现 Etag 过滤器
2012-07-09 16:58 3757原文出处:http://blog.chenlb.com/200 ... -
Fitnesse使用
2012-05-05 13:27 23491Fitnesse 的使用 一,介绍 Fitnesse是一种 ... -
Customizing the new FitNesse parser
2012-05-05 13:13 2133FitNesse began its life using ... -
java application中内嵌ActiveX控件
2011-11-14 15:57 5516我这里用的是SWT/JFace开发application,SW ... -
Google Java Developer Tools Downloads
2011-08-09 00:04 2346WindowBuilder Pro原来叫WindowB ... -
Jalita
2011-08-06 00:49 1565Jalita (Java light terminal ada ... -
【转】用Java写字符终端界面
2011-07-29 13:13 2120终端界面GUI开源项目charva。 这个框架让你可以用开发 ... -
[转]mybatis下的分页,支持所有的数据库
2011-07-21 13:21 14838大 家都知道,mybatis的自带分页方法只是逻 ... -
Java framework for text- & console-based forms?
2011-07-21 01:06 1709charva jcurses JNA , ... -
JNA(Java Native Access)学习入门
2011-07-21 01:04 22612Java Native Access 项目 在 ... -
JAVA上加密算法的实现用例
2011-06-25 12:38 4882来源:www.ibm.com ... -
如何将GlassFish作为Windows服务运行
2011-05-18 23:21 2370本文档来自GlassFish官方网站,详细介绍了将 G ... -
JAVA UDP打洞必备知识点---NAT
2011-05-05 12:56 8685一、引言 RFCl631 ... -
Keystore概念,Keytool工具使用
2011-04-28 16:20 2902近来由于项目需要做Single Sign On, 研究了一 ... -
利用Eclipse Profile Plugin监控分析Tomcat性能
2011-04-18 16:14 3700目前新版本的Eclipse在启动应用服务器的时候有一个新的选 ... -
m2eclipse: Eclipse is running in a JRE, but a JDK is required
2011-02-04 23:43 2537Eclipse 安装了Maven插件,启动Eclipse ... -
利用JNative实现Java调用动态库
2010-10-18 00:43 2099由于项目要求,需要用J ... -
RHEL5支持大内存
2010-10-08 16:19 3002安装 RHEL 5 ,硬件为 4G 内存,安装完成 ... -
Windows Server 2003 和 Windows 2000 提供大内存支持
2010-10-08 16:19 1854本文介绍物理地址扩展 ...
相关推荐
P-unit 是一款强大的开源性能测试工具,它专为开发者和测试工程师设计,旨在帮助他们评估和优化应用程序的性能。这款软件的独特之处在于其多线程支持功能,使得测试案例能够灵活地在单线程和多线程环境中运行,极大...
测试工具大全是一个全面涵盖各类测试工具的资源列表,旨在帮助测试人员找到合适的工具来执行不同类型的测试任务。这些工具按照其功能和应用领域进行了分类,包括通用功能自动化测试工具、性能测试/监控工具以及白盒...
- Functional Tester:IBM Rational的另一款功能测试工具,可进行UI测试和数据驱动测试。 - SilkTest:Segue Software的自动化测试工具,支持多种应用类型。 - SilkTest International:Segue的全球化版本,支持...
P-Unit是一款针对Java平台的单元测试框架,特别注重性能测试。在本文中,我们将深入探讨P-Unit 0.15版本,了解其功能、使用方法以及如何利用它提升Java应用的性能测试能力。 一、P-Unit简介 P-Unit是Java社区的一...
Test :: Unit :: Lite-无需外部依赖项的单元测试 概要 将作为软件包分发的一部分进行捆绑: perl -MTest::Unit::Lite -e bundle 运行所有测试单元: perl -MTest::Unit::Lite -e all_tests 用作Test :: Unit的...
《BS EN 62595-1-1:2013 LCD backlight unit Part 1-1:Generic specification》是一份重要的技术标准文档,它详细定义了液晶显示器(LCD)背光单元的一般规范。这份标准由英国标准协会(BSI)发布,并在2013年进行...
hadoop-unit-standalone: 有关更多信息,请参见 相容性矩阵 Hadoop单元版本 Hadoop迷你集群版本 HDP版本 Hadoop版本 3.8 0.1.16 HDP 2.6.5.0 Hadoop 2.6.5 + Hadoop 3.2.1 3.7 0.1.16 HDP 2.6.5.0 Hadoop ...
这里就要提到一个非常实用的工具——Mongo-unit,它是一个专门为MongoDB设计的前端开源库,用于帮助开发者对应用中的数据库操作进行单元测试。 Mongo-unit的核心功能在于模拟MongoDB环境,允许开发者在不实际触碰...
团结单元测试助手 入门 这些说明将为您提供测试Solidity Dapp的有用帮助者。 先决条件 您需要安装软件什么东西以及如何安装它们: 。 正在安装 要将条目添加到package.json的依赖项中,请执行以下操作: npm ...
dbt-unit-test可以很容易地为可能在DBT模型中重用的任何代码编写测试用例。 安装 $ pip install dbt-unit-test 或最新版本: $ pip install git+https://github.com/AgeOfLearning/dbt-unit-test.git 设置 从dbt...
因此, postcss-relaxed-unit可以帮助您忘记这一点,您只需要定义一个描述自定义单元到目标单元映射的规则即可! 就这样! :party_popper: 精密溢流 :OK_hand: 您不必担心精度溢出,因为postcss-relaxed-unit包装...
- sharpener:['ʃɑ:pənə] 卷笔刀 - school:[sku:l] 学校 【Unit 2】的单词聚焦在身体部位,有助于孩子们认识和描述自己的身体: - head:[hed] 头 - face:[feis] 脸 - nose:[nəuz] 鼻子 - mouth:[mauθ] ...
数据库单元database-unit 使用数据库简化单元测试。 database-unit 模块提供了 junit 规则,这些规则正在启动一个内存数据库(即 apache derby)进行单元测试。 ##模块:
欢迎来到kvm-unit-tests ...make install会将所有测试安装在PREFIX / share / kvm-unit-tests / tests中,每个测试都是独立测试。 运行测试 然后使用运行程序脚本检测正确的调用并调用测试: ./x86-run ./
Iperf是一款广泛应用于网络性能测试的工具,主要用于评估网络传输性能,包括TCP和UDP带宽质量的测试。它能够提供网络性能的重要指标,如最大TCP带宽、延迟抖动以及数据包丢失情况等。 #### 功能特点 - **TCP和UDP...
此角色是使用Ansible base的版本开发和测试的。 使用Ansible base时,您还需要安装以下集合: --- collections : - name : community.general version : 2.0.0 - name : ansible.posix version : 1.1.1 注意:...
**fd-unit: 用于单元测试的FlashDevelop 4插件** ...对于使用FlashDevelop进行Flex和ActionScript 3开发的团队来说,`fd-unit` 是一个值得考虑的工具,它可以有效提升项目的测试覆盖率和整体质量。
《Swift单元测试:FizzBuzz-Unit-Test-Swift课程详解》 在编程领域,单元测试是确保代码质量的重要手段,它能帮助开发者在早期发现并修复错误,提高软件的可靠性。Swift作为苹果平台的主要开发语言,同样拥有强大的...
测试MarkLogic marklogic-unit-test是一个测试框架,允许项目测试MarkLogic代码。 一经导入,一个项目即可立即访问: 用于编写和运行MarkLogic单元测试的框架,包括几个内置的断言函数用于查看和运行单元测试的UI...
TDD的核心理念是"红、绿、重构":首先写一个失败的测试(红),然后编写足够的代码使测试通过(绿),最后重构代码以保持简洁。这种工作方式能确保代码的健壮性和可维护性。本项目"php-tdd-unit"就是专门针对PHP的...