Rails端口测试环境

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

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

Capybara.server_port = 1234 

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

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

命令

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

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

说明

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

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

该部分的输出本身就是这样的:

 p12345 n*:5001 n*:5001 

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

最后,我们管它通过… * grep ^n消除第一行(进程id)* cut来说“从第4列上切下” – 即删除n*:只返回端口,和* uniq只获得一个实例

(它也会有一个尾随的换行符,因此脱strip调用。)

用法

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

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

MyApp :: Application.configure do config.action_mailer.default_url_options [:host] =“0.0.0.0:#{port}”end

毫无疑问,你也可以在Rspec的helper / config中做同样的事情。