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

From Hype to Hard Hats: Practical Use Cases for AI chatbots in Construction and Proptech.

From Hype to Hard Hats: Practical Use Cases for AI chatbots in Construction and Proptech.

Remember the multimedia craze in the early 2000s? It was everywhere, but did it truly revolutionize our lives? Probably not. Today, it feels like every piece of software is labeled "AI-powered." It's easy to dismiss AI chatbots in construction as just another tech fad.

Read more
Fears surrounding external support. How to address concerns about outsourcing software development?

Fears surrounding external support. How to address concerns about outsourcing software development?

Whether you’ve had bad experiences in the past or no experience at all, there will always be fears underlying your decision to outsource software development.

Read more
What do you actually seek from external support? Identify what’s preventing you from completing a project on time and within budget

What do you actually seek from external support? Identify what’s preventing you from completing a project on time and within budget

Let’s make it clear: if the capabilities are there, a project is best delivered internally. Sometimes, however, we are missing certain capabilities that are required to deliver said project in a realistic timeline. These may be related to skills (e.g. technical expertise, domain experience), budget (hiring locally is too expensive) or just capacity (not enough manpower). What are good reasons for outsourcing software development?

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