Testing at Emuzikos: A BDD story
This is a featured guest blog post by Boris Rorsvort. He writes about development on his app Emuzikos – "The first easy way to find local musicians."
A few months ago, when I started using Codeship I didn't realize how more worry-free my designer/developer life could be. I came across Continuous Integration testing a year ago when I started to work on a big social network application (TrustedFamily).
There were already 3 developers working on different features. Due to code security policies we were using Jenkins CI.
Around that time I started to build, as a side project, a musicians searching app called (Emuzikos). As a musician I always thought that musician forums were a pain when it comes to searching for other people and as a designer/developer I found that building an app would be more gratifying and easier to maintain than an constantly outdated portfolio.
Working on a side project also means you have small chunks of time to work on your app. Here more than ever the agile methodology make sense: split your project's tasks into small and isolated ones that match the time frames you're working in.
Ideally you want to test each of these small releases, so when you push your code you make sure you don't break the entire app.
Here is the workflow I've put in place to optimize my output.
The development tools
Spinach, a Cucumber without regex
I recently discovered Spinach: a BDD framework written in pure Ruby that features encapsulation and modularity of your step definitions.
I used to work only with RSpec and steak but felt that I was missing some clarity about what the app is supposed to do at a glance (and other reasons described here). I wanted to switch to a gherkin style integration testing framework.
So for each feature that I build, I write an integration test that describes the big picture. Coming from RSpec you, at first, often tend to replicate the capybara steps in gherkin, which leads to unreadable specs and makes them impossible to transmit to any shareholder or even yourself when you have to fix bugs. It's also very tedious to maintain because you have to change the code at two places each time you change a class or some text.
There is no point to start speaking about technicalities (like clicks, fill-in inputs, …) when you describe a behavior. Let's look at thise example
Bad
Feature: Testimonials
Scenario: Create a new testimonial with valid data
Good
Feature: Testimonials Background
Scenario: Create a new testimonial with valid data
Then you do all the capybara, PhantomJS magic in your steps file. You get the thing …
Zeus
In order to gain some time when writing code that incrementely makes the tests pass, I'm using Zeus to preload the rails environment or more technically: Zeus is a language-agnostic application checkpointer for non-multithreaded applications. That in addition to Livereload is a must!
Continuous Integration: Codeship to speed up Development
As your test suite grows you don't want to wait for all your tests to pass locally before committing something. That's where Codeship becomes a very useful tool.
As you develop a new feature:
git flow feature start awesome_feature zeus start
write your feature specific specs write the code to make the feature specific tests pass
git commit -am "Fix the tests" git flow feature finish awesome_feature // which will nmerge it back to dev git push // make sure develop has a deployment method to a staging server
check if the full test suite passes in codeship and send staging server to user-testing or client for getting feedback and fix the eventual bugs until the tests are all green
git flow release start new_set_of_features // so you get the version tag and all
you can still do some commit at this point
git flow release finish new_set_of_features git push
let the test run on Codeship
let Codeship deploy for you.
grab a beer, celebrate!
Conclusions
Continuous integration really makes it easy to find out which commit broke your app and quickly revert your code to the previous one. Also, If you work using git-flow you can create release branches, test them and deploy them separately, allowing you to make last fixes while other developers can continue working on new stuff.
Suppose you have a full test suite, you get warnings of conflicting changes much more early in the release process. That practically gives you an almost always stable branch for staging demos, releases …
We want to thank Boris for his blog post and are glad he is a happy Codeship users. How do you develop your app? Let us know which services and tools you use to speed up your processes in the comments!
Stay up to date
We'll never share your email address and you can opt out at any time, we promise.