2.5 运行程序
接下来我们实现下一个步骤,编辑 features/step_definitions/calculator_ steps.rb,修改第二个步骤定义如下:
下载first_taste/04/features/step_definitions/calculator_steps.rb
When /^the calculator is run$/ do
@output = `ruby calc.rb #{@input}`
raise('Command failed!') unless $?.success?
end
这段代码试图运行我们的计算器程序calc.rb,同时传入上一个步骤保存下来的输入,并用另一个实例变量保存输出。接下来它检查一个名字很特别的(实际上是很隐晦的)Ruby变量$?,来核实命令是否成功运行了,如果运行失败则抛出一个错误。记住,如果步骤定义抛出一个错误,Cucumber就会将步骤标记为失败,这就是实现这个目的最简单的方法。
这时我们运行Cucumber,应该就能看到它真正去尝试运行计算器了:
Feature: Adding
Scenario: Add two numbers
Given the input "2+2"
ruby: No such file or directory -- calc.rb (LoadError)
When the calculator is run
Command failed! (RuntimeError)
./features/step_definitions/calculator_steps.rb:10
features/adding.feature:5
Then the output should be "4"
Failing Scenarios:
cucumber features/adding.feature:3
1 scenario (1 failed)
3 steps (1 failed, 1 skipped, 1 passed)
0m0.026s
这次步骤失败了,因为我们还没有可运行的calc.rb程序。你应当看到Cucumber在步骤下面将抛出错误所产生的输出都用红色标亮了,这能帮助你定位问题。
你可能会想,明知calc.rb这个文件还不存在,却依然编写代码试图去运行该程序,这样做有点奇怪。我们是故意这么做的,因为我们想确保在深入到解决方法的实现之前拥有一个功能完备的测试。基于这条纪律编写测试意味着我们可以信任测试,因为我们看到这些测试失败了,当测试通过时我们就可以满怀信心地认为任务真的完成了。对于我们所谓的由外向内开发,这种优雅的节奏是其中的重要部分,初看起来这好像有点奇怪,我们希望通过本书展现这种开发方式的一些显著的益处。
由外向内开发还有另外一个好处:在未花任何精力实现计算器之前,我们就有机会从用户角度考虑计算器的命令行接口。而在这个阶段,如果我们意识到接口的一些问题,是非常容易做出改变的。
时间: 2024-10-26 16:31:37