欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

認識 p-unit : 一款開源的性能測試工具

系統 2175 0
p-unit 是一款開放源碼的性能測試框架,和 JUnit 不同,JUnit 關注的是測試案例的正確性,而 p-unit 不僅關注測試案例的正確性,還收集測試案例的性能參數,默認情況下,p-unit 收集測試案例的時間和內存消耗情況,可以產生文件,圖片,和 PDF 格式的報表。此外,p-unit 還支持參數化測試,多線程測試以及不同 Java 虛擬機性能之間的比較。

p-unit 簡介

或許我們已經習慣了使用 JUnit 來寫單元測試來保證代碼質量(我也一直這么做),但可能經常碰到這樣的問題:

  1. 程序多線程下正確性如何?
  2. 如何測試程序的性能?
  3. 當有多個方案可以選擇時,技術上如何比較不同方案的性能?

對 于問題 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 是一個最為普通的測試案例:


清單 1. 測試案例 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 函數中寫一行代碼來運行它:


清單 2. 單線程運行測試案例

            	
public static void main(String[] args) {
	new PUnitSoloRunner().run(SimpleTestClass.class);
}

          



清單 3. 單線程運行測試案例結果

            [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 即可!


清單 4. 多線程運行測試案例

            public static void main(String[] args) {
	new PUnitConcurrentRunner().run(SimpleTestClass.class);
}

          



清單 5. 多線程運行測試案例結果

            [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 接口,該接口的定義為:


清單 6. p-unit Concurrent 接口

            public interface Concurrent {
	public int concurrentCount();
}

          

?

該接口的意思,相信無需再多做解釋了,返回該測試案例需要的線程數。

參數化測試案例

性能測試,不同于單元測試,經常要求測試不同數量級在同一個測試場景中的表現,JUnit 是一款非常優秀的單元測試工具,但沒覆蓋到這個方面。比如我們比較類庫 Foo1 的方法 bar() 和類庫 Foo2 的方法 bar() 哪個更符合自己的應用程序,我們需要測試該函數在應用程序可能的數量級的范圍內的表現。有經驗的開發者知道經常碰到在小數量級 A 更好大數量級 B 更好的局面,因此全面的測試對于代碼的性能理解非常重要,能幫助開發者做出正確的決定。p-unit 支持將參數傳給測試方法,測試案例需要實現 p-unit 的 parameterizable 接口,該接口的主要方法是返回一組參數列表,這組列表的參數將會一一傳給測試方法。


清單 7. p-unit 參數化測試案例

            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);
		}
	}
}


          

?

上述代碼的執行結果為:


清單 8. p-unit 參數化測試案例輸出

            [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 函數即可:


清單 9. p-unit 運行環境測試案例

            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);
        }
    }
    
}

          

?

上述代碼的運行結果如下:


圖 1. 運行環境測試案例結果
圖 1. 運行環境測試案例結果 圖 1. 運行環境測試案例結果

從上圖中可以很直觀的看出,筆者使用的 HARMONY 版本在該測試案例中速度更快(左圖),但內存消耗更多(右圖)。下一節將講述如何輸出報表,但或許你已經注意到了,代碼非常簡單。

從 上面的實例中我們已經看到 p-unit 的輸出結果的兩種形式,控制臺和報表圖片。默認情況下,p-unit 將輸出到控制臺。p-unit 采用事件機制,在運行器的每個節點都會提供通知事件。所有的輸出都是通過注冊事件響應器來實現的。這也表明了結果輸出和運行器完全隔離,用戶也可以定制自 己的報表。p-unit 有 4 種內建輸出,分別為控制臺、文件、圖片報表以及 PDF 報表。上一節的例子中我們已經看到圖片報表,其代碼為:


清單 10. 添加 p-unit 總體圖片報表

            runner.addPUnitEventListener(new OverviewReporter(new ImageRender()));

          

?

p-unit 內建的報表有分三種不同的粒度:總體級別(OverviewReporter),TestSutie 級別(TestSuiteReporter),以及測試案例類級別(TestClassReporter)。這三種級別都可以輸出圖片格式或是 PDF 格式,因此,總共有六種類型的輸出。上述的代碼就是輸出總體級別的圖片。由于事件監聽器是互相獨立的,因此你可以既選擇輸出圖片又選擇輸出 PDF 文件,只需再添加事件監聽器即可:


清單 11. 添加多個 p-unit 事件監聽器

            runner.addPUnitEventListener(new OverviewReporter(new ImageRender()));
runner.addPUnitEventListener(new OverviewReporter(new PDFRender()));

          

?

總結

至此,你是否基本理解了 p-unit 的概念呢?簡單,易用,關注多線程,關注性能,這就是 p-unit。此外 p-unit 還有很多很好的小特性,如 Alphabetical 接口來保證執行測試函數的先后順序等。使用 p-unit,讓你的代碼更健壯!


參考資料

學習


獲得產品和技術


討論

認識 p-unit : 一款開源的性能測試工具


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 久久爱伊人 | 久久亚洲精品中文字幕二区 | 亚洲国产精品热久久 | 精品一区二区免费视频 | 日韩欧美精品 | 欧美综合自拍亚洲综合图片区 | 久久我们这里只有精品国产4 | 午夜影院在线观看视频 | 欧美一级在线播放 | 国产精品视频99 | 日本不卡一区 | 色秀视频在线观看全部 | 久久亚洲国产欧洲精品一 | 牛牛a级毛片在线播放 | 久久中文字幕一区 | 国产精品久久婷婷六月丁香 | 超碰在线国产 | 国产福利视频一区二区 | 二级毛片视频 | 色橹橹欧美在线观看视频高清免费 | 麻豆精品传媒一二三区在线视频 | 色天天天天综合男人的天堂 | 精品久久久久久久久久久久久久 | 日本九九视频 | 亚洲欧美一区二区三区在线 | 成人在线观看国产 | 高清在线一区二区 | 天天干夜夜笙歌 | 欧美日韩亚洲一区二区三区在线观看 | 在线视频中文字幕乱人伦 | 亚洲第一精品在线 | 涩涩撸 | 成人在线小视频 | 日韩在线观看视频一区 | 欧美日韩一区二区三区四区五区 | 日韩电影在线看 | 亚洲欧美日韩精品久久亚洲区色播 | 日韩黄色影视 | 奇米影视四色7777 | 欧美videosex性欧美成人 | 中文字幕av网 |