跳转到主要内容

Turnt 是一个简单的命令行 expect-style 测试工具

项目描述

小型统一运行器和测试器 (Turnt)

Turnt 是一个简单的快照测试工具,灵感来自 CramLLVM的lit。它适用于测试将文本文件转换为其他文本文件的事物,如编译器。想法是每个测试都是一个输入文件,你想要运行一个命令并检查它是否仍然与保存的输出文件匹配。

使用方法

  1. 配置。 确定您想要测试的命令。创建一个 turnt.toml 配置文件,并在其中放入 command = "mycmd {filename}" 以将每个测试文件作为参数传递给 mycmd
  2. 创建一个测试。 只需在您的 turnt.toml 旁边编写一个输入文件。我们将它称为 foo.t
  3. 拍摄快照。 运行 turnt --save foo.t 来执行 mycmd foo.t 并将标准输出保存到 foo.out。您可能想查看此输出以确保它是您期望的内容。然后您将输入 foo.t 和输出 foo.out 检查到版本控制中。
  4. 测试您的作品。 现在您已经设置了一个测试,继续工作。使用 turnt *.t 来运行所有测试并确认输出是否仍然匹配。如果有不匹配,您可以使用 turnt --diff 来查看更改。(或者如果您有信心,尝试 turnt --save 然后跟 git diff。)

Turnt 的哲学是最大限度地减少编写新测试的努力,这样您可以快速构建大量的测试。您不需要编写任何自定义逻辑来检查结果;您只需为每个测试记录完整的“黄金”输出。

与普通单元测试相比,“快照”测试在事物更改时需要手动检查差异的心理努力。作为回报,它更容易扩展测试覆盖率。快照还充当原始形式的文档,因为每个测试都是您程序的完整、有效输入。

安装

这是一个Python 3工具。使用 pip 安装它

$ pip install --user turnt

或者,如果您想使用 Turnt,可以安装Flit,克隆此存储库,并输入以下命令以获得一个具有符号链接的“实时”安装:

$ flit install --symlink --user

配置

Turnt 在您的测试文件的所有祖先目录中寻找名为 turnt.toml 的配置文件。它可以与测试文件放在一起,或在任何包含目录中。它是一个 TOML 文件,其内容如下:

command = "mycmd {args} < {filename}"
return_code = 42
output.txt = "result.txt"

命令

command 设置为在给定的测试文件上运行的 shell 命令。这是唯一必需的设置。

该命令是一个 模板;Turnt 将填充以下值:

  • {filename}:测试文件的路径,相对于工作目录。
  • {base}:测试文件的基名,不包括扩展名。
  • {args}:测试或用户提供的额外参数。(有关 ARGS: 覆盖和 --args 命令行选项,请参见下文。)

命令的工作目录是配置文件 turnt.toml 的位置,如果有的话。如果没有配置文件,则它是测试文件本身的位置。

返回码

默认情况下,Turnt 期望测试命令成功,即退出状态码为 0。如果您期望失败,请将 return_code 设置为不同的状态码。

输出

默认情况下,Turnt 捕获测试命令的标准输出流。如果您的命令产生其他输出文件“作为副产品”或您想捕获标准错误流,您可以配置 output 表。

output 是从 快照扩展名收集的文件名 的映射。例如,以下 TOML 配置:

output.txt = "result.txt"

意味着运行命令将生成一个名为 result.txt 的文件,我们希望将该文件保存在名为 <test-name>.txt 的快照中。

使用 - 替换文件名以指示命令的标准输出,使用 2 以指示其标准错误。默认行为如下配置:

output.out = "-"

它捕获 stdout 并将其保存在 <test-name>.out 中。在 turnt.toml 中定义 output 将禁用此默认行为;如果您想将其与其他输出一起包含,则可以明确包含它。

二进制

默认情况下,Turnt 在测试文件中查找覆盖(请参见下文)。如果您的测试输入是二进制文件(非文本文件),则这不会起作用(Turnt 将发出警告并继续执行,不执行覆盖)。将 binary = true 设置为完全抑制此覆盖搜索。

输出目录

可选地将预期测试输出放在不同的目录中。默认情况下,这是 .,即预期输出文件与测试文件“相邻”。将此设置为一个相对于测试文件的目录,以将它们保存在其他位置。

待办事项

标记一个测试为允许失败。例如,您可能添加了一个暴露您尚未修复的错误的测试,但您希望您的 CI 保持“绿色”。将 todo = true 设置为允许测试失败;Turnt 将在 TAP 输出中以 # todo 标记它。

针对特定测试的覆盖

有时您需要更改特定测试文件的设置。Turnt 在测试文件本身中查找一些覆盖:例如,您可能将它们放在测试程序顶部的注释中。

将这些内容放入您的测试文件中以覆盖配置:

  • CMD: <command> 覆盖配置中的 command
  • ARGS: <arguments> 向配置命令添加参数。Turnt 将此字符串放在命令使用 {args} 的位置。
  • OUT: <ext> <filename> 覆盖配置中的 output。您可以通过这种方式指定多个文件:每行一个文件。
  • RETURN: <code> 覆盖预期的退出状态。
  • TODO: <true|false> 可以将测试标记为“待办事项”(允许失败)。

多环境

Turnt 主要关于在许多输入文件上运行一个命令。然而,有时你可能需要在每个文件上运行多个命令。这对于 差异测试 特别有用:当你想检查多个事物以相同方式行为时,你可以通过检查它们在给定相同输入时是否产生相同输入来检查。

你可以在配置文件中的 envs 表下创建多个环境。该表将环境 名称 映射到一系列配置选项,这些选项与上面描述的 顶级配置 非常相似。例如

[envs.baseline]
command = "interp -g {filename}"

[envs.optimized]
command = "compile -O3 {filename} ; ./a.out"

每个环境都可以拥有上面描述的全部配置选项:例如,commandoutputreturn_code。当你对某些文件运行 turnt 时,它将在所有文件上运行所有环境。还有一个布尔 default 标志可以默认关闭环境;这样,你只能通过使用 -e 标志来请求它(见下文)。

这个示例是一个差异测试设置,因为这两个环境共享同一个(默认)快照文件:一个测试 foo.t 将在其 foo.out 中查找其 stdout 快照。如果这两个环境不匹配,至少有一个会失败。如果你想要更标准的(非差异)设置,只需为两个环境分别设置不同的 output 配置,如下所示

[envs.interp]
command = "interp -g {filename}"
output.res = "-"

[envs.profile]
command = "profile {filename}"
output.prof = "-"

目录测试

Turnt 测试通常只是一个输入文件,但你也可以将多个相关文件组织到一个目录中。使用目录的方式与单个文件相同:将路径传递给 turnt 命令,该路径将作为配置命令的 {filename} 出现。因此,你可能这样配置测试命令

command = "mycmd {filename}/test.c"

如果你想让每个测试目录都包含一个名为 test.c 的文件。

Turnt 将快照放在测试目录 内部 而不是旁边。它在那个目录中命名它们为 out.<extension>

有两个仅用于处理目录测试的配置选项

  • out_base。目录测试中输出文件的基准名称:默认为 out
  • opts_file。在目录测试内部读取的文件名,用于搜索嵌入式覆盖。在我们上面的例子中,你可以将其设置为 test.c 以在该文件中查找 ARGS: 和其他内容,或者设置为 opts.txt 以在旁边单独的文件中查找它们。

命令行界面

在运行和更新测试时,你将需要的最常见的 turnt 命令行选项如下

  • --save:将每个测试的当前输出视为“正确的”输出,并将其保存到你想要检查到版本控制中的输出文件。
  • --diff:显示每个测试的实际输出和预期输出之间的差异。(差异输出到 stderr,而 TAP 结果保持在 stdout。)

你可能还会喜欢

  • --parallel-j:使用并行线程更快地运行你的测试。

这些选项在处理特定测试文件时很有用

  • --verbose-v:禁用 Turnt 的默认行为,它会抑制测试命令的 stderr 输出。结果是更有帮助但更难阅读。
  • --print-p:不是检查测试结果,而是直接运行命令并显示输出。这在与 -v 结合使用时非常有用(特别是在交互式迭代测试时)。
  • --args-a:覆盖测试命令中的 {args} 字符串。

这些选项让你可以在不同的测试环境之间切换

  • --env-e:为要运行配置的 环境 提供名称。使用此选项多次以运行多个环境。默认情况下,Turnt 为每个测试运行所有配置的环境。使用特殊名称 default 作为顶级、未命名的测试环境。
  • --config-c:查找此配置文件名,而不是默认的 turnt.toml

TAP

Turnt 以机器可读的 TAP 格式输出结果。为了使输出更易于阅读,可以将它通过管道传输到类似 tap-difflettap-dotfaucet 的工具。

$ npm install -g tap-difflet
$ turnt *.t | tap-difflet

致谢

Turnt 由 Adrian SampsonAlexa VanHattum 创建。我们为在 Capra 中测试各种研究编译器而创建它。该许可证为 MIT

由以下机构支持