The 4 Basics of Calabash Steps and Step Definitions – How to Implement Those


Dear Testdroiders,

In the past few blogs about Calabash for Android and iOS we’ve covered how to setup and get started with both platforms and define some of the fundamental things in Calabash. This time we’ll take a look at Calabash Steps, Step definitions and predefined steps that are set be default with Calabash installations. There are few tips and tricks that can be extremely handy and useful when it comes to using additional tools to help creating Calabash test scripts for your mobile app – and inspecting what should be put in Ruby code.


Steps, Step Definitions and Predefined Steps

In mobile test automation user interactions are in the epicenter and drive the behavior and progress of the app execution. User naturally interacts with UI components, visual assets, that enable the control of the app. To get better understanding of how Calabash drives user interactions on these we’ll take a look at few different methods to interact with an application. For instance, gestures on regular UI elements and interactions on those (e.g. pinch, zoom, swipe).

The UI hierarchy is pretty trivial for developers who build the app, but for testers there are some inspection tools that can be very useful to further inspect on which types of characteristics these UI elements contain. For instance, what layers, fragments and other implementations maybe difficult to inspect, but there are good tools that can be used to identify regular native UI components (e.g. Appium Inspector and uiautomatorviewer).

These types of inspection tools can help to find the name, description, value other useful attributes about the UI elements and objects. Let’s look at some basics of the step definitions and how those would be described in Ruby code. Meanwhile, you can download our free Calabash 101 to get a full understanding of steps and other tips.

1. Button Interactions

First of all, pressing a button (both on Android or iOS) is a basic procedure that test script and implementation must handle. For example, when user presses a back button the script and implementation could look something as follows

Then I go back

Naturally, there are some reserved buttons for both Android and iOS (e.g. Back, Home, Enter) that can then use perform_action function call to send the key press details:

For Android:
Then /^I go back$/ do

Then /^I press the enter button$/ do

For iOS:
Then /^I go back$/ do
  touch("navigationItemButtonView first")

Another example with Radio buttons would be very similar, despite that the nature of Radio button is different (on/off) and it contains information whether button is already checked. In this example we could use the same syntax but the implementation part would use another Ruby call:

Then I press view with id "radio0"

The “radio0” is an ID of the Android UI component that test must tap on. The implementation using tap_when_element_exists would click the UI element when it is available/ready for a click, and the implementation would go as follows:

Then /^I press view with id "([^\"]*)"$/ do |id|
  tap_when_element_exists("* id:'#{id}'")

Now, it’s slightly different how you do (implementation) this with iOS. The script itself would look the same, but the implementation part would be different:

Then /^I (?:press|touch) the "([^\"]*)" button$/ do |name|
  touch("Button touched: '#{name}'")

With iOS press/tap is called ‘touch’ but this would still use the name as a definition of which button is going to get pressed.

Other possible scenarios for touch would be a swipe where coordinates are given:

Then /^I (?:press|touch) on screen (\d+) from the left and (\d+) from the top$/ do |x, y|
  touch(nil, { offset: { x: x.to_i, y: y.to_i } })

For more information on specific tap/click/press/touch variants and how to configure those can be found in Calabash step definitions.

2. Entering Text into Text Field

For any use case where test script needs to enter text into text fields (e.g. login credentials or regular EditText elements) Calabash provides predefined steps out of the box. However, these can be easily tweaked to fit with your app. For instance:

Then I enter "Testing text input..." as "EditText1"

The script would enter “Testing text input…” as content into ‘EditText1’ UI element, and the implementation would go as follows:

Then /^I enter "([^\"]*)" as "([^\"]*)"$/ do |text, field|
  enter_text("android.widget.EditText {field LIKE[c] '#{field}'}", text)

The same could be applied to IDs of UI elements:

Then /^I enter text "([^\"]*)" into field with id "([^\"]*)"$/ do |text, id|
  enter_text("android.widget.EditText id:'#{id}'", text)

If you are interested to find out more about UI elements and inspect those – for example with Android – you can use uiautomatorviewer to get quickly all relevant information for your script. As default, uiautomatorviewer is installed with Android Studio.

3. Gestures

Gestures are natural for users with mobile devices and Calabash supports those as well. Let’s take a swipe as an example. The test would call it as follows:

Then I swipe right

The implementation part is slightly different for Android and iOS, and in addition there are few other navigation/gesture implementation differences between these two platforms:

For Android:
Then /^I swipe right$/ do
  perform_action('swipe', 'right')

For iOS:
Then /^I swipe (left|right|up|down)$/ do |dir|

The implementation for swipe with iOS looks more flexible as you only need one function to set the swipe direction. However, another example with scroll would be vice-versa when it comes to implementation:

Then I scroll up
For Android:
Then /^I scroll down$/ do

For iOS:
Then /^I scroll (left|right|up|down)$/ do |dir|
  scroll("scrollView index:0", dir)

4. Waiting and Asserts

First, the classic example with waiting/delaying test execution on Calabash:

Then I wait

This basically gives 2 seconds of delay as stated in implementation:

Then /^I wait$/ do
  sleep 2

Second example makes the test execution to wait until certain label/text is shown on the screen:

Then I wait to see "Hello!"

The same method can be also used to track if certain UI element (e.g. button) is visible on the screen. The implementation goes as follows:

For Android:
Then /^I wait to see "([^\"]*)"$/ do |text|

For iOS:
Then /^I wait to see "([^\"]*)"$/ do |expected_mark|
  wait_for(TIMEOUT) { view_with_mark_exists( expected_mark ) }

The Wait-To-See calls are definitely better than regular sleep as this can synchronize the test execution. As said, Waits can be also applied to certain elements, and here is an example of waiting implementation until Android button is visible:

Then /^I wait for the "([^\"]*)" button to appear$/ do |identifier|
  wait_for_element_exists("android.widget.Button marked:'#{identifier}'");

Asserting is very similar to waiting and cucumber language changes from “to see” to “should see”. For example:

Then I should see "Hello!"

This step checks the view for provided text on screen. If Calabash cannot find the identified text on the screen, the test step will fail.

For Android:
Then /^I should see "([^\"]*)"$/ do |text|
  wait_for_text(text, timeout: 5)

For iOS:
Then /^I should see "([^\"]*)"$/ do |expected_mark|
  res = (element_exists( "view marked:'#{expected_mark}'" ) or element_exists( "view text:'#{expected_mark}'"))
  if not res
     screenshot_and_raise "No element found with mark or text: #{expected_mark}"

How Test Steps and Step Definitions Show Up

The beauty of Calabash is that it really works well for both Android and iOS and despite of minor differences in Ruby implementations and sometimes with Calabash versions, we’re here to help you to run your Calabash tests smoothly on our devices. When you log in to Testdroid Cloud and upload your application plus tests, you’ll see the project overview of your test runs:

Screen Shot 2016-04-14 at 1.55.10 PM

If you run a Calabash test in Testdroid Cloud you get all the fine-grained details of Calabash steps under each test run. Just click the specific device run open (click the device name or anything on that line) and you’ll get the very same steps shown in the device run view:

Screen Shot 2016-04-14 at 2.03.03 PM

The UI shows your Calabash test steps and by clicking “Show screenshots” you’ll be able to see what happened with the test execution during each step with the app. Furthermore, you’ll also get the specific CPU and memory consumption details of the test run which provides excellent glance on what should be focused in performance optimization as well as memory allocations/deallocations.

Finally, Calabash test runs done in Testdroid Cloud also provide you Calabash log which can be used to further investigate behavior of test script and what happened in execution.

Screen Shot 2016-04-14 at 2.06.42 PM

Happy Calabash Testing folks!

By continuing to use the site, you agree to the use of cookies. more information

The cookie settings on this website are set to "allow cookies" to give you the best browsing experience possible. If you continue to use this website without changing your cookie settings or you click "Accept" below then you are consenting to this.