在MUnit中寻找像JUnit的@Before/@After这样的东西

mmo*_*ris 5 wolfram-mathematica

我在一个.mt文件中编写了许多测试用例,这些测试用例共享常见的设置(和拆卸)过程.我希望看到类似JUnit的@Before/ @After,但MUnit软件包中没有任何内容跳出来,这样就可以实现这一点.老实说,MUnit软件包文档比Wolfram Workbench的MUnit文档要好一些,但它还远未完成. 查看MUnit包的说明.

所以在我重新发明轮子之前,我想我会检查一下我是否错过了MUnit中的某些内容,或者是否有人的模式运行良好?

所以根据Leonid Shifrin的最初答案(他把我的答案放在一起时更新了他的答案)这是(我)在哪里(当时)...

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[];
Run Code Online (Sandbox Code Playgroud)

Leo*_*rin 3

MUnit文件是普通的包文件,它们是按顺序读取和执行的 - 或者至少这是我对它们的经验。您只需在测试之前和之后添加包含公共代码的行,它们将分别在所有测试之前和之后执行。

如果您想为每个测试单独调用设置和拆卸过程,您可以在每个测试之前和之后添加相应的行(调用)。然后,您可能会发现编写一个预处理器很方便,它将您的测试作为包加载(例如,通过使用Import["Tests.tm","HeldExpressions"]- 在此示例中测试所在的位置Tests.tm),然后插入相应的行,然后再次保存文件。这将需要对所保存的代码进行一些流畅的操作,但可以相当快地掌握,并且如果您有很多测试,则非常方便。

编辑

作为更轻量级的替代方案,您可以定义类似宏的快捷方式。以下是测试文件内容示例:

(* 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];

wrapTest@
Test[f[2],
  8,
  TestID -> "MyTest1"
]

wrapTest1@
Test[f[2],
  8,
  TestID -> "MyTest2"
]
Run Code Online (Sandbox Code Playgroud)

该功能beforeafter模仿您的设置/拆卸功能。该函数withCodeAfter是一个辅助宏,它before首先执行 code,然后执行 code after,但最终返回 的结果before。这些函数wrapTest说明wrapTest1了两种可能性:您可以定义单独的“before”和“after”函数并将代码夹在其中,或者您可以使用Block并定义“around”宏,这有时可能更方便。无论哪种方式,测试都会有效。您还可以混合使用这些方法。在这两种情况下,样板代码的数量都是最少的 - 只需wrapTest@在每次测试之前添加一行即可。