Rails port of testing environment

后端 未结 2 331
再見小時候
再見小時候 2021-01-18 17:49

I\'d like to test the HTTP API of our Rails app using Faraday and RSpec. Faraday needs the host url + port. Unfortunately the port of the testing environment does always cha

相关标签:
2条回答
  • 2021-01-18 18:35

    There's probably more than one way to do this, but this is working for me right now:

    The command

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

    Note that you'll have to do this at some point after the app has loaded - i.e., you can't use this in your environment.rb or application.rb file.

    The explanation

    Basically what this command does is as follows:

    • lsof is the Unix command for LiSt Open Files
    • -p #{Process.pid} limits it to the current process (i.e., your test web server instance)
    • -ai TCP limits it to "files" of type TCP (i.e., open TCP ports). (Note: the -a is to make it AND the search with the pid one - the default, using just -i would OR the search)
    • -as TCP:LISTEN limits to just TCP ports that are being listened on (as opposed to any open port - like your app's connection to Postgres for example)
    • -Fn tells it to only output the "name" column, which in this case will be the IP/port that is being listened on

    The output of that part by itself will be something like this:

    p12345
    n*:5001
    n*:5001
    

    The first line, starting with p is the process ID. There's no way to suppress this. The next 2 lines (not sure why it can output multiples, but we'll take care of it in a minute) are the "name" column (hence n), followed by the IP + port. In our case (and I imagine yours as well, in a test environment), the web server listens on all available local IPs, thus *. Then it tells us that the port is, in this case 5001.

    Finally, we pipe it through... * grep ^n to eliminate the first line (the process id) * cut to say "cut from columns 4 on" - i.e., remove the n*: to return just the port, and * uniq to just get the one instance

    (It will also have a trailing newline, thus the strip call.)

    The usage

    In my case, I'm using this in my Cucumber env.rb thusly, to reconfigure the URL options for ActiveMailer so my email links get generated properly as working links in test:

    port = 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

    No doubt you could do the same thing in a helper/config for Rspec as well.

    0 讨论(0)
  • 2021-01-18 18:38

    If using Capybara you can set the port in the spec_helper.rb like so:

    Capybara.server_port = 1234
    

    See also: https://github.com/jnicklas/capybara/pull/123

    0 讨论(0)
提交回复
热议问题