昨天一位園友sinodragon21在Windows phone應用開發[9]-單元測試評論中.提出關於Windows phone 單元測試中可否使用微軟的Pex自動化生成工具生成單元測試用例.和單元測試質量即代碼覆蓋率統計問題.頗有價值.html
針對這兩個問題.首先須要解釋.關於Windows phone 中單元測試現狀.針對Windows phone應用程序Unit Test 官方並無在IDE提供對應的測試框架,目前開發者社區使用比較普遍框架是MS Windows phone 產品組Jeff.wilcox維護的Silverlight Unit Test Framework[SUTF] Windows phone版本.詳見Blog:Updated Silverlight Unit Test Framework bits for Windows Phone and Silverlight 3 . 但這個版本始終做爲我的形式對開發者發佈.並無以正式的官方渠道向Windows phone開發者推送,因此官方對此並無提供指定的維護和開發者社區支持.數組
至此官方也就沒有提供自動化測試工具道理. 相似Android 平臺自動化Monkeyrunner以外還有更多選擇.而Windows phone自動化測試只能靠開發者本身想辦法.app
那麼關於SUTF 中Code Converage代碼覆蓋率呢? 針對這個問題 特別諮詢SUTF WP版本維護做者Jeff.Wilcox.獲得回覆信息以下:框架
HI Jeff,
how to take code coverage from SilverLight Unit test framework for WP7?編輯器
jeffwilcox Reply:ide
Code coverage is not available, it was a feature that was cut before
shipping for 2010 from the toolkit.函數
在2010年發佈SUTF版本時已經去掉對Code Converage支持. so.既然如此是否真的就此定論了.? Now 如今提到Pex and Moles.仍是不甘心.打算動手在應用程序中親自驗證.本篇並不打算當即採用Pex在SUTF進行驗證.有必要系統瞭解Pex and Moles.工具
<1>構建Pex測試環境Well.關於Pex And Moles其實能夠分爲兩個部分.其一Pex-全稱是[Program EXploration]是微軟研究院的一個關於白盒測試自動生成工具.原來開發人員只能經過指定路徑編寫獨立的測試用例.PEX經過分析代碼來自動生成測試用例。對於程序裏面的每一行代碼,PEX都會盡量地生成合適的輸入值來達到提升覆蓋率的目標。同時PEX還會分析代碼中的分支,生成覆蓋更多分支的測試代碼(輸入數據);PEX在執行代碼的同時會監控和分析代碼的控制流和數據流,瞭解程序的行爲。每運行完單一個測試之後,PEX會選擇一條在前面的測試中沒有覆蓋到的路徑,而且嘗試執行它.本篇主要來說到的是PEX.單元測試
PEX自動化生成用例並執行UT返回測試結果的過程.大大減小開發人員手動編寫大量測試用例狀況發生.測試
關於PEX and Moles可經過以下連接瞭解更多:
PEX And Moles:
Pex and Moles - Isolation and White box Unit Testing for .NET
Download Page:
Pex and Moles – Download Page LinkGet Start Online PDF Document:
找到下載頁面.PEX如今有3個Flavor,支持2個版本的Visual Studio,分別是VSTS2010和VSTS2008,這3個版本的PEX在功能上存在區別,這主要由於下載受衆羣體不一樣,通常用戶只能使用到PEX功能.本篇全部演示都是基於Visual Studio 2010. 基於MSDN訂閱權限下載PEX And Moles完整版本.
安裝完成後.能夠打開Visua Studio 當即建立一個Console Application命名爲BasicConsolePexComponent_Demo,在此先不要把焦點放在PEX原理實現上.來快速體驗一下PEX.首先須要在Program類中頂一個轉換字符串的方式.做爲測試用例的宿主程序.建立以下:
well通常狀況下.關於如何創建單元測試應用程序,通常若是沒有PEX以前.可能做爲開發人員更多的是根據該方法實現.建立一個新的Test測試項目.構建對應測試用例.實現對該方法的UT.其實這個過程已經Visual Studio內置了這些工做已經自動建立.只需右鍵點擊就能看到Create Unit Test選項:
點擊後能發現.其實Create Unit TEst爲了不測試框架和測試用例污染源代碼自己.通常狀況要對單元測試用例和源代碼執行分離.也就是建立一個新的單獨測試項目.
此時在執行測試以前須要作一些設置點擊Settings按鈕:
須要設置建立默認文件以及對應測試類和測試方法名稱.點擊ok.若是沒有設置對應測試項目名稱會以下提示:
修改完成後開始建立.建立過程可能會有以下提示:
建立前提示主要提到兩點.須要爲測試項目BasiceConsolePexComponent_Demo設置InternalsVisible屬性可用.這是設置其實內在的緣由是.對一個組件或模塊進行單元測試時.單元測試用例須要調用定義在測試組件或模塊中的Internal成員對象時. 須要跨程序集訪問.而Modifier的Internal類型成員默認設置僅限於當前程序集訪問.而對宿主程序而言須要暴露給測試程序集調用.
另一點在不少狀況下,咱們須要將最終的程序集以強命名的形式發佈。爲此,咱們修改Lib項目設置,開啓"Sign the assembly」開關,並建立一個密鑰文件.不能經過編譯,具體的錯誤信息爲:「Friend assembly reference 'Test' is invalid. Strong-name signed assemblies must specify a public key in their InternalsVisibleTo declarations.」,針對須要指定的不是程序名的強命名,而是指定對程序集進行簽名時採用的公鑰.把公鑰指定到InternalsVisibleToAttribute特性中便可.
點擊ok.看一下項目結構:
多了一個測試項目和該項對應Program方法測試類.now構建好了測試項目.在回到宿主程序Program類中對字符串轉換操做的方法見一個UT.找到該方法名右鍵依然可見Create Unit Test選項點擊看到:
能夠看到針對方法作UT時會把該UT的應用程序的輸出默認爲剛纔建立的測試項目:AutomationConsole.Test.點擊ok.找到測試項目下ProgramProgramTestHelper類能夠看到增長一個測試方法以下:
能夠看到該測試方法命名依然採用默認命名方式.方法內代碼實現關於調用Program類中字符串轉換大寫操做的方法ConvertStringToUpper. 分別定義三個變量的字.其實從變量名稱徹底能夠看出這是一個默認的測試用例.要想改UT達到想作.只需修改對應變量參數的值來匹配.InputString做爲方法參數輸入.通過測試用例會會生成對應指望值和方法執行實際值.最後經過對指望值和實際比對得到對應測試結果.直接運行 能夠看到測試結果以下:
well由於兩個測試用例都沒作了修改沒有實際值傳入因此都是Inconcluetive測試結果不肯定.如今看看這種傳統方式下一Visual Studio Unit TEst框架爲主UT編寫開發人員要重複作哪些工做.?首先要重複手動編寫大量的UT測試用例.目的是在給定的方法中爲每一個執行路徑手寫獨立測試. 並且針對這種沒法避免的要建立一個獨立的測試項目.其實在實際編碼中.並非全部模塊都須要即時創建UT.可能需求發生變動.從開發人員角度來講建立一個笨重測試項目這意味更多精力發在測試代碼維護上.可能咱們更須要一種既可以建立對應測試項目同時也能即時看到當前版本Code UT效果.
Now.UT屬於白盒測試的範疇.若是可以有一個很好白盒測試工具可以封裝這些重複的行爲.並可以重複執行UT測試用例.讓開發人員從Ut的過多細節和維護中解放出來關注更核心的業務邏輯.Pex and moles就是這樣的一個工具.
<2>Pex 構建白盒測試雖然本篇幅沒有核心焦點放到Pex實現原理上.但關於Pex and Moles其實分爲兩塊整理官方原文翻譯以下[直譯]:
Pex Pex 是一個 Visual Studio 外接程序,用於補充 .NET Framework 應用程序上的單元測試。 Pex 在 Visual Studio 代碼編輯器中查找對應程序方法的輸入和輸出值。 PEx將這些值另存爲將具備高代碼覆蓋率的小型測試套件。
Moles Moles 容許開發人員將任何 .NET 方法替換爲委託。 Moles 經過使用 Detour 和 Stub 提供隔離來支持單元測試。 由於 Moles 在方法級別工做,因此當目標 API 不支持它時,它提供替代項進行模擬。 SharePoint 是一個受益於隔離的常見 API 示例,但不直接支持模擬。Moles 還可用於錯誤植入,由於它使得開發人員在測試下向代碼中注入任意行爲變得輕鬆.
Pex核心是給開發人員一個手寫的參數化單元測試,Pex徹底自動地分析代碼,來決定相關的測試輸入。其結果就是生成一個有着高度代碼覆蓋的傳統單元測試,另外,Pex還會建議開發人員如何去修復所發現的Bug.
安裝完Pex and Moles工具後.打開Visual Studio 能夠看到右鍵選項中多了:
Run Pex 和Pex 下Create Parameterized Unit Tests兩個可操做選項.針對Pex測試效果.首先在Programe類添加一個字符串合併操做方法代碼以下:
注意該方法的輸入參數firstname和lastname在方法內都沒有判斷是否空字符串或是Null並且裏面涉及字符數組的操做.針對該方法採用Pex方式執行UT操做.右鍵調集選中Run Pex 提示以下:
注意咱們當前類是在Program類下.該類的簽名以下:
提示的意思當前類型不可見.沒法經過Pex方式建立UT,須要把當前類的簽名改爲公開 虛類型便可:
在來運行Run Pex 彈出執行 結果窗體以下:
能夠看到Pex在沒有建立一個獨立單元測試項目和對應測試類狀況.自動對當前方法進行白盒測試封裝.運行測試109 Runs次.建立了7個測試用例. PEx會監視當前類,而且運行這個方法.執行屢次測試.其中有三次測試失敗的.並Sunmmary/Exception 提出具體測試參數和出現的異常信息.
點擊對應失敗的測試用例.能夠在右側彈出對應異常堆棧詳細信息.:
點擊DEtails能夠看到執行該測試用例的代碼和對應異常信息:
在查看異常詳情右側窗口中.能夠執行以下操做:
Save Test保存當前PEX的測試用例爲普通單元測試用例.點擊保存:
若是在此以前沒有建立對應Pex測試項目會提示當前測試用例輸出.或是提示建立一個新的測試項目:
上面Project Under Test是待測試的宿主項目.而下面是須要建立新的測試項目設置.點擊OK建立一個新的測試項目.這裏在RunPex時並無強制開發人員強制創建一個新的測試項目.可是這裏SAve 目的是在於若是以爲當前測試代碼能夠留存作之後迴歸測試.PEX也是支持測試代碼保存的.
add Precondition是用來經過Pex自動添加代碼來避免錯誤的發生.而All Exception則容許次異常在當前應用程序中出現.send to若是你的項目採用TFS版本控制.sendto操做會吧全部信息發到文本或剪切板中.這裏全部的信息包括Detail和STack Trace 若是TFS裏配置WorkItem,PEX會自動發送對應的WorkItem中.
well如今既然存在異常.經過Add PreCondition來經過Pex來修正.會看到以下菜單:
這個窗體中上半部分告訴開發人員PEX在當前會作哪些操做.操做會修改哪些方法等.下半部分則是PEX具體的添加的修復代碼.能夠看到對firstname輸入參數因當前NullException異常因此添加了是否非Null的判斷。點擊Apply能夠看到原來代碼中添加一段判斷代碼 完整以下:
<pex>標籤之間註釋就是PEX修復是添加的代碼.若是以爲PEX代碼不夠美化.開發人員也徹底能夠手工修改.自此你會看到PEX幫開發人員找到一個Bug並嘗試不在維護UT代碼的狀況下並修復該異常.well.固然如上演示只是PEX做爲白盒測試工具的豐富功能一個特性.其實剛開始看官方給出解釋最吸引我莫過於它支持寫參數化單元測試[Parameterized Unit Test].方式.
<3>Pex參數化單元測試在Pex中針對白盒測試提出參數化單元測試的概念-Parameterized Unit Test。Dang咱們經過PEX實現更多模塊的UT操做.確保全部單個模塊可以按照程序設計預期執行. 其實實際效果並不是如此.PEX經過一個指令一個指令地分析.NET代碼,解釋代碼執行時的動做,而後「以一種徹底自動的方式,計算出那些能觸發邊角代碼的相關測試輸入。」
PEX在執行和分析代碼行爲時.只是獲得代碼最基本代碼模塊行爲簡單異常相似NullException.可是實際上開發人員並無寫過一個關於全部模塊集成起來以後完整測試用例. 沒法預期當前軟件的行爲.PEX提供參數化的單元測試提供一種強大的方式來評估當前代碼在集成後是否如預期同樣行爲.
找到上次增長SpiltStringToMerge字符串合併操做方法作實例.建立參數化單元測試:
找到該方法選中右鍵點擊能夠看到Pex->Create Parameterized Unit Tests選項:
若是原來沒有建立對應的PEX測試項目會提示建立一個新的Test Project.與宿主程序分離.能夠看到增對測試文件目標PEX增長多重過濾項. 在Test Project項目輸出上若是沒有建立Test Project則建立.固然針對建立的測試項目能夠指定不一樣的測試框架.PEX中集成了NUnit/Visual Studio Unit TEst/MbUnit V系列等.讓開發人員以本身最熟悉的測試框架來維護測試代碼.Pex還基於擴展反射可管理子協議API (Extended Reflection managed profiling API)對監測應用程序的集成提供了支持.在建立看一下設置項Settings:
能夠設置默認建立的命名空間和測試類下默認PexMethod測試方法.這裏採用默認方式建立:
建立成功後Solution目錄:
打開ProgramTest.cs文件能夠看到這個PEX自動生成的參數化單元測試方法:
其實關於PEX參數化單元測試的概念.其實它就是一個帶有參數並經過調用宿主測試程序簡單測試方法.其實這裏不少人都很疑惑怎麼和傳統建立單元測試方法和PEX參數化方法區別在哪呢?其實昨天我在看到這時也很困惑好久.後來在官方找了不少資料.總算是找到一點權威的論述:
A unit test is a method without parameters represents a test case which typically executes. a method of a class-under-test with fixed arguments and verifies that it returns the.
expected result. A parameterized unit test (PUT) is the straightforward generalization。of a unit test by allowing parameters. PUTs make statements about the code’s behavior.
for an entire set of possible input values, instead of just a single exemplary input value.
相對傳統建立的單元測試通常狀況參數都是指定固定的參數值.並在執行後會預期函數中返回對應的結果.PEX參數化單元測試概念則不一樣.在PEX中單元測試的參數能夠輸入任何可能的參數用來驗證程序代碼執行中全部可能的行爲.你大概明白PEX提出這個概念的目的了吧.也就是說PEX在執行的時候會分析PEX參數化單元測試代碼方式來查看宿主程序代碼的行爲.固然這個過程須要集成宿主程序的代碼.而相對於傳統固定參數值.PEX單元測試參數能夠是任意的.這樣更便於測試過程當中測試宿主程序代碼可能出現崩潰的概率和行爲.
當前已經建立PEX對應的測試項目.在回到宿主橫須Program類中.再次運行Run PEX:
出了能看到原來Pex Test Results窗體測試結果.注意這時PEX內部根據測試須要會在測試項目對應測試ProgramTEst類中.建立普通測試方法[TestMethod]同時也會建立PEX下參數化單元測試. 建立普通測試的數量和測試結果中測試用例的數量是一致的.若是TestReaults.PEX使用7個用例那麼在ProgramTest.SpiltStringToMerme.g.cs文件中確定會有相同數量的普通測試方法存在.PEX參數化單元測試方法則放在ProgramTest.cs文件中.
若是你以爲這個過程不明顯.或是想了解一些PEX工做處理過程.能夠選中右鍵能夠PEX->Delete Generated Unit Tests操做:
其實該操做的目的會自動刪除ProgramTest.SpiltStringToMerme.g.cs文件中全部的普通測試方法[TestMethod]也就是當前使用測試用例.而後找到該方法在運行Run PEX./運行玩後能夠找到對應測試實例的Save Test方式在把指定的測試用例保存到ProgramTest.SpiltStringToMerme.g.cs文件中.well 這裏保存第一個經過的測試用例 低級Save TEst:
Apply.完成後.會看到ProgramTest.SpiltStringToMerme.g.cs文件中多了一個普通測試方法.同時在Test Result窗體中發現每一個測試的圖標再也不包含一個磁盤位圖而是一個對號.:
這樣有選擇的方式讓開發人員很輕鬆可以保存在不一樣版本需求變更生成的測試用例/.並且是可選擇的.固然在添加過程每每會提示一些命名上問題例如以下提示:
這是由於如今PEX如今對中文GB2312格式支持存在亂碼的問題. 固然在建立是PEX爲了防止訪問路徑過長.就限制在PEX全部文件命名長度.
其實到這裏不少人依然對PEX 參數化單元測試的概念依然有些困惑.這個概念其實很簡單.但在實際運用你會發現它的實際用途的好處.若是你熟悉並經常使用的單元測試.但還不理解PEX中參數化單元測試概念.能夠從如下幾個方向去考慮[僅做參考]:
理解參數化單元測試的方向:
[1]:當時你手寫普通的單元測試.思考如下你要測試代碼的行爲.在構建單元測試時你的須要多少個獨立參數傳入.?
[2]:目前尚不清楚確切的數字可能會是什麼.但在測試過程它是很重要的,因PEX角度來講開發人員永遠有時間來即時建立和維護測試代碼.
固然更多還請參考官方的資料:http://research.microsoft.com/en-us/projects/pex/default.aspx
<4>Pex小結本篇PEX 自身應用角度來闡述PEX相對傳統單元測試所具備的特色.做爲一個白盒的測試工具.開發人員常在程序開發過程當中.需求每每也是不斷變化的.固然也沒法避免將來開發過程當中.或進入代碼維護階段是.所須要面對代碼修正的問題.爲了每次都能保證軟件代碼工做都正確無誤.並且即時在需求發生變動須要添加新功能時.也能保證原有功能正常運行.使用可控的測試導向的開發模式是必行的.
固然做爲開發人員要在開發過程手工編寫大量的測試用例並維護笨重測試的代碼.這會在必定程度上致使項目開發進度延緩。這也是不少開發人員忽視UT一個緣由之一.但如今PEX白盒測試工具.能夠把測試流程徹底的自動化.把開發人員從單元測試的需求中解脫出來專一於核心業務開發之上.
本篇並無急於在Windows phone Application 中驗證PEX是否可行.可是PEX透露出來關於測試理念確實頗有深刻的價值.稍後會在下篇副中不管成功仍是失敗.演示Windows phone應用程序中使用PEX整個過程.
若有問題請在評論中提出.本篇全部源代碼下載地址以下:/Files/chenkai/BasicConsolePexComponent_Demo.rar