编写测试#
测试对于提高程序的质量和可维护性很重要。它们验证程序的行为,也作为规范,以避免随时间的推移出现退步。
MoonBit 提供测试支持,使编写测试更加简单和容易。
测试块#
MoonBit 提供测试代码块,用于编写内联测试用例。例如:
test "test_name" {
assert_eq!(1 + 1, 2)
assert_eq!(2 + 2, 4)
inspect!([1, 2, 3], content="[1, 2, 3]")
}
测试代码块本质上是一个返回 Unit
抛出 String
的函数。它在执行 moon test
期间被调用,并通过构建系统输出测试报告。assert_eq
函数来自标准库;如果断言失败,它会打印错误消息并终止测试。字符串 "test_name"
用于标识测试用例,是可选的。
如果测试名称以 "panic"
开头,表示测试的预期行为是触发 panic,只有在触发 panic 时测试才会通过。例如:
test "panic_test" {
let _ : Int = Option::None.unwrap()
}
快照测试#
在指定预期值时,编写测试可能会很繁琐。因此,MoonBit 提供了三种快照测试。所有这些都可以使用 moon test --update
自动插入或更新。
快照 Show
#
我们可以使用 inspect!(x, content="x")
来检查实现了 Show
特征的任何内容。正如我们之前提到的,Show
是一个可以派生的内建特征,提供了 to_string
来打印数据结构的内容。标记参数 content
可以省略,因为 moon test --update
会自动插入:
struct X { x : Int } derive(Show)
test "show snapshot test" {
inspect!({x: 10}, content="{x: 10}")
}
快照 JSON
#
派生的 Show
特征的问题是它不能对输出进行格式化,导致输出非常长。
解决方案是使用 @json.inspect!(x, content=x)
。其好处是生成的内容是一个 JSON 结构,在格式化后更易读。
enum Rec {
End
Really_long_name_that_is_difficult_to_read(Rec)
} derive(Show, ToJson)
test "json snapshot test" {
let r = Really_long_name_that_is_difficult_to_read(
Really_long_name_that_is_difficult_to_read(
Really_long_name_that_is_difficult_to_read(End),
),
)
inspect!(
r,
content="Really_long_name_that_is_difficult_to_read(Really_long_name_that_is_difficult_to_read(Really_long_name_that_is_difficult_to_read(End)))",
)
@json.inspect!(
r,
content={
"$tag": "Really_long_name_that_is_difficult_to_read",
"0": {
"$tag": "Really_long_name_that_is_difficult_to_read",
"0": {
"$tag": "Really_long_name_that_is_difficult_to_read",
"0": { "$tag": "End" },
},
},
},
)
}
也可以实现自定义 ToJson
来保留必要的信息。
快照任何内容#
有时我们不仅要记录一个数据结构,还要记录整个过程的输出。
可以使用完整的快照测试使用 @test.T::write
和 @test.T::writeln
记录任何内容:
test "record anything" (t : @test.T) {
t.write("Hello, world!")
t.writeln(" And hello, MoonBit!")
t.snapshot!(filename="record_anything.txt")
}
这将在该包的 __snapshot__
下创建一个具有给定文件名的文件:
Hello, world! And hello, MoonBit!
这也可以用于测试应用程序的输出,无论是创建图像、视频还是一些自定义数据。
黑盒测试和白盒测试#
在开发库时,验证用户是否可以正确使用它是很重要的。例如,可能会忘记使类型或函数公开。这就是为什么 MoonBit 提供了黑盒测试,允许开发人员了解其他人的感受。
只能访问包中所有成员的测试称为白盒测试,因为我们可以看到一切。这样的测试可以内联定义,也可以在文件中定义,文件名以
_wbtest.mbt
结尾。只能访问包中公共成员的测试称为黑盒测试。这样的测试需要在文件中定义,文件名以
_test.mbt
结尾。
白盒测试文件(_wbtest.mbt
)导入包配置(moon.pkg.json
)中的 import
和 wbtest-import
部分定义的包。
黑盒测试文件(_test.mbt
)导入当前包和包配置(moon.pkg.json
)中的 import
和 test-import
部分定义的包。