Mobile Software Test Automation: Running the project on Android

Last week we set up the page support for the project, so all thats left is plugging that into the step definitions and then we can run the project!  So that's what we will be doing this week.

Hooking up Page Support

If you remember a few weeks ago, when we created step definitions, there was a code block after each step definition where we can put platform independent code.  Well now is that time.  So for each step definition, you will want to put some code linking that step to the page support method that is doing what you intend.  If you are asserting that you are on a specific page (as defined by the 'trait' on that page), your will code it like this:


page(LandingPage).await(timeout:30)

This example is essentially asserting that a page class named 'LandingPage' exists with the trait defined in that class, and will wait 30 seconds for the trait on that page to appear.  Since typing the page object out can be a bit tedious, you can also write it like this:


@current_page = page(LandingPage).await(timeout:30)

Typing it this way will prevent you from having to type out the whole page definition later.  So going down the list of step definitions from our sample, the above code should go between the "do" and "end" blocks of the "Then I am taken to the landing screen" step definition.  I am leaving the code blocks from the first two steps blank, because they are kind of redundant, and I mainly used those steps to show how to write Gherkin.  Next, we will define the step definition for the "And I can see a keypad and basic operators" code block.  This can be done in two ways, which I'll show below.  First, there's the long way:


page(LandingPage).keypad_basic_operators_present

The keypad_basic_operators_present is a method that we defined last week, which is simply waiting for a few specific elements to exist.  There is also the "short" way:


@current_page.keypad_basic_operators_present

I put short in quotes because here, it's not really that much shorter.  But when your page class is really long, like "SharedScheduleNewEventDetailsStartsChunk", defining it once will save lots of time.  I used @current_page in this example, but you can name it whatever you want, and even have multiple set up, one for each page.  Just make sure you put an @ before the variable attribute you are assigning.  

Next, we will define the step definition "When I enter a simple math problem".  So that we are on the same page, the simple math problem will be "10 + 9".  This can be done a few ways, but for simplicity, I am doing this in the step definitions.  It could also be a single method that we create in the page support for each platform, if you feel more comfortable doing it that way.  But this is what the math problem step should look like between the code blocks:


When(/^I enter a simple math problem$/) do
page(LandingPage).touch_button1
page(LandingPage).touch_button0
page(LandingPage).touch_button_plus
page(LandingPage).touch_button9
end

If you remember from last week, all of the "touch_buttonX" methods were defined in the LandingPage page object.  Now you should be able to define the last two steps on your own.  I ended up having to define some logic for the Given steps to dismiss an ad that pops up on occasion.  But when it's all said and done, your project should look something like this:

Running the Project

Now the moment you have been waiting for...Running the project on a local (physical or emulated) device!  Before I give you the run command, first create a file titled "cucumber.yml" in your project folder.  Inside this file, put the following text:


# config/cucumber.yml
##YAML Template
---
android: PLATFORM=android -r features/support -r features/android -r features/step_definitions -r features/android/pages

This basically allows all of our page objects to be compiled when we run the project with the android profile.  Now, you will want to cd into your project directory and make sure a physical device is connected and unlocked, or an emulator is launched and unlocked.  Now for the run command:


bundle exec calabash-android run android-apks/Calculator.apk -p android

To break down these pieces real quick, you have the run command "bundle exec calbash-android run", followed by the path to the apk, followed by "-p" which is then expecting a platform type, which we specify as "android".  To run this, you could also explicitly define your apk path, but I simply defined it here as relative to where the terminal is currently pointing, or relative to my project directory.  

Now sit back, kick your heels up, and watch the code run.  Although this was a simple test of a simple app, you should give yourself a pat on the back for getting everything set up, which can now easily be applied to your own project.  And if for some reason, the code didn't run for you, hit me up in the comments with the error(s) you are getting and I'll help you through it.

 Now, I'm assuming your company doesn't only have an android app, correct?  Thats what I thought.  Next we will get started setting up an iOS project.  It will be more abbreviated than the android setup, since I am assuming you will transfer the knowledge you gained over to iOS.  This will, however, require having access to the source code for the iOS app, so work on getting that if you don't have access already.  And I haven't looked yet to see what's out there, but I will try to find an open source iOS calculator project for a sample, and if one doesn't exist, I'll write one and post it to GitHub for you to follow along...So if I don't do a post next week, you'll know why.