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 …
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 from one day to another. And the latter is exactly what happened. Even if it wouldn’t have: local testing doesn’t work without an internet connection, and your CI builds could break any moment. A recipe for flaky tests.
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.
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
# 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
Add the main domain and all the subdomains you need to your
# /etc/hosts 127.0.0.1 foodlane.test app.foodlane.test ristorante-milano.foodlane.test
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