2012-01-03 45 views
5

我在一個共享通用設置(和拆卸)過程的單個.mt文件中寫入了大量測試用例。我希望看到像JUnit的@Before/@After這樣的東西,但是沒有任何東西從MUnit包中跳出來,那樣就可以實現這一點。老實說,MUnit軟件包文檔比Wolfram Workbench的MUnit文檔稍好一些,但它也遠沒有完成。因此,在我開始重新發明輪子之前,我想我會檢查是否在MUnit中遺漏了某些東西,或者如果有人有一種運行良好的模式?在MUnit尋找像JUnit的@Before/@After之類的東西

因此,基於列昂尼德·希夫林初始答案(他更新了自己的答案,而我把這個在一起),這是(是)我所在的地方(是)在...

TestPlus.mt

(* Mathematica Test File *) 

(* x is a global value *) 
x=0; 

SetUp[] := Module[{}, x=1;]; 
TearDown[] := Module[{}, x=0;]; 

(* test SetUp[] *) 
SetUp[];  
Test[x, 1, TestID->"SetUp-20120103-F2U9V6"] 

(* test TearDown[] *) 
TearDown[]; 
Test[x, 0, TestID->"TearDown-20120103-O4R6M7"] 

(* test plus --contrived tests-- *) 
SetUp[]; 
Test[x+0, 1, TestID->"Plus-20120103-S5D9X6"] 
TearDown[]; 

SetUp[]; 
Test[x+1, 2, TestID->"Plus-20120103-D7Q3E0"] 
TearDown[]; 

SetUp[]; 
Test[x+2, 3, TestID->"Plus-20120103-F0S4P9"] 
TearDown[]; 

回答

3

MUnit文件是正常的包文件,並將它們讀取和順序執行的 - 或者至少這是我與他們的經驗。您可以簡單地在測試前後使用通用代碼添加行,並且它們將分別在所有測試之前和之後執行。

如果您想針對每個測試單獨調用設置和拆卸過程,可以在每次測試之前和之後添加相應的行(調用)。你可能會發現編寫一個預處理器會很方便,它將把你的測試作爲一個包加載(例如,通過使用Import["Tests.tm","HeldExpressions"]--在這個例子中你的測試在Tests.tm中),然後插入相應的行並再次保存文件。這需要一定的流利度來操作保存的代碼,但可以快速合理地選擇,如果您有很多測試,則非常方便。

EDIT

作爲更輕質的替代,可以定義宏狀捷徑。下面是一個例子測試文件內容:

(* Mathematica Test File *) 

before[]:= (Print["Before Test: ",f[2]];f[x_]:=x^3); 
after[] := (ClearAll[f];Print["After Test: ",f[2]]); 

SetAttributes[withCodeAfter,HoldRest]; 
withCodeAfter[before_,after_]:=(after;before) 

SetAttributes[{wrapTest,wrapTest1},HoldAll] 
wrapTest[code_]:= withCodeAfter[before[];code,after[]] 
wrapTest1[code_]:=Block[{f},f[x_]:=x^3;code]; 

[email protected] 
Test[f[2], 
    8, 
    TestID -> "MyTest1" 
] 

[email protected] 
Test[f[2], 
    8, 
    TestID -> "MyTest2" 
] 

功能beforeafter模仿你的安裝/拆卸功能。函數withCodeAfter是一個幫助程序宏,它首先執行代碼before,然後執行代碼after,但作爲結果返回before的結果。函數wrapTestwrapTest1說明了兩種可能性:您可以定義單獨的「之前」和「之後」函數,並將它們與代碼夾在一起,也可以使用Block並定義「around」宏,有時可能更方便。測試將以任何方式工作。你也可以混合使用這些方法。在這兩種情況下,樣板代碼的數量都很小 - 只需在每次測試前添加[email protected]行。

+0

好吧,我更新了我的問題有什麼,我還以爲你在談論一位跛腳的例子。現在,我明白你在說什麼了。謝謝 – mmorris 2012-01-03 22:29:35

+0

@mmorris感謝您的接受。您的更新確實是我在最初回答中的含義。我的更新只是爲了展示如何用相對少的努力來減少樣板代碼的數量。 – 2012-01-03 22:43:51

+0

請參閱下面的答案。謝謝Mike – mmorris 2012-01-05 03:15:33

0

我無法格式化的評論,所以我這樣做,作爲一個答案正確...

好吧,我想我已經解剖的代碼在你的答案,請讓我知道如果我正確。


定義之前和「測試案例」後評估什麼是評估。一個側面說明,你正在定義fbefore,undefining fafter

(* Mathematica Test File *) 

before[]:= (Print["Before Test: ",f[2]];f[x_]:=x^3); 
after[] := (ClearAll[f];Print["After Test: ",f[2]]); 

定義功能withCodeAfter。它需要兩個表達式,第一個表達式before在傳入時進行評估。第二個表達式after未被評估,並且是withCodeAfter中要評估的第一個表達式。評估的第一個表達式beforewithCodeAfter返回。

SetAttributes[withCodeAfter,HoldRest]; 
withCodeAfter[before_,after_]:=(after;before) 

定義功能wrapTest。它需要一個表達式,code,傳入未評估。該表達式code是化合物表達式before[];code的第二表達式,其作爲第一表達式before傳遞至withCodeAfter。在傳遞到withCodeAfter時評估化合物表達式before[];code。評估的表達式code的值由withCodeAfter返回,其後after被評估。 withCodeAfter返回的值由wrapTest返回。

SetAttributes[{wrapTest},HoldAll] 
wrapTest[code_]:= withCodeAfter[before[];code,after[]] 

是一回事調用wrapTest[Test[f[2], 8, TestID -> "MyTest1"]]

[email protected] 
Test[f[2], 8, TestID -> "MyTest1"] 
+0

是的,你完全正確 - 這正是發生的事情。函數'withCodeAfter'只是一個方便的函數,它不是必須的 - 只是保存一個輔助變量的引入來保存'before'的結果。它實際上是一個宏,也許是我知道的有用宏的縮寫。對不起,如果我的答案不是很清楚。 – 2012-01-05 10:08:54

+0

感謝您的理智檢查! – mmorris 2012-01-05 13:14:39

相關問題