I’ve been tinkering with Elixir and Phoenix a bit recently. I really like the language (it’s the first time since Ruby that a new (to me) language has seemed this much fun) and Phoenix seems like a rock solid framework, but I was interested in what the surrounding ecosystem was like compared to the much more mature Ruby/Rails landscape. This was just a tyre-kicking exercise – I only really took each tool as far as making sure I could install it and do the basics. Incidentally, a great place to find popular Elixir resources is Awesome Elixir.
The app I started creating (which does virtually nothing!) is on github, and here are some brief notes of the stuff I tried out:
BDD executable specifications
Ruby equivalent: Cucumber
White Bread (because that’s what you make cucumber sandwiches with) is a Gherkin parser/runner. It works in much the same way as Cucumber.
It took me a bit of fiddling to get it working with Phoenix, but nothing too difficult. According to the docs it should generate a sample context (equivalent to a Cucumber step definitions file) when you first run it, but that failed. Once I’d copied the example from the docs though, it worked fine.
The most obvious difference in the steps is that they operate (as you would expect) in a functional style, passing the context from one step to the next rather than relying on shared state. This is actually quite nice, as it makes it very clear what data is being passed between steps.
Test data creation
Ruby equivalent: Factory Girl
Completely painless to install and get started with, and seems to work very much like Factory Girl (although I only scraped the surface).
Blacksmith is another option, which I didn’t investigate.
Ruby equivalent: Capybara
First I tried TucoTuco (apparently it’s an animal similar to a capybara). The first problem I had was that Webdriver (a dependency) failed to compile under Elixir 2.2, so I had to drop back to Elixir 1.1.1 (I raise an issue against the project, and got a quick reply saying it’ll be fixed soon). I also had to explicitly add ibrowse as a dix dependency, as it seems to only be available from GitHub, not hex. I found TucoTuco’s documentation to be a bit sketchy, and never quite got it working with Phoenix.
Switching to Hound, I found the documentation to be much better. It still uses webdriver, so had the same compatibility issue as TucoTuco, but not ibrowse.
One difference compared with Capybara is that you need to manually start phantomjs (
phantomjs --wd), rather than it being started for you. It should be easy enough to wrap it in an Elixir application, but I haven’t tried that yet.
Elixir version management
Previously I’d just been using the latest version of Elixir from Homebrew, but having to downgrade because of the webdriver incompatibility set me looking for a version manager. Exenv follows the philosophy of rbenv rather than rvm, is dead simple to install and use, and just keeps out of your way and works flawlessly.
Pretty similar to RSpec. Includes the same kind of matchers, mocking, stubbing etc.
Ruby equivalent: Rubocop
The docs a bit out of date, but otherwise works more-or-less as expected, failing the build if the rules you specify are broken. I suspect it doesn’t have quite the range of rules or configurability as rubocop (yet).
If you just want gentle style suggestions rather than enforcement, consider Credo instead (which I didn’t try).
Ruby equivalent: Slim
Works as expected. Seems to show up on Mix as phoenix_slim too, which is the one I specified. Might have been renamed to phoenix_slime? Who knows?
Ruby equivalent: Simplecov
Coverage is built into exunit and espec, using Erlang’s cover tool:
mix espec --cover
The output’s not great though, so enter Coverex, which produces output much more like simplecov’s.
Unfortunately both tools seem to mark things like
use statements within
defmodule blocks as uncovered, which leads to misleadingly low coverage scores. I can’t see any obvious way to have it fail the build on low coverage either. In ruby I normally fail if any line is uncovered (if you’re test-driving the code, that’s never going to happen, right?), so that’s two reasons I can’t do the same thing in Elixir.
This is built into IEx. In your code, do:
Make sure you start the server attached to an IEx session:
iex -S mix phoenix.server