我正在使用Frank进行iOS测试。这是一颗红宝石宝石,也使用了Cucumber。我有一个"给定"步骤,检查应用程序是否正在运行或是否崩溃。如果我的步骤发现它崩溃了,我想再次启动该应用程序。我使用一个shell脚本启动该应用程序,该脚本存储在cucument.feature文件附近。
如何根据该步骤定义调用脚本?
你可以用几种不同的方法
Kernel.system "command"
%x[command]
`command`
正如其他答案所建议的那样,有很多从Ruby执行shell脚本的方法,但它们的创建并不相同。我会更详细地解释我所知道的所有方法。
Backticks
`command arg1 arg2`
%x(command arg1 arg2)
在子shell中运行命令并返回命令的输出。命令及其参数以字符串形式提供,该字符串由反引号分隔。另一种语法是%x(...)
,它用于避免转义问题,例如,当您想要执行包含backticks本身的命令时。括号可以替换为其他分隔符,如[]
、{}
、!!
…,以便能够解决任何转义问题。
标准错误正常打印,标准输出被抑制。返回命令的stdout输出。这意味着您可以使用反勾号表示法将命令的输出转换为变量以进行进一步处理。
Kernel.exec
exec("command arg1 arg2")
exec("command", "arg1", "arg2")
通过运行命令替换当前进程。命令及其参数以普通字符串或逗号分隔的字符串列表的形式提供。如果您已经有一个数组形式的参数列表,这可能很有用。输出保持原样,即将打印到控制台,就像直接运行命令一样。
内核系统
system("command arg1 arg2")
system("command","arg1 arg2")
类似于Kernel.exec
,但再次在子shell中运行。如果进程正确退出(状态0),则返回true
,否则返回false
。这在if
-语句中非常有效。
Kernel.spawn
pid = spawn("command")
# do other stuff
Process.wait(pid)
类似于Kernel.system
,但会生成一个子进程来运行指定的命令。因此,除非使用Process.wait
,否则父进程将不会等待命令完成执行。返回值是派生进程的PID。
IO.popen
io = IO.popen("command")
IO.popen("command") {|io| ... }
再次在子进程中运行该命令,但允许对IO进行更大的控制。子进程的stdout和stdin连接到一个IO对象,该对象可以作为返回值或块参数访问。如果通过返回值获得,则IO对象应在与io.close
一起使用后关闭。
Open3
对于比system
或IO.popen
更高级的用例,可以使用Ruby标准库中的Open3。它的popen3
方法允许您手动与子进程的stdin、stdout和stderr交互。Open3的popen2
方法是相同的,只是它没有给您stderr。使用popen2
:的示例
require 'open3'
Open3.popen2("wc -c") do |stdin, stdout, status_thread|
stdin.print "answer to life the universe and everything"
stdin.close
p stdout.gets #=> "42n"
end
这里有一些不错的方法。蜱虫可能是侵入性最小的。但是要注意:正如tadman所指出的,exec
终止了调用进程,这可以通过创建子进程或使用system
来避免。