A month ago, when I started using codeship I didn’t realize how more worry-free my designer/developper life could be. I came across continuous integration testing a year ago when I started to work on a big social network application (TrustedFamily). They were already 3 developpers working on differents features and because of code security policies were using Jenkins CI. Around that time I started to build, as a side project, a musicians searching app (Emuzikos). As a musician I always thought that these musicians forums were a pain when it comes to searching for other people and as designer/developper 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 mean you have small chunks of time to work on your app. Here more than ever the agile methodology make sense: split your projects tasks into some smaller one and isolated one that match the time frames you’re working in.
Idealy you want to test each of these small releases, so that when you push your code you make sure you don’t break the entire app.
So here is the workflow I’ve put in place to optimize my output.
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 rpsec 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.
So there is no point to start speaking about technicalities (like clicks, fill-in inputs, …) when you describe a behaviour.
Then you do all the capybara, phantomjs magic in your steps file. You get the thing …
In order to gain some time when writing code that incrementely make the tests pass, I’using Zeus to preload the rails environement 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 the rescue
As your test suite grows you don’t want to wait all the tests to pass locally before comitting something. So that’s where Codeship becomes a very useful tool.
As you develop a new feature:
- write your feature specific specs
- write the code to make the feature specific tests pass
- check if the full test suite passes in codeship and send staging server to user-testing or client for getting feedback
- fix the eventual bugs until the tests are all green
- you can still do some commit at this point
- let the test run on Codeship.
- let Codeship deploy for you.
- grab a beer, celebrate!
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 realease branches, test them and deploy them separately, allowing you to make last fixes while other developpers 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 …
I could also immagine that at some point, CI could be integrated with some kind of quality tools like Code Climate and make the tests fail if the code quality drops under a certain rating.