2009-02-20 49 views
0

編寫標準的TDD [測試]方法會暴露常見的內存問題是否有用?標準.Net TDD內存測試

這組測試可以很容易地被快速應用到一個方法,並且會導致經典的.NET內存問題出現紅色故障,但是會使傳統的解決方案變綠。

例如,常見的內存問題可能是:垃圾收集器的太多重定位 ;分配太多;太多垃圾回收(經典示例比StringBuilder優先於字符串reallocs);堅持記憶太久(經典的示例調用處理,並且不停留在終結器上);不適當地達到g1,g2,LOH的物體;隨着時間的推移,一些重大的漏洞加起來......等等。

也許代碼可能是這個樣子......

[Test] 
public void Verify_MyMethodUnderTest_Is_Unlikely_To_Have_Common_Memory_Problem() 
{ 

//-Setup 
var ExpectationToleranceA = ... 
var ExpectationToleranceB = ... 
... 

//-Execute 
var MeasurementA = MyClassUnderTest.MyMethodUnderTest(dependancyA) ; 
var MeasurementB = MyClassUnderTest.MyMethodUnderTest(dependancyB) ; 
… 

//-Verfiy 
Assert.That( MeasurementA , Is.WithinTolerance(ExpectationToleranceA )) ; 
Assert.That( MeasurementB , Is.WithinTolerance(ExpectationToleranceB )) ; 

} 

有內存壓力問題的其他職位,但這裏的想法是能夠在一個方法來快速指向一個標準的測試和測試將紅色 - 在常見/經典的內存壓力問題上失敗,但綠色 - 通過常見的解決方案。然後,開發人員可能會指出檢查失敗的代碼,並可能修復泄漏,更改公差甚至刪除TDD內存壓力測試。

這個想法有腿嗎?

C++應用程序有一個相關的問題,Memory leak detection while running unit tests,這是一個類似的問題,但不完全相同的事情。 TWK的問題指向看着所有的測試都運行完畢後的記憶......

我在這裏的想法是讓.NET來 1)單元測試,共同記憶每個方法發出 2)失敗的經典內存問題 3 )將經典修補程序傳遞到經典常見內存問題 4)能夠快速在功能上進行快速標準測試,以查看其是否顯示經典症狀 5)能夠升級標準TDD .Net內存壓力測試單元測試。這意味着對上述代碼進行重構,以便標準測試的升級將改變整個Nunit測試套件中針對項目應用的內存測試。

(附註:我知道有沒有Is.WithinTolerance電話,但我只是展示一個想法。) 歡呼......

回答

0

良好的單元測試應該指向小塊的代碼。理想情況下,它們應該是可重複的,當涉及垃圾回收器時情況並非如此。

然而,你可以使用可以使用單元測試框架設施進行非單元測試(功能測試,迴歸測試,壓力測試...)。但你需要知道,你不是在做真正的單元測試。所以不要在某些自動構建中使用它們,也不要強迫其他開發人員在他們的提交測試中包含這些測試。 真正的單元測試可能不會受到非單元測試的影響!

如果您想要做這樣的事情,可以考慮在您要測試的操作前後調用GC.Collect()方法。連續進行多次調用,以更輕鬆地感知內存消耗的增長。考慮在一個單獨的過夜構建中添加這樣的測試(與實際單元測試分開),因爲這可能很耗時。在另一臺完全控制的機器上調用測試(在測試過程中打開帶有一些Flash動畫或病毒掃描程序的瀏覽器可能會影響結果)。將內存消耗的數據存儲在某處供以後查看。這會讓您意識到在長時間的開發週期中緩慢增加的內存消耗。

+0

是的,GC是不可預知的,但可能會告訴傳說中的更大問題的跡象,如給皮膚過敏測試。這可能是「皮膚測試」功能。是的,我的想法不符合TDD單元測試的原始思路。在生產之前確定具有問題的功能將是有用的,... – judek 2009-02-20 23:12:48

3

單元測試,一般最好用於測試小塊的功能。你所追求的東西聽起來更像集成測試,它測試整個系統的行爲和性能。

我用這種方法看到的問題是,系統中的任何給定單元可能不會生成這些與內存相關的錯誤。所以,即使你能得到這樣的工作,你也無法保證一旦你的部門整體工作,內存問題就不會出現。

所以我的建議是在多個州進行集成測試。在不同的負載水平下測試系統,看看會出現什麼樣的內存問題(如果有的話)。這種測試對你來說更有利。

+0

謝謝。我認爲我的想法背後的問題是梳理問題並獲得更好的質量功能代碼,特別是除測試業務功能外的常見內存壓力問題。記憶問題只能用集成測試來表達,這是一個很好的觀點。 – judek 2009-02-20 22:19:02

0

我會說這是一個壞主意。如果你想編寫能夠「驗證」垃圾回收器的某些行爲的測試,那麼基本上就是「測試」你無法控制的代碼。垃圾收集器的確切行爲是當前CLR的實現細節。它可能會在未來發生變化,從而導致您的測試「失敗」。在大多數情況下,您可能無法更改代碼中的任何內容來「修復」測試,因此您不得不更改測試以反映新的實現。在我看來這是有限的使用。

應該使用單元測試來驗證您自己的代碼的意圖,以便在更改破壞現有代碼時通知您。使用它們來幫助開發和維護自己的代碼。

根據我的經驗,最好的結果是通過確保單元測試沒有依賴關係來實現的。做你描述的那種測試意味着測試對硬件和運行時系統都有很多依賴性。

只是我5美分。

+0

好點,TDD建議測試自己的功能。我仍然對.net mem'leaks'感興趣,要麼在一個函數中,要麼與其他函數的調用一起使用。一個函數可能會通過通常的單元測試,但由於它導致.Net內存'泄漏',所以它失敗了,所以如何測試這個... – judek 2009-02-20 22:37:58