我正在构建一个Ruby命令行程序,并使用Cucumber和Aruba来测试它。 Aruba包含一些非常方便的匹配器,所以我可以在.feature
文件中用几行测试输出:
When I run `myprogram`
Then it should pass with:
"""
my program output
"""
问题是我的程序可能包含数十行甚至数百行输出;将所有内容放在.feature
文件中将使得阅读和导航变得更加困难(并且有点令人讨厌)。在这种情况下测试输出的推荐方法是什么?
答案 0 :(得分:7)
简短的回答是:你不应该这样做。
黄瓜测试应该是面向用户和可读的。他们描述了特征。如果错误输出与字节的某个已知值字节匹配,则用户不会关心。
你需要问问自己:我在测试什么?答案是错误信息吗?可能不是。您正在测试应用程序中的某些功能。如果您真的想确保它失败,那么您在Cucumber场景中想要的是以下几行:
Then the exit status should not be 0
这假设脚本遵循标准惯例,即非零退出状态表示错误。
如果您的方案要求输出中有某条消息,您可以添加它:
Then it should fail with
"""
Some error message
"""
但这不一定是整个输出,只是部分匹配。 (请注意,在aruba中定义了“它应该完全失败:”,但我不建议使用它。)
编辑:您已将示例更改为测试通过而非失败,但我的基本建议是相同的:
答案 1 :(得分:2)
要测试您的程序,您有两个选择:
仅检查邮件的相关部分(您实际要通过此测试检查的内容)。 Aruba有built-in stepdef因为它很容易
检查完整消息。如果消息很短,您可以使用Aruba的built-in stepdef。但是,如果消息很长,您可能希望将其放在单独的文件中。由于Aruba不包含此类方法,您应该自己编写此步骤。
看起来像:
# Require aruba/api before that
Then /^it should (pass|fail) with message from file "(.*)"$/ do |pass_fail, filename|
exact_output = File.read(filename)
Aruba::API::assert_exit_status_and_output(pass_fail == "pass", exact_output, true)
end
如果您想编写大量测试并且许多消息类似,那么最终可能会出现大量WET消息。断言完整的消息将使支持测试变得更加困难。
因此,您可能希望使用某种模板引擎来断言这些消息以进行DRYer测试。
你可以用不同的方式设计你的测试 如果您只使用第一种方法,那么您的测试可能找不到一些回归错误,因为它们不会测试所有内容。如果您使用第二种方法,如果消息之间存在大量重复,则支持它们可能要困难得多。
因此,在这两个选项之间存在权衡。通常你用方法1构建一些测试,用方法2构建另一个测试。你应该考虑在你的情况下哪个更好。我不知道任何黄金法则。
答案 2 :(得分:0)
数百个输出在应用程序中并不令人惊讶。是的,你需要让它们易于阅读。如果您不能在Cucumber功能文件中执行此操作,我担心没有更好的替换位置。毕竟Cucumber都是简单的英语,并作为现场文档。
您只需要整理它们。以下是一些基本提示,以防您忽略它们。
仅针对.feature
个文件编写涵盖一个主题的特定功能。虽然我知道您提到的When I run my program
仅用于演示目的,但这样的广泛主题是不可接受的。
将.feature
个文件放入features/
文件夹。并且,如有必要,进一步将它们拆分为子文件夹,如features/user/user_login.feature
。
使用Scenario Outline
和Examples
在一个场景中组织类似的输出。这些示例将有行清楚地表示它们中的每一个。
希望这些帮助。
答案 3 :(得分:0)
我会推荐以下内容:
When I run `my_app`
Then the exit status should not be 0
And the output should contain:
"""
some output
"""
这样,只要从程序中输出“some output”,测试就会通过,但附加输出会被忽略,你的测试不需要输出所有输出。
如果你想一步断言所有这一切,那就自己动手吧,虽然我觉得这更清楚。