新項目,WebTest

最近爲了給Jumony for ASP.NET進行單元測試有點傷神,ASP.NET由於環境特殊,一直是單元測試的禁地,傳統的單元測試工具因爲運行在非ASP.NET環境,可謂是舉步維艱。固然,微軟在搞ASP.NET MVC的時候已經注意到了這一點,僱了不少個臨時工把HttpContext以及全部的相關類型所有寫了個Base和Wrapper類型,用來Mock一個HttpContext僞裝在ASP.NET環境。有了這些對象,測試個MVC的Controller和Action也夠用了(只是我還沒找到自動Mock這一大坨對象的方法)。可是ASP.NET環境顯然不止這些,譬如說你們不多用到的VirutalPathUtility就在其列。因爲Jumony for ASP.NET是個框架性質的項目,因此一些框架底層不經常使用的東西隨處可見。固然,也有人不堪其擾,對這個東西也改造了一番: git

還有這個: github

但這些都是internal的,我不能直接用之,再說,指不定哪天就成了public的,個人還與其衝突。最後,我也沒有微軟那麼多臨時工去一個個方法Mock出來。想來想去,個人要求再簡單不過,只要有個HttpRuntime就行了,不妨直接用真的ASP.NET環境。 app

 

用真的ASP.NET環境有幾個方案,VS自帶的測試工具支持ASP.NET的測試,可是摸索了半天,發現侷限大的很,還只能測試aspx文件,用起來也很是的不方便,徹底不能知足個人要求,遂放棄。 框架

而後又想,乾脆本身用控制檯搭一個ASP.NET運行環境出來,這樣的話就能夠本身發個請求進去,讓裏面的代碼執行個結果扔出來。雖然說微軟提供了本身搭建ASP.NET環境的類型和工具,可是因爲宿主和ASP.NET環境是在兩個AppDomain,通訊不便不說,調試起來也特別麻煩,網站編譯什麼都是事兒。 工具

最後,終於想到,TMD乾脆本身在ASP.NET環境搭一個單元測試框架算了。話說其實一個單元測試框架就是找到測試方法而後所有跑一次,再看看有沒有什麼AsertException之類的東西,顯示出來就完了。我直接在ASP.NET環境搭一個,整個單元測試都在網站跑,就什麼問題都解決了。 單元測試

 

而後,就有了WebTest這個開源項目: 測試

https://github.com/Ivony/WebTest 網站

 

既然是從新搞,那新的技術神馬的全都給用上,之前的Assert是個靜態類,一大堆的靜態方法,有些斷言沒有就只好轉換成真假再去判斷。新的框架索性把Assert弄成個對象,全部的斷言方法都給整成擴展方法,大家愛有多少斷言就有多少,不夠再來補充包。之前的測試得本身寫個靜態類,而後每一個方法都要加個[TestMethod]告訴框架這個方法是個測試用的,而我以爲這純屬多餘。只須要寫一個類型,裏面全部的無參public方法所有都被認爲是測試方法,反正框架都會一個個來跑。 設計

肯定好思路後,作起來仍是很快的。首先我想到要有一個類型負責運行測試。 調試

而後來設計這個類型:

  1. 首先咱們能夠獲得一個測試類型,把測試類型丟給TestManager,就能夠進行測試(RunTest)。
  2. TestManager獲得測試類型後,應當建立一個實例來測試,由於全部的測試方法都是實例方法(RunTest)。
  3. 對實例進行測試(RunTest)時,應當找出哪些方法是用來測試的方法(FindTestMethods)。
  4. 找到測試方法後,要給測試方法建立調用器(CreateInvoker),便於快速調用測試。
  5. 運行完測試方法後,要建立測試結果(TestResult),測試結果有三種,成功(Success)、失敗(Failure)、異常(Exception)。
  6. 建立測試結果前,要獲取當前測試方法的信息(GetTestInfo),放在測試結果中。

設計後的結果就是以下圖:

再加上一個找到全部測試類的靜態方法,TestManager就差很少了。

而後是設計TestResult類型,呈現結果的時候,最關鍵的只有兩個元素,消息和是否成功,而後針對三種測試結果,設計三個派生類:

 

再而後定義一個測試基類,繼承於這個類型的全部類型都是測試類:

Initialize和Cleanup如今均可以定義爲這個基類的虛方法,若是須要的話就重寫好了,事實上查找測試類型的時候,查找基類比查找Attribute要快,我想不通如今的測試框架爲啥都要弄個特性來標識。

測試基類提供了一個Assert對象,這個對象能夠用來進行斷言:

由於全部的斷言方法都作成擴展方法,因此斷言失敗的時候須要調用Failure方法來描述斷言失敗了。

 

至此,OOD就基本完成了,而後是一些細節的實現。

查找全部測試類型:

找全部測試方法:

建立Invoker:

事實上,若是熟悉ASP.NET MVC的代碼,這些看似高深的東西並不費神。

 

最後,寫一個IHttpHandler做爲總控,運行測試,並顯示測試結果,而後,就能夠直接寫單元測試用例了。

固然,做爲一個單元測試框架,目前還有諸多欠缺的地方,例如僞造指定URL的請求,分析代碼覆蓋率等,若是我有時間的話,會繼續完善這個框架的。

 

事實上,單元測試並不難,即便是搭建一個測試框架,也就是幾百行代碼的事情,咱們有什麼理由不去作呢?

相關文章
相關標籤/搜索