In Recipe 10 of the book, we show you how to set up your own Jenkins continuous integration server to run Cucumber every time you push your latest code changes. Jenkins is of course not the only CI option out there. The CruiseControl family, just to name one, can do a lot of the same things.
You also have the option of using a hosted service such as Travis CI or Codeship, where the vendor takes care of maintaining the server for you. These are a nice, low-hassle way to get started with CI.
In this recipe, we’re going to show you how to get started with Cucumber on the Codeship hosted Continuous Integration service.
Here’s how the app works: when you leave the house in the morning, you ping OTD from your smartphone (preferably automatically), and OTD in turn notifies Beeminder how many minutes early or late you are. If you start to miss your target repeatedly, Beeminder’s incentives kick in.
With such a simple app, the Cucumber test practically writes itself. In your project directory, create a file called
features/otd.feature with the following contents:
Feature: Time logging Scenario: Leaving Given I want to leave at 8:00 When I leave at 8:17 Then I am 17 minutes late
Eventually, we’ll test this app through its web interface. But just for the purposes of getting started with Codeship, let’s start with simple math on the departure times.
The Step Definitions
features/step_definitions/otd_steps.rb, and add the following step definitions to it:
require 'time' Given(/^I want to leave at (\d+:\d+)$/) do |time| @desired = Time.parse time end When(/^I leave at (\d+:\d+)$/) do |time| @achieved = Time.parse time end Then(/^I am (\d+) minutes late$/) do |minutes| late = (@achieved - @desired) / 60.0 late.should be_within(0.001).of(minutes.to_f) end
This code is Ruby-agnostic, but we’ll be giving the examples here using JRuby. Install Cucumber and make sure the feature passes:
$ jruby -S gem install cucumber rspec-expectations $ jruby -S cucumber .... 1 scenario (1 passed) 3 steps (3 passed) 0m2.350s
Once that’s working, it’s time to create your project on Codeship.
Getting Started with Codeship
You can create an account on Codeship with your existing GitHub or Bitbucket credentials, or with an e-mail address and password. Once you’ve done so, they’ll lead you to the new project page:
Codeship needs to know where to get the source code for your app. Head over to GitHub or Bitbucket and create a blank repository. Then, click the corresponding button on the Codeship new project page and choose the repo you just created.
Once you’ve created your project, you need to tell Codeship how to test it. Codeship uses the familiar Ruby Version Manager to choose Ruby implementations, so all you need to do is tell their server to make sure JRuby is installed.
In the Test tab of the user interface, leave the default technology stack set to “I want to create my own custom commands.” Then, enter the following text into the Setup Commands window:
rvm install jruby-1.7.8 rvm use jruby-1.7.8 jruby -S gem install cucumber rspec-expectations
Further down the page, in the Test Commands, window, type:
jruby -S cucumber
Now, when you save your project, Codeship will prompt you to complete the setup by adding a hook to your project:
Follow the on-screen instructions to configure Github or Bitbucket to use the Codeship hook.
On your local machine, commit your project to Git and push it up to the server, so that Codeship can see it:
git init git add features git commit -m "Initial commit" git remote add origin git@...:username/otd.git
As soon as you push the project, Codeship will grab the latest version and run your Cucumber features:
Congratulations! You’ve created your first passing Codeship integration.
Now that we have a running project, what do we do? There are several ways we could improve this project:
- Switch to Bundler for managing our gems
- Add the actual app code to the project
- Replace the pure-math step definitions with real ones that drive our app over HTTP
- Use Heroku to deploy the app
In a future post, we’ll tackle a few of these tasks.
This release includes two new recipes and a new appendix:
- “Test Android Apps With Calabash” demonstrates using Cucumber to drive an Android application.
- “Define Steps as Regular Ruby Methods” shows you a way to declutter your step definitions and make your tests more maintainable.
- “RSpec Expectations” gives you a quick overview of writing good pass/fail assertions using RSpec Expectations, the assertion framework we use most heavily in the book.
We’ve also substantially updated “Test .NET Code Using Cucumber Syntax” and “Drive a Windows App Using White” to use Visual Studio Professional and the NuGet package manager.
This release includes two new recipes:
- “Drive a Flash App Using Cuke4AS3” walks you through setting up the environment for testing Flash apps.
- “Manipulate Time” shows you a couple of different ways to make your tests faster by speeding up the clock.
We’ve also substantially updated one recipe:
- “Test On iOS Using Frank” now covers the new version of the Frank toolkit, which is now much more automated and primarily command-line-driven. Thanks to Pete Hodgson, the creator of Frank, for taking the time to walk us through what’s new.
Are there any Cucumber techniques you’d like to see covered in the book? These could be tricks you’ve discovered, tasks you’ve always wondered how to perform, or follow-ons for specific recipes.
- A discussion of the Page Objects technique as it applies to web testing
This release includes two new recipes:
- “Test a Grails App Using grails-cucumber” shows you how to get started testing a Grails app by plugging Cucumber into Groovy
- “Test Scala Code” demonstrates driving a Scala library from Cucumber using Cucumber-JVM
This new release includes two new recipes:
- “Test Through Multiple Interfaces Using Worlds” explains how to drive both your GUI and your API from the same set of Cucumber features
We’ve also added a little real-world advice to our recipes on HTML tables and Sikuli. Thanks to readers Dean Cornish and Chuck van der Linden for weighing in on these topics in the forums.
You can test just about anything with Cucumber—we certainly have! See how to test desktop, web, mobile, and server applications across a variety of platforms. We’ll arm you with ready-rolled solutions to real-world problems: your tests will run faster, read more clearly, and work in any environment.
See below for the table of contents, or read the Pragmatic Programmers release announcement for more information.
Table of Contents
- Compare and Transform Tables of Data
- Generate an RTF Report With a Custom Formatter
- Run Slow Setup/Teardown Code With Global Hooks excerpt
- Refactor to Extract Your Own Application Driver DSL
- Compare Images
- Test Across Multiple Cores
- Test Across Multiple Machines With SSH
- Run Your Features Automatically With Guard and Growl
- Add Cucumber To Your Continuous Integration Server
- Publish Your Documentation on Relish
- Drive Cucumber’s Wire Protocol
- Implement a Wire Protocol Listener
- Use Cucumber Directly With JRuby
- Use Cucumber With Java Via Cucumber-JVM excerpt
- Drive a Spring Model
- Drive Hibernate Persistence
- Drive a Grails Appa
- Test Scala Code
- Test Clojure Code
- Drive a Swing Interface With Marathon
.NET and Windows
- Get Good Text Output On Windows
- Test .NET Code Using Cucumber Syntax
- Drive a Windows App Using win_gui
- Drive a Windows App Using White
Mobile and Web
- Test On iOS Using Frank
- Test On Android
- Test Across Multiple Mobile OSes With Calabash
- Test On Windows Phone
- Parse HTML Tables excerpt
- Test a Web App Using Watir
- Test a PHP App With cuke4php
- Play Back Canned Network Data Using VCR
- Drive a Flash App Using Cuke4AS3
- Monitor a Web Service Using Nagios and Cucumber
Other Languages and Platforms
- Drive a Mac GUI Using AppleScript and System Events
- Drive a Mac GUI Using MacRuby and AXElements
- Test Python Code Using Lettuce
- Test Erlang Code
- Test Lua Code Using cucumber-lua
- Test a GUI on Linux, Mac, or Windows With Sikuli
- Test an Arduino Project Using Serial