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 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

BDD frameworks (part 3)

BDD frameworks (part 3)

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

Read more
BDD frameworks (part 1)

BDD frameworks (part 1)

Programmer, tester, manager, client – mutual understanding between these people is essential for the positive completion of any mobile application programming project. Nobody said it would be easy, but BDD frameworks can help.

Read more
How to become a programmer?

How to become a programmer?

The fast development of modern technology has caused an incessant growth in the need for programmers. As a consequence, more and more people have been becoming interested in this field. If you, as others, are trying to answer the question of “how to become a programmer”, this article is for you.

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


back to top