使用测试框架
使用测试框架
test = VerificationTest[2 + 2, 4]TestCreate 仅创建测试,而不立即运行它:
test = TestCreate[2 + 2, 4]如要运行测试,可以使用 TestEvaluate:
TestEvaluate[test]因为 TestCreate 不对测试进行实际运算,所以创建测试是一个快速操作:
AbsoluteTiming[tests = Table[TestCreate[Pause[1];2 + 2, 4, TestID -> i], {i, 4}]]AbsoluteTiming[Map[TestEvaluate, tests]]你可以考虑使用 ParallelMap 对长时间的测试运行进行加速:
AbsoluteTiming[ParallelMap[TestEvaluate, tests]]在使用 TestCreate 创建测试时,不会运算输入表达式中包含的符号. 考虑以下测试:
a = 2;
test = TestCreate[a + 3, 5]test["Input"]TestEvaluate[test]Clear[a];
TestEvaluate[test]为了避免全局依赖性,您可以使用例如 With 将值注入到测试中:
test = With[{a = 2}, TestCreate[a + 3, 5]]test["Input"]expr = NumericArray[Range[10]]output = Export[CreateFile[], expr, "WXF"]result = Import[output, "WXF"]result == exprTestEvaluate @ TestCreate[
Import[Export[CreateFile[], NumericArray[Range[10]], "WXF"], "WXF"],
NumericArray[Range[10]]
]tests = TestEvaluate @ {
TestCreate[
output = Export[CreateFile[], NumericArray[Range[10]], "WXF"],
_String ? FileExistsQ,
SameTest -> MatchQ,
TestID -> "my-test-export"
],
TestCreate[
Import[output, "WXF"],
NumericArray[Range[10]],
TestID -> "my-test-import"
]
}Last[tests]["Input"]test = TestEvaluate @ TestCreate[
With[
{output = IntermediateTest[
Export[CreateFile[], NumericArray[Range[10]], "WXF"],
_String ? FileExistsQ,
SameTest -> MatchQ,
TestID -> "my-test-export-stage"
]},
Import[output, "WXF"]
],
NumericArray[Range[10]],
TestID -> "my-test-import"
]test["IntermediateTests"]如果 IntermediateTest 失败,外部测试也会失败,因此您仍然会获得测试的单个总体结果. 您可以检查外部测试中的 IntermediateTest 结果,以查看外部测试的哪些步骤有效,哪些步骤失败.
TestReport 是一个具有多种用途的单一函数.
使用 TestReport 运行测试
TestReport 可用于运行多个测试:
TestReport[{
TestCreate[Sin[E] > Cos[E]],
TestCreate[MatrixQ[{{1, 2, 3}, {4, 5, 6, 7}}]], TestCreate[1 / 0, ComplexInfinity]
}]tests = {VerificationTest[Echo[1 + 1], 2], TestCreate[Echo[2 + 2], 4]}TestReport[tests]使用 TestReport 合并测试结果
r1 = TestReport @ Table[TestCreate[RandomInteger[], 1], 4]
r2 = TestReport @ Table[TestCreate[RandomReal[], 0.5, SameTest -> Greater], 12]r3 = TestReport[{r1, r2}]TestReport 在合并结果时会自动删除重复项:
TestReport[{r1, r1, r2, r2, r3}]使用 TestReport 收集测试而不进行运算
file = Export[
CreateFile[],
Unevaluated@{TestCreate[Echo[1], Null], TestCreate[Echo[2], Null]},
"WL"
]当对文件运行 TestReport 时,默认情况下会执行所有未运算的测试:
report = TestReport[file]report = TestReport[file, TestEvaluationFunction -> Identity]tests = #["TestCreate"]& /@ report["Results"]现在可以通过释放 HoldForm 来创建测试对象:
Map[ReleaseHold, tests]记录 TestReport 正在执行的操作对于调试代码至关重要. 创建一个运行时间较长的测试套件,该套件可能在运行过程中的某个时刻失败:
tests = Table[
TestCreate[Pause[1]; If[RandomReal[] <= 0.2, Throw[i]], Null, TestID -> i],
{i, 10}
];TestReport[tests]您可以使用 HandlerFunctions 来实时记录所有失败的测试:
TestReport[
tests,
ProgressReporting -> False,
HandlerFunctions -> <|"TestEvaluated" -> Function[If[#Outcome != "Success", Echo[#TestObject, "😵"]]]|>
];TestReport[
Table[TestCreate[RandomInteger[], 1], 3],
ProgressReporting -> False,
HandlerFunctions -> <|"UnhandledEvent" -> Echo|>
];Catch @ TestReport[
Table[TestCreate[RandomInteger[], 1, TestID -> i], {i, 20}],
HandlerFunctions -> <|
"TestEvaluated" ->
Function[If[#Outcome != "Success", Throw[#TestObject]]]|>
]为 TestReport 编写测试文件通常是一个简单的操作. 只需将任何所需的上下文在测试文件的开头加载即可:
Needs["MyContext`"]
TestCreate[MyContext`AddOne[1], 2, TestID -> "MyContext-AddOne-Test"]
TestCreate[MyContext`AddTwo[1], 3, TestID -> "MyContext-AddTwo-Test"]
所有未包含在 TestCreate 中的代码将在每次加载测试文件时执行,即使您未运行测试. 测试文件可以包含测试列表或以编程方式创建测试的表达式:
Needs["MyContext`"]
Table[
TestCreate[
MyContext`AddOne[i],
i+1,
TestID-> "MyContext-AddOne-" <> IntegerString[i]
],
{i, 1, 20}
]
为每个测试分配一个有意义的 TestID 始终是一个良好的习惯.
相关技术笔记
-
▪
- 使用测试笔记本