BDD frameworks (part 2)

published in Agile Methodology, Android Development, Project Management, Tutorials
by Wojciech Szóstak

In this series of articles, you can learn how to use automated software testing with Behavior-Driven Development. In part 1, I described the main assumptions of the process. Now it is time for BDD testing tools.

In this part, I will present select BDD frameworks that I use as testing user interfaces (User Interface testing).

Calabash tutorial for mobile app testing

This is a BDD framework for writing automated tests for Android, iOS, and hybrid platforms. Calabash uses the Cucumber framework to describe the behavior of an application in natural language. An interesting option is to install Calabash Sandbox on both Windows and MacOS platforms.

Calabash-Android installation

Installation instructions can be found here:  GitHub – Calabash Android

Requirements:

  • Installation of Ruby >= 2.0
  • add permission to the application:
    <uses-permission android:name="android.permission.INTERNET"/>

How to use Calabash?

To begin your adventure with Calabash, first, you have to generate a directory structure. To do so, you need to enter the command: calabash-android gen.

The result should appear as below:
features
|_support
| |_app_installation_hooks.rb
| |_app_life_cycle_hooks.rb
| |_env.rb
| |_hooks.rb
|_step_definitions
| |_calabash_steps.rb
|_my_first.feature

In my_first.feature you define features and scenarios, whereas in calabash_steps.rb – we can define our steps (behaviors).

Calabash provides many default steps (it is worth looking here: GitHub – Canned steps and here: GitHub – Steps, but you can also define your own steps for the application you are working on.

Calabash-Android example

I have designed an example application that calculates the volume for a circle, rectangle and cube. It looks more or less like this:

Calabash-Android example

Example application

Writing a test

Feature: Circle feature

  Scenario: As a user I can calculate area of circle
    Then I press view with id "circle_button"
    Then I enter text "55" into field with id "radius_edittext"
    Then I go back
    Given I press the "Calculate" button
    Then I see the text "Area of circle is 9503.32"

  Scenario: As a user I write bad radius
    Then I press view with id "circle_button"
    Then I enter text "-4" into field with id "radius_edittext"
    Then I go back
    Given I press the "Calculate" button
    Then I see the text "Radius must be non-negative"
    Then I clear "radius_edittext"
    Then I go back
    Given I press the "Calculate" button
    Then I see the text "Incorrect data"

Feature: Square feature

  Scenario: As a user I can calculate area of square
    Then I press view with id "square_button"
    Then I enter text "5" into field with id "value_x_edittext"
    Then I enter text "8" into field with id "value_y_edittext"
    Then I go back
    Given I press the "Calculate" button
    Then I see the text "Area of square is 40"

Running a test

In order to run the test, we need to build a server. We can do this by using the command:

calabash-android build <apk>

Once we have the server, nonetheless, if the keys which we signed the server and application are different, we have to use the following command:

calabash-android resign <apk>

The test start-up comes after issuing the following command:

calabash-android run <apk>

Done! Let’s check out next framework now!

Green Coffee

Green Coffee uses two frameworks: Gherkin and Espresso (GitHub – Espresso setup). It allows you to run Android instrumentation tests.

Green Coffee is a good alternative to Calabash – in that it doesn’t require the installation of Ruby. In addition to the tool not being cross platform (it can only be used within Android), we have to define the steps we want to use within the tests in our application ourselves in this framework.

Green Coffee installation

Installation instructions can be found here:  GitHub – Green-coffee.

dependencies {
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2',     {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    androidTestCompile 'com.mauriciotogneri:greencoffee:2.0.1'
}

defaultConfig
{
    testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}

Directory Structure

Directory Structure

Directory Structure

We store features in the assets folder in androidTest. While in java/<package>/test, we put step definitions and classes that run the test.

Green Coffee Test Example


@RunWith(Parameterized.class)
public class SquareActivityTest extends GreenCoffeeTest {
    @Rule
    public ActivityTestRule activity = new ActivityTestRule<>(MainActivity.class);
    public SquareActivityTest(ScenarioConfig scenario) {
        super(scenario);
    }
    @Parameterized.Parameters
    public static Iterable scenarios() throws IOException
    {
        return new GreenCoffeeConfig()
                .withFeatureFromAssets("assets/square.feature")
                .scenarios();
    }
    @Test
    public void test()
    {
        start(new DefaultSteps(), new SquareActivityStep());
    }
}

As you see, initially we start up the first activity that we want to test:


@Rule
 public ActivityTestRule activity = new ActivityTestRule<>(MainActivity.class);

Next, we define the parameter which is injected into the test constructor. For example, a path for saving screenshots can be added to the parameter GreenCoffeeConfig.

 
@Parameterized.Parameters
public static Iterable scenarios() throws IOException
{
    return new GreenCoffeeConfig()
            .withFeatureFromAssets("assets/square.feature")
            .scenarios();
}
 

Finally, we define which step definitions the test will have access to:

 
@Test
public void test()
{
    start(new DefaultSteps(), new SquareActivityStep());
}

Example test steps:

 
public class DefaultSteps extends BasicStep {
    @Then("^I enter text \"([^\"]*)\" into field with id \"([^\"]*)\"$")
    public void enterTextToEditTextWithId(String text, String id) throws NoSuchFieldException, IllegalAccessException {
        onView(withId(resolve(id))).perform(clearText(), typeText(text), closeSoftKeyboard());
    }


    @Given("^I press the \"([^\"]*)\" button$")
    public void pressButtonWithText(String text) {
        onView(withText(text)).perform(click());
    }
    @Then("^I see the text \"([^\"]*)\"$")
    public void seeText(String text) {
        onView(withText(text)).check(matches(isDisplayed()));
    }
}

A step can be defined with the help of the following properties:

  • keyword: @When, @Given, @Then
  • a regular expression that describes a given step („<Regex corresponding to the appropriate behavior written in the feature file>”)

BasicStep class

To perform a specific action the object ID is necessary. BasicStep can be used to make searching for elements by ID easier

 
public class BasicStep extends GreenCoffeeSteps {
    public int resolve(String id) throws NoSuchFieldException, IllegalAccessException {
        Class<?> clazz = R.id.class;
        Field field = clazz.getField(id);
        return field.getInt(field);
    }
}

Example usage of class:

Feature: Login screen to authenticate users

  Scenario: As a user I can calculate area of circle
    Then I enter text "55" into field with id "radius_edittext"
    Given I press the "Calculate" button
    Then I see the text "Area of circle is 9503.32"

  Scenario: As a user I write bad radius
    Then I enter text "-4" into field with id "radius_edittext"
    Given I press the "Calculate" button
    Then I see the text "Radius must be non-negative"
    Then I clear "radius_edittext"
    Given I press the "Calculate" button
    Then I see the text "Incorrect data

Test Suite (grouping)

Another useful Green Coffee option is to group tests into one. This allows one test to run all the grouped tests.

 
@RunWith(Suite.class)
@Suite.SuiteClasses({
        CircleActivityTest.class,
        SquareActivityTest.class
})
public class AllTests {
}

We put all of the selected tests that we want to run simultaneously into Suite.SuiteClasses.

User Interface Testing

In this part, I have talked about Calabash and Green Coffee – selected frameworks used for testing user interfaces (User Interface testing). In the next section, I will describe Spock – unit testing framework.


You can find the source code on my GitHub.


Wojciech Szóstak Mobile Developer

Wojtek is a mobile developer at Zaven. He mostly works on android apps and enhances his knowledge about software testing (like BDD). In his spare time, Wojtek enjoys martial arts - he exercises several times a week!

Popular posts

3D Touch Peek and Pop Tutorial

3D Touch Peek and Pop Tutorial

With the release of the new model of phones: the iPhone 6s, Apple introduced 3D Touch. It's a functionality that allows the user to interact with the device using pressure. In the "3D Touch Peek and Pop Tutorial", I will show you how to use the Peek and Pop feature in iOS app development.

Read more
3D Touch Quick Actions Tutorial

3D Touch Quick Actions Tutorial

Did you know that the iPhone is able to detect different levels of touch depending on how hard you press? This is all thanks to 3D Touch! Check out how to add 3D Touch quick actions to your iOS apps.

Read more
BDD frameworks (part 3)

BDD frameworks (part 3)

In this series of articles, I am presenting selected BDD frameworks. In this part, I will talk about Spock – a unit testing framework.

Read more
Mobile Apps

Get your mobile app in 3 easy steps!

1

Spec out

with the help of our
business analyst

2

Develop

design, implement
and test, repeat!

3

Publish

get your app out
to the stores

Contact us

Hire us now!

back to top