How to test your Rails app with subdomains the easy way
When you look for ways to test your Ruby on Rails app that uses (wildcard) subdomains, you are usually told to use lvh.me
or similar domains as your host. These services resolve all subdomains you throw at them to localhost. Problem solved, right? Well, not really …
The problem
First, I’ve always wondered how anyone could feel good about relying on an external service for that. Especially one that no one knows anything about. It could either change the way things work, have network issues, or just shut down anytime. Even if not: local testing doesn’t work without an internet connection, and your CI builds can break any moment. A recipe for flaky tests.
The solution
Luckily there is a simple solution: Just use your hosts
file to resolve the needed subdomains back to localhost. But what if I have wildcard subdomains you might ask? There is no way to add these to the hosts
file, but you don’t need to do that anyway. I would argue that you only need to test a limited number of subdomains to make sure things work as expected.
Rails setup
Alright, let’s assume our app sits on foodlane.io. For testing we will make that foodlane.test
. (For some time Safari didn’t set cookies for .test
domains, but that seems to be fixed now. A workaround was to use .local
.)
# development.rb
config.hosts << 'foodlane.test'
config.hosts << /[a-z0-9-]*\.foodlane\.test/
# test_helper.rb
# ...
class ActiveSupport::TestCase
# ...
Capybara.app_host = 'http://foodlane.test'
end
Hosts file
Add the main domain and all the subdomains you need to your /etc/hosts
file
# /etc/hosts
127.0.0.1 foodlane.test app.foodlane.test ristorante-milano.foodlane.test
CI
On your CI server it works exactly the same way. Just add the necessary domains to the hosts
file before running your tests.
My Github Actions file looks like this:
# ci.yml
# ...
- name: Add hosts to /etc/hosts
run: |
echo "127.0.0.1 foodlane.test" | sudo tee -a /etc/hosts
echo "127.0.0.1 app.foodlane.test" | sudo tee -a /etc/hosts
echo "127.0.0.1 ristorante-milano.foodlane.test" | sudo tee -a /etc/hosts
- name: Run system tests
run: bin/rails test:system