Rails测试环境端口

Zar*_*doz 4 port rspec ruby-on-rails

我想使用Faraday和RSpec测试我们的Rails应用程序的HTTP API.法拉第需要主机网址+端口.不幸的是,测试环境的端口总是会改变.如何在规范中以编程方式访问当前端口?

fpa*_*ser 9

如果使用Capybara,您可以在spec_helper.rb中设置端口,如下所示:

Capybara.server_port = 1234
Run Code Online (Sandbox Code Playgroud)

另见:https://github.com/jnicklas/capybara/pull/123


JKu*_*cki 5

可能有不止一种方法可以做到这一点,但这现在对我有用:

命令

port = `lsof -p #{Process.pid} -ai TCP -as TCP:LISTEN -Fn | grep ^n | cut -c 4- | uniq`.strip
Run Code Online (Sandbox Code Playgroud)

请注意,您必须在应用程序加载后的某个时刻执行此操作 - 即,您不能在您的environment.rbapplication.rb文件中使用此操作。

说明

基本上这个命令的作用如下:

  • lsof是列出打开文件的 Unix 命令
  • -p #{Process.pid}将其限制为当前进程(即您的测试 Web 服务器实例)
  • -ai TCP将其限制为 TCP 类型的“文件”(即打开的 TCP 端口)。(注意:是-a使其pid 进行搜索 - 默认情况下,使用 just -iwill OR搜索)
  • -as TCP:LISTEN仅限于正在侦听的 TCP 端口(而不是任何开放端口 - 例如您的应用程序与 Postgres 的连接)
  • -Fn告诉它只输出“名称”列,在本例中将是正在侦听的 IP/端口

该部分本身的输出将如下所示:

p12345
n*:5001
n*:5001
Run Code Online (Sandbox Code Playgroud)

第一行以 开头,p是进程 ID。没有办法抑制这种情况。接下来的 2 行(不确定为什么它可以输出多个,但我们会在一分钟内处理它)是“名称”列(因此n),后面是 IP + 端口。在我们的例子中(我想你的情况也是如此,在测试环境中),Web 服务器侦听所有可用的本地 IP,因此*. 然后它告诉我们端口在本例中是 5001。

最后,我们通过管道... *grep ^n消除第一行(进程 ID) *cut表示“从第 4 列剪切” - 即,删除 来n*:返回端口,并且 *只获取一个实例uniq

(它还会有一个尾随换行符,因此是strip调用。)

用途

就我而言,我在 Cucumber 中使用它env.rb来重新配置 ActiveMailer 的 URL 选项,以便我的电子邮件链接在测试中正确生成为工作链接:

端口= lsof -p #{Process.pid} -ai TCP -as TCP:LISTEN -Fn | grep ^n | cut -c 4- | uniq.strip

MyApp::Application.configure 执行 config.action_mailer.default_url_options[:host] = "0.0.0.0:#{port}" end

毫无疑问,您也可以在 Rspec 的帮助程序/配置中执行相同的操作。