Getting Started With BDD With Calabash and Specta (Part 1)

So if you are anything like me, you may have noticed whenever you create a new Xcode project you get an associated Test folder with it’s own scheme. You may have even opened up a few of the test files and seen something like this.

 

#import <UIKit/UIKit.h>
#import <XCTest/XCTest.h>

@interface QuizTests : XCTestCase

@end

@implementation QuizTests

- (void)setUp {
    [super setUp];
    // Put setup code here. This method is called before the invocation of each test method in the class.
}

- (void)tearDown {
    // Put teardown code here. This method is called after the invocation of each test method in the class.
    [super tearDown];
}

- (void)testExample {
    // This is an example of a functional test case.
    XCTAssert(YES, @"Pass");
}

- (void)testPerformanceExample {
    // This is an example of a performance test case.
    [self measureBlock:^{
        // Put the code you want to measure the time of here.
    }];
}

@end

You may have even hit ⌘+U to run the tests, the problem I often face is know what test to write first. You know you should test but it is just so hard to get started writing the first test, and the next one, and the next one.

Developers often have trouble knowing where to start or what tests they should write next.
– BDD in Action: Behaviour-Driven Development for the whole software lifecycle.

So you just start writing the code and hoping that inspiration will hit you and you can start writing some tests to validate your newly created code functions as it should. Behaviour-Driven Development (BDD) helps to focus you on the way you write tests. In fact the first cultural difference, you’re not writing tests, you’re validating behaviours.

Don’t write automated tests, write executable specifications.
– BDD in Action: Behaviour-Driven Development for the whole software lifecycle.

This seemingly small detail is key in understanding BDD and helping guide you on what behaviour you should write to validate the workings of your application. BDD builds upon Test-Drive Development, taking the good habits of the best practitioners of TDD. To me BDD feels like a natural evolution to TDD, as you build your effectiveness as a TDD practitioner you naturally progress to BDD. BDD was invented by Dan North in response to his frustration of TDD.

 The deeper I got into TDD, the more I felt that my own journey had been less of a wax-on, wax-off process of gradual mastery than a series of blind alleys. I remember thinking “if only someone had told me that!” far more often than I thought “Wow, a door has opened.” I decided it must be possible to present TDD in a way that gets straight to the good stuff and avoids all the pitfalls.
– Introducing BDD, Dan North (http://dannorth.net/introducing-bdd/)

This blog post is a practical demonstration of BDD using Calabash and Specta. Using a basic iOS application taken from the book iOS Programming: The Big Nerd Ranch Guide (4th Edition). I have chosen a really simple iOS application to not distract from the main purpose of this post: what a BDD workflow looks like.

BDD Workflow from a 1,000 feet

I am going to look at the BDD workflow from a development perspective. There is a lot more which I could say about the role the whole team plays, and I will in a future blog post or posts. From a development perspective the BDD workflow works as follows:

BDD Workflow

Using an outside-in approach we implement a feature  starting from the acceptance criteria and working down. We will automate the validation of the acceptance criteria using calabash and cucumber.  We will build what is needed to make the acceptance tests pass and we will ensure the validity of this lower level code using Specta.

So let’s Get Started

We are going to cover a lot of things within this post, we will approach the sample project in steps as follows:

  1. Creation of a Single View Application and how to amend that application to use a XIB file rather than a storyboard.
  2. Adding Specta and Calabash.
  3. Writing Acceptance Tests
  4. Completion of the application using outside-in Development

I am using Xcode 6.1.1 for this tutorial but later versions of Xcode will work just as well. So let’s get started, fire up Xcode and create a new project. The Single View Application will do for our needs as it is the simplest starting point.

Single View Application

Project Template

 

Within the template options, fill as follows:

  • Product Name: Quiz
  • Organisation Name: fill this in however you wish
  • Organisation Identifier: the identifier you use for your apps, usually your domain in reverse notation
  • Language: Objective-C
  • Devices: Universal
  • Use Core Data: not checked

After Xcode has done it’s stuff the project will look as follows:

Xcode Window

We are going to convert this project to use a XIB file rather than a Storyboard. The Big Nerd Ranch book iOS Programming: The Big Nerd Ranch Guide (4th Edition) is opinionated on the benefits of storyboards. You will find lots of articles on the web also complaining about Apple’s implementation of storyboards. I think storyboards have their place and am not against them as such but as I am using an example from The Big Nerd Ranch book we will remove them.

Delete the following files from your project: Main.storyboard, ViewController.h, ViewController.m and QuizTests.m.

Click on Quiz project in the Project navigator ⌘+1 if you are not already viewing it. Under the Deployment Info section delete the text Main from the Main Interface drop-down.

Project navigator

 

Now if you run the application at this point ⌘+R the project should build and run, you will briefly see the launch screen and then a blank screen. Don’t worry about this, we haven’t got a View Controller or any code within the AppDelegate to display an interface to the user. We are going to cover everything using an outside-in approach so we are going to add these elements as automated acceptance criteria dictates that we need them.

Adding Specta and Calabash

We’re going to tackle adding Specta to the project first. Specta is a light-weight TDD/BDD framework for Objective-C. Specta is built on top of XCTest and as such has excellent Xcode integration. We are going to use Cocoapods to handle the integration of Spectra.

Setting Up Cocoapods

To set-up Cocoapods libraries in the project first ensure that you have Cocoapods installed. To do that, open the Terminal application and type the following, and hit Enter.

$ which pod

If you have Cocopods installed on your machine you should see something similar to the following:

/usr/bin/pod

If the terminal returns to the prompt, or you get the message pod not found, Cocoapods isn’t installed and you should follow this tutorial on Cocoapods.

We will use a Podfile to tell Cocoapods which Pods to import. To create a Podfile, use Terminal again to run the following:

$ pico Podfile

Once pico has opened, paste in the following:

target :QuizTests do
  pod 'Specta'
  pod 'Expecta'
end

To save the file, press Control+O, and hit Enter. You can now press Control+X to exit Pico. To install the two Pods listed in the Podfile, type the following into Terminal and hit Enter.

$ pod install

If successful you should see output like this:

$ pod install
Analyzing dependencies

Downloading dependencies
Installing Expecta (0.4.2)
Installing Specta (0.5.0)
Generating Pods project
Integrating client project

[!] Please close any current Xcode sessions and use `Quiz.xcworkspace` for this project from now on.


You should now close the Quiz project in Xcode and use Quiz.xcworkspace instead. If you take a look at the Project navigator you will now see a Pods project in the workspace. This Pods project contains the Specta and Expecta libraries.

Project navigator - Pods

 

 

 

 

 

 

 

 

 

 

 

Now check the project still builds and run ⌘+R, as before you will briefly see the launch screen and then a blank screen.

Adding Calabash

Adding Calabash to your project is a little more involved, I haven’t had much luck in the past using Cocoapods to add Calabash although it should work. I would recommend you have RVM installed on your machine there is a tutorial by Moncef Belyamani which is good here.

It is good practice to create a gemset for your project which will allow you to have an independent set of ruby and gems for your automated testing. In the Terminal application enter the following and hit Enter.

$ cd /path/to_your_project
$ rvm --rvmrc --create use ruby-2.1-head@calabash
Using /Users/dave.green/.rvm/gems/ruby-2.1-head with gemset calabash

Now install the calabash-cucumber gem, again in Terminal in the application folder enter the following and hit Enter.

$ gem install calabash-cucumber
Successfully installed calabash-cucumber-0.14.1
Parsing documentation for calabash-cucumber-0.14.1
Done installing documentation for calabash-cucumber after 1 seconds
1 gem installed

The next step is to generate the features folder and irb shell scripts, again in Terminal in the application folder enter the following and hit Enter.

$ calabash-ios gen

----------Question----------
I'm about to create a subdirectory called features.
features will contain all your calabash tests.
Please hit return to confirm that's what you want.
---------------------------


----------Info----------
Features subdirectory created. 
Make sure you've build your -cal scheme in XCode and 
try executing 

cucumber
---------------------------

This command sets up a basic structure for the calabash tests. You will now see a features directory with two folders step_definitions and support. If you have used cucumber before this will look familiar to you.

Setting up your Xcode project

The safest way to set-up your Xcode project with Calabash integration is manually. You first need to duplicate the primary/production target. Within the Project navigator ⌘+1 select the Quiz project and within the Targets section right-click and select Duplicate.

Duplicate Target

You will end up with a new target Quiz copy, rename the new target from Quiz copy to Quiz-cal. From the menu select Manage Schemes.

Manage Schemes

Rename the scheme Quiz copy to Quiz-cal. You now need to link the Calabash framework, in Terminal download the latest version of the calabash.framework by running the following command again from the project directory.

$ calabash-ios download

----------Info----------
caution: excluded filename not matched:  __MACOSX/*
caution: excluded filename not matched:  calabash.framework/.DS_Store
---------------------------

Use Finder to drag the calabash.framework file which was downloaded into your project directory into your project’s Framework folder in Xcode.

Calabash Framework

You need to make sure that:

  • Copy items into destination group’s folder (if needed) is checked
  • Only your “Quiz-cal” target is checked in Add to targets.

Copy Targets Dialog

You must also link your Quiz-cal target with CFNetwork.framework. To do this click on the Quiz-cal in Xcode. Click on Build Phases, expand Link Binary with Libraries, click to add CFNetwork.framework.

You now need to configure the Quiz-cal Target Build Settings.

  • Click on your project and select your new Quiz-cal target.
  • Select Build Settings
  • Ensure that All and not Basic settings are selected in build settings
  • Find Other Linker Flags
  • Ensure that Other Linker Flags contains: -force_load “$(SRCROOT)/calabash.framework/calabash” -lstdc++

Unfortunately now that you have created a separate target, new files that you add to your project are not automatically added to your Quiz-cal target. Make sure that any new files that you add to your production target are also added to the Quiz-cal target.

Testing calabash set-up

Now that we have everything considered it is time to see if everything worked correctly. Select the Quiz-cal scheme and run your application in a simulator. You should see the following console output if everything worked:

2015-05-06 12:49:00.797 Quiz copy[3562:204375] Creating the server: <LPHTTPServer: 0x7fca914069b0>
2015-05-06 12:49:00.799 Quiz copy[3562:204375] Calabash iOS server version: CALABASH VERSION: 0.14.1
2015-05-06 12:49:00.799 Quiz copy[3562:204375] App Base SDK: iphonesimulator8.1
2015-05-06 12:49:00.799 Quiz copy[3562:204375] simroot: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk
2015-05-06 12:49:00.817 Quiz copy[3562:204375] Started LPHTTP server on port 37265
2015-05-06 12:49:01.137 Quiz copy[3562:204375] WKWebView is not available
2015-05-06 12:49:01.702 Quiz copy[3562:204890] Bonjour Service Published: domain(local.) type(_http._tcp.) name(Calabash Server)

We have accomplished a lot so far, we have a basic Xcode project with Calabash and Specta integrated. We have successfully deleted the storyboard from the Xcode project ready to add an interface using a XIB file instead. You may want to get a quick coffee before we start the next section.

Writing Acceptance Tests

Normally we will have a list of features and for each of these features we will want to write some examples which form our automated acceptance tests. For this post we are using a Quiz App from the book iOS Programming: The Big Nerd Ranch Guide (4th Edition) so we haven’t got a documented set of features or examples. For simplicity I am going to take a sample feature for the Quiz App

Feature: Take a quiz
As a user
I want to take a quiz
So I can improve my general knowledge

From this feature  we may come up with the following automated acceptance tests documented using the domain specific language ‘Gherkin’

Scenario: View quiz question
Given I am on the Quiz Screen
When I view a question
Then a question is displayed
And the answer is not displayed

Scenario: View next question
Given I am on the Quiz Screen
And I am viewing a question
When I view the next question
Then a new question is displayed
And the answer is not displayed

Scenario: View answer
Given I am on the Quiz Screen
And I am viewing a question
When I give up and view the answer
Then the answer is displayed

Scenario: View next question after viewing an answer
Given I am on the Quiz Screen
And I am viewing a question with answer displayed
When I view the next question
Then a new question is displayed
And the answer is not displayed

Remember when we run the command `calabash-ios gen` that command generated a shiny new features folder. Open up the features folder in a text editor of your choice such as Sublime Text or TextMate. Delete the my_first.feature file and create a new file take_a_quiz.feature and copy and paste the following into the new file:

Feature: Take a quiz
As a user
I want to take a quiz
So I can improve my general knowledge

Scenario: View quiz question
Given I am on the Quiz Screen
When I view a question
Then a question is displayed
And the answer is not displayed

Scenario: View next question
Given I am on the Quiz Screen
And I am viewing a question
When I view the next question
Then a new question is displayed
And the answer is not displayed

Scenario: View answer
Given I am on the Quiz Screen
And I am viewing a question
When I give up and view the answer
Then the answer is displayed

Scenario: View next question after viewing an answer
Given I am on the Quiz Screen
And I am viewing a question with answer displayed
When I view the next question
Then a new question is displayed
And the answer is not displayed

Open up support/env.rb and change the contents of the file to read:

require 'calabash-cucumber/cucumber'
require 'rspec/expectations'

Open up Terminal in your project directory and run the following command:

$ cucumber

Feature: Take a quiz
  As a user
  I want to take a quiz
  So I can improve my general knowledge

  Scenario: View quiz question      # features/take_a_quiz.feature:6
    Given I am on the Quiz Screen   # features/take_a_quiz.feature:7
    When I view a question          # features/take_a_quiz.feature:8
    Then a question is displayed    # features/take_a_quiz.feature:9
    And the answer is not displayed # features/take_a_quiz.feature:10

  Scenario: View next question       # features/take_a_quiz.feature:12
    Given I am on the Quiz Screen    # features/take_a_quiz.feature:13
    And I am viewing a question      # features/take_a_quiz.feature:14
    When I view the next question    # features/take_a_quiz.feature:15
    Then a new question is displayed # features/take_a_quiz.feature:16
    And the answer is not displayed  # features/take_a_quiz.feature:17

  Scenario: View answer                # features/take_a_quiz.feature:19
    Given I am on the Quiz Screen      # features/take_a_quiz.feature:20
    And I am viewing a question        # features/take_a_quiz.feature:21
    When I give up and view the answer # features/take_a_quiz.feature:22
    Then the answer is displayed       # features/take_a_quiz.feature:23

  Scenario: View next question after viewing an answer # features/take_a_quiz.feature:25
    Given I am on the Quiz Screen                      # features/take_a_quiz.feature:26
    And I am viewing a question with answer displayed  # features/take_a_quiz.feature:27
    When I view the next question                      # features/take_a_quiz.feature:28
    Then a new question is displayed                   # features/take_a_quiz.feature:29
    And the answer is not displayed                    # features/take_a_quiz.feature:30

4 scenarios (4 undefined)
18 steps (18 undefined)
0m45.916s

You can implement step definitions for undefined steps with these snippets:

Given(/^I am on the Quiz Screen$/) do
  pending # express the regexp above with the code you wish you had
end

When(/^I view a question$/) do
  pending # express the regexp above with the code you wish you had
end

Then(/^a question is displayed$/) do
  pending # express the regexp above with the code you wish you had
end

Then(/^the answer is not displayed$/) do
  pending # express the regexp above with the code you wish you had
end

Given(/^I am viewing a question$/) do
  pending # express the regexp above with the code you wish you had
end

When(/^I view the next question$/) do
  pending # express the regexp above with the code you wish you had
end

Then(/^a new question is displayed$/) do
  pending # express the regexp above with the code you wish you had
end

When(/^I give up and view the answer$/) do
  pending # express the regexp above with the code you wish you had
end

Then(/^the answer is displayed$/) do
  pending # express the regexp above with the code you wish you had
end

Given(/^I am viewing a question with answer displayed$/) do
  pending # express the regexp above with the code you wish you had
end

All our tests are currently pending which is to be expected. From running this cucumber test you can tell one other thing as well, we are currently 0% complete on our feature. We are now going to use outside-in development to finish up our Quiz application and make sure we have a set of passing automated acceptance tests.

Outside-in Development

So to begin lets start with the step “Given I am on the Quiz Screen”, to make things easier put a tag against the first scenario by adding @wip to the scenario as follows:

@wip
Scenario: View quiz question
Given I am on the Quiz Screen
When I view a question
Then a question is displayed
And the answer is not displayed

You can now run just this scenario by typing the following in the Terminal application and hitting Enter.

$ cucumber -t @wip

Feature: Take a quiz
  As a user
  I want to take a quiz
  So I can improve my general knowledge

  @wip
  Scenario: View quiz question      # features/take_a_quiz.feature:7
    Given I am on the Quiz Screen   # features/take_a_quiz.feature:8
    When I view a question          # features/take_a_quiz.feature:9
    Then a question is displayed    # features/take_a_quiz.feature:10
    And the answer is not displayed # features/take_a_quiz.feature:11

1 scenario (1 undefined)
4 steps (4 undefined)
0m10.400s

You can implement step definitions for undefined steps with these snippets:

Given(/^I am on the Quiz Screen$/) do
  pending # express the regexp above with the code you wish you had
end

When(/^I view a question$/) do
  pending # express the regexp above with the code you wish you had
end

Then(/^a question is displayed$/) do
  pending # express the regexp above with the code you wish you had
end

Then(/^the answer is not displayed$/) do
  pending # express the regexp above with the code you wish you had
end

Let’s start by adding a step definition for the first step “Given I am on the Quiz Screen”. Delete the my_first_steps.rb file in the step_definitions folder and create a new file called step_definitions/quiz_steps.rb. Within the newly created quiz_steps.rb file enter the following:

Given(/^I am on the Quiz Screen$/) do
  pending # express the regexp above with the code you wish you had
end

Running the cucumber command again “cucumber -t @wip” you will notice the output has changed. The step is no longer unimplemented and is now pending and you will see something like the following:

  @wip
  Scenario: View quiz question      # features/take_a_quiz.feature:7
    Given I am on the Quiz Screen   # features/step_definitions/quiz_steps.rb:1
      TODO (Cucumber::Pending)
      ./features/step_definitions/quiz_steps.rb:2:in `/^I am on the Quiz Screen$/'
      features/take_a_quiz.feature:8:in `Given I am on the Quiz Screen'
    When I view a question          # features/take_a_quiz.feature:9
    Then a question is displayed    # features/take_a_quiz.feature:10
    And the answer is not displayed # features/take_a_quiz.feature:11

We now work to make this step pass, we first complete the step definition in quiz_steps.rb. There are many ways to implement this step but I have chosen to look for something I know is on the quiz screen, a question label. Go ahead and change your quiz_steps.rb file to look like the following:

Given(/^I am on the Quiz Screen$/) do
  expect(element_exists("label accessibilityLabel:'question-label'")).to be true
end

Go ahead and run cucumber again “cucumber -t @wip”, again the output has been changed.

$ cucumber -t @wip

Feature: Take a quiz
  As a user
  I want to take a quiz
  So I can improve my general knowledge

  @wip
  Scenario: View quiz question      # features/take_a_quiz.feature:7
    Given I am on the Quiz Screen   # features/step_definitions/quiz_steps.rb:1
      
      expected true
           got false
       (RSpec::Expectations::ExpectationNotMetError)
      ./features/step_definitions/quiz_steps.rb:2:in `/^I am on the Quiz Screen$/'
      features/take_a_quiz.feature:8:in `Given I am on the Quiz Screen'
    When I view a question          # features/take_a_quiz.feature:9
    Then a question is displayed    # features/take_a_quiz.feature:10
    And the answer is not displayed # features/take_a_quiz.feature:11

Failing Scenarios:
cucumber features/take_a_quiz.feature:7 # Scenario: View quiz question

1 scenario (1 failed)
4 steps (1 failed, 3 undefined)
0m8.460s

You can implement step definitions for undefined steps with these snippets:

When(/^I view a question$/) do
  pending # express the regexp above with the code you wish you had
end

Then(/^a question is displayed$/) do
  pending # express the regexp above with the code you wish you had
end

Then(/^the answer is not displayed$/) do
  pending # express the regexp above with the code you wish you had
end

We now need to work on getting that step to pass, the error indicates it expected a label and didn’t find one. We need to change our project to show a view with the correct label on. We are going to unit test the code we add using Specta, so head over to Xcode and under the QuizTests folder add a group called Delegate by right-clicking on the QuizTests folder and selecting New Group. Right-click on the new Delegate group and click New File and select Objective-C File and click Next.

New File

 

Within the file options dialog enter the following info:

  • File: AppDelegateSpec.m
  • File Type: Empty File

Go ahead and create the file and open the new file from the Project navigator and edit the file as follows:

//
//  AppDelegateSpec.m
//  Quiz
//
//  Created by Dave Green on 06/05/2015.
//  Copyright (c) 2015 DeveloperDave. All rights reserved.
//

#import "Specta.h"
#import "Expecta.h"

#import "AppDelegate.h"
#import "QuizViewController.h"


SpecBegin(AppDelegate)

describe(@"AppDelegate", ^{
    
    it(@"should create an instance of QuizViewController", ^{
        AppDelegate *delegate = [UIApplication sharedApplication].delegate;
        id vc = [[delegate window] rootViewController];
        
        expect(vc).to.beKindOf([QuizViewController class]);
    });
});

SpecEnd

Specta uses a RSpec style syntax, we describe the AppDelegate and describe what we expect to happen “should create an instance of QuizViewController”. We haven’t written the QuizViewController yet so let’s go ahead and do this now. Under the Quiz folder right-click and create a New Group and name the new group View Controllers, under the new View Controllers group right-click and create a New Group and name the new group Home. Right-click the Home group and select New File and create a new Cocoa Touch Class making sure you set the options as shown in the next series of screenshots.

Add new Cocoa Touch Class Set File Name Set Target

 

Open up the QuizViewController.xib file and drag a new label onto the canvas. We are going to position the label manually so we don’t get bogged down with Auto Layout. If you feel comfortable with Auto Layout by all means layout the view that way, that is the way I would do this in reality. To aid manually setting up the view click on the view and click Attributes Inspector ++4 and in Simulated Metrics and set the Size to iPhone 4-inch. Make sure when you run the app you use a 4-inch iPhone device.

Select the label in your view and set the views frame rectangle  ++5 as follows:

  • x position: 20
  • y position: 50
  • width: 280
  • height: 44

Open the Attributes Inspector  ++4 and set the text alignment to center aligned. Now open up the AppDelegate.m file and edit as follows:

//
//  AppDelegate.m
//  Quiz
//
//  Created by Dave Green on 24/04/2015.
//  Copyright (c) 2015 DeveloperDave. All rights reserved.
//

#import "AppDelegate.h"
#import "QuizViewController.h"

@interface AppDelegate ()

@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    
    QuizViewController *quizVC = [[QuizViewController alloc] init];
    self.window.rootViewController = quizVC;
    
    [self.window makeKeyAndVisible];
    
    
    return YES;
}

@end

Run the application ⌘+R and you should now see a blank white screen rather than the black screen you seen previously. Open the AppDelegateSpec.m file and click on the circle icon next to SpecBegin line and the unit test should pass.

1st Passing Test

Now with all this in place running cucumber again you should now see a passing step.

$ cucumber -t @wip
Feature: Take a quiz
  As a user
  I want to take a quiz
  So I can improve my general knowledge

  @wip
  Scenario: View quiz question      # features/take_a_quiz.feature:7
    Given I am on the Quiz Screen   # features/step_definitions/quiz_steps.rb:1
    When I view a question          # features/take_a_quiz.feature:9
    Then a question is displayed    # features/take_a_quiz.feature:10
    And the answer is not displayed # features/take_a_quiz.feature:11

1 scenario (1 undefined)
4 steps (3 undefined, 1 passed)
0m7.391s

You can implement step definitions for undefined steps with these snippets:

When(/^I view a question$/) do
  pending # express the regexp above with the code you wish you had
end

Then(/^a question is displayed$/) do
  pending # express the regexp above with the code you wish you had
end

Then(/^the answer is not displayed$/) do
  pending # express the regexp above with the code you wish you had
end

Congratulations you have your first passing step, we repeat this process again and again for each step until all features are complete!

Completing the second calabash step

So the second step of our first scenario is “When I view a question”. So from a user interface perspective we want to be able to tap a button and see a question. To start off with we will implement the step definition in quiz_steps.rb

When(/^I view a question$/) do
  macro 'I touch "show-question-button"'
end

The easiest way to get the step definition to handle the step is by copying it from the Terminal app when you run the cucumber tests. Calabash provides a whole series of steps, you can find a reference to these in the step_definition file calabash_steps.rb. One of the Calabash steps provided is “When I touch ‘{reference_here}'”, you can call Calabash steps using the macro keyword in your step definition.

So to make this work we are going to need a show-question-button in the view which can be clicked. But before we go any further let’s run the Cucumber tests again and see what happens. As expected the test fails and there is a message that touch could not find view marked: show-question-button which is not surprising. Let’s go ahead and implement the show-question-button now.

Open up QuizViewController.xib and drag a button onto the view. Again we are going to position the button manually, open the Size Inspector ++5 and set the Frame Rectangle for the button as follows:

  • x position: 20
  • y position: 100
  • width: 280
  • height: 30

In the Attributes Inspector ++4 set the background colour to a grey colour so it stands out and set the text colour to white. Change the button text to “Show Question” and in the Identity Inspector set the Accessibility Label to show-question-button. Run the application +R and you should see your newly created button, tapping the button should do nothing at the moment.

Now if you run Cucumber again you should have two passing steps. Also the cool thing is if you look at the other Scenario’s you will notice out of 4 scenario’s 3 of them start with the same first two steps. So we have in fact completed two steps for three scenario’s, pretty cool!

If you have got this far you definitely deserve a cup of coffee and some cake. So take a break and we will finish up the rest of the scenario’s in part 2.

2 replies

Trackbacks & Pingbacks

  1. […] back in Part 1 we set-up a simple Quiz App, we added Specta and Calabash to the project and most importantly we […]

  2. […] written before on the subject of Behaviour-Driven Development, here and here. I have found it invaluable in answering the question “what should I test?” […]

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

Your email address will not be published. Required fields are marked *