— Aug 29, 2015
An indispensable tool of web development is the ability to drive a browser for automated feature testing. In Ruby, we tend to reach for Capybara (a test framework) and Poltergeist (a PhantomJS driver). Regardless of what tool you choose, browser-driven feature tests are a great way to ensure the expected behavior of your apps. Let’s do that in Elixir.
TL;DR Check out this example of how one might configure Hound to run browser-driven feature tests in Elixir.
On such tool in the Elixir ecosystem, is Hound. Much like Capybara, Hound is a test framework which provides an interface for using a webdriver to test the behavior of pages. Also like Capybara, it does not make any assumption about the driver you wish to use. Instead you must configure it to use the driver of your choice, such as Selenium, ChromeDriver, or PhantomJS. Since we’re familiar with PhantomJS (and love the headless nature of it), we’ll go with that!
The truth is Akash Manohar has already written an excellent blog post about configuring Hound to work with Phoenix, so I won’t rehash that here. Go read this blog! Instead, I will hit the highlights and emphasize the particulars that tripped me up.
First, if you haven’t already, you will need to install PhantomJS. If you’re on a Mac, this is probably easiest done with Homebrew. From the command line:
The successful completion of that command should add a phantomjs
command to your path.
Finally, in order to actually run the tests YOU MUST START THE WEBDRIVER.
A lot of time was wasted trying to figure this out.
In Ruby with Poltergeist, this step is not necessary as that gem manages the phantomjs
process for you.
The easiest way to start PhantomJS is:
This starts PhantomJS as a webdriver (without the --wd
option, it starts in interactive mode).
As you can see the driver runs on it’s default port 8910
which is conveniently configured by default in Hound.
Basically, it isn’t great having to remember to start PhantomJS before running your tests. With a small Bash script, we can make sure it’s running every time we run our tests.
This will start PhantomJS before running mix test
.
The trap
ensures that PhantomJS is stopped when the script exits (or is terminated).
You might drop this in your ./bin/
directory and then a full test run is as easy as bin/test
.
You may have noticed --include feature
above.
Using the technique from my previous post you can configure ExUnit to exclude tests tagged with :feature
by default.
That way tests depending on the webdrive don’t fail when you run mix test
alone.
This option will then ensure that feature tests are included when you run bin/test
.
I put together an example application implementing all these ideas. Check it out: https://github.com/iamvery/hound-example.
One other thing I want to note is that perhaps Hound (or some other small library) could/should manage the phantomjs
process itself.
I haven’t given this a try yet, but it sounds like a good challenge!