Mobile Software Test Automation: Sample iOS Project

I want to start out and apologize for the delay in getting this post up.  With all the craziness around the holidays, I was busy finishing up some side projects so they could be billed before the end of the year, and got severely behind on everything else.  But we're back.  I was going to make this a two-part walkthrough, but to make up for my delay, I'll wrap it all in one, so be warned, this post will be a little longer than usual.  Now on to setting up the iOS project! 

Download the Project

I was able to find an open sourced calculator project for iOS that will work perfectly for what we are doing, and it makes things a lot easier for all of us.  You can find the repo on GitHub here.  You will need to go ahead and pull this down to your machine. 

Overview of what's next

If you have a lot of experience with Xcode, you could probably get by following a more succinct tutorial on the calabash-ios installation guide on GitHub.  If you want to skip this post and find the short version, you can do so here.  Otherwise, I'm doing a step by step walkthrough so you can follow along.

However, before we get into making changes to the project, I want to talk a little bit about what we will actually be doing.  In short, we will be embedding a calabash specific framework as an event listener, and private Apple API's to synthesize touch events.  You do not want these in your production app version.  I repeat, YOU DO NOT WANT THESE IN YOUR PRODUCTION APP VERSION!  If they are added into your production app, your app WILL get rejected by the app store when it is submitted.  Now, there are a few ways around this...First, you can duplicate the target and make changes to only the duplicate target, which is (in my opinion) the best method, but does run the risk of developers not adding new features to the new target.  This is the way I will show today.  Or second, you could pull the project in locally and embed these frameworks locally, without ever checking in the changes.  It's up to you.  At my day job, I opted to duplicate the target (twice actually, one for prod and one for qa targets), and just made sure my developers included those targets when adding new features.  This also makes it easier to get the project suite running on a build server once this is all complete, but this decision is going to predominately depend on your individual workflow.  So moving on...

Setting up the Xcode project manually

Launch Xcode, and open up the Calculator.xcodeproj project file.  Once the project opens, you should have the standard editor in view, on the General tab.  It should look something like this:


Now, you will want to duplicate the target. This is done by right clicking the target (or two finger tap), and click duplicate.  You will then see a dialog popup that asks if you want to duplicate and transition to iPad, or duplicate only.  Select the Duplicate Only option.

Now, you should have a duplicate target named Calculator copy.  Lets go ahead and change this to Calculator-Calabash.  There are a few places we do this:  First, double-click on the target to go into edit mode. From here you can change the target name as shown below.  You will notice the bundle identifier changed as well.

Next, to the right of the stop button in the upper left part of the screen, click the dropdown and then click "Manage Schemes."  For the scheme that has "copy" at the end, click once to highlight, and then a second time on the text to bring up edit mode.  Change the scheme name as shown below, and then hit 'Close'.

Now, in the editor pane (which is the center pane), select 'Build Settings' and search for product name.  The latest version of Xcode will have already changed this for you, so it may not be necessary, but I wanted to include this just in case.

Next, we need to download the calabash framework.  This is most easily done using a gemfile with bundler. And as luck would have it, we already have that set up in our project folder.  Alternatively, you could set up a gemfile within the same directory as the .xcodeproj file and put the framework there, but I have found it is much more difficult to manage framework updates this way, especially if you have to support more than one version of an app at one time, which is why I am loading the framework into the automation project folder.  Simply open up the terminal, cd into your automation project folder, and run these two commands:

$ bundle

$ bundle exec calabash-ios download

Your terminal window should look something like this:

There should now be a calabash.framework folder added inside your project folder.

Now, back to Xcode... in the left hand pane, there should be a folder icon. If it's not already selected, click this, and you should see all the different files that make up your app.  You should see a Frameworks folder listed.  Drag the calabash.framework folder from finder and drop it on the frameworks folder in Xcode. 

Now, you will be presented with a dialog popup to adjust some options.  DON'T SKIP THIS STEP!  This is very important, and could cause your app to get rejected from the store if you aren't careful!  Configure your options as shown below and click finish.  The most important part is to uncheck the adding of this framework to your production target, and select only the -Calabash target.  Also, make sure 'copy items if needed' and 'create groups' is also checked.

Hang in there, we are almost done with the setup...only a few more steps to go.  So now that the calabash framework is added, make sure that the -Calabash target is selected, click on 'Build Phases' in the editor, expand the 'Link Binary With Libraries' tab, click on the + sign, and add CFNetwork.framework.   You will also need to add Security.framework (if it's not already there).


With the -Calabash target still selected, click on 'Build Settings', click All (this may already be selected), then search for 'other linker'.  Click on the 'Other Linker Flags' row, and click in the whitespace to enter edit mode.  For those of you using this tutorial to modify your own project, there may already be an argument here, don't remove it, simply add to it.  Add the following to this Other Linker Flags field:

-force_load "$(SRCROOT)/calabash.framework/calabash" -lstdc++

Click anywhere outside of the edit field to save your changes.  When you are done, it should look something like this (with a slightly different folder structure, depending on where you saved the project):


Testing the setup

Now that we have added the CFNetwork.framework and the calabash.framework to our project, lets test and make sure we did it all correctly.  In the scheme dropdown, just to the right of the stop button in the upper left corner, select the Calculator-Calabash scheme, and choose to run on a simulator. 

It's the moment of truth! Press the run (play) button.  You may get a dialog box asking if you want the application to accept incoming network connections.  If so, click 'Allow'.  The app should now be launched in the simulator, but you will need to check the console log to make sure everything is up and running.  This has changed a little over the years, but with the calabash-ios version I am running now (0.16.4), and Xcode 7.2, the important things to look for in the console log are "Creating the server: <LPHTTPServer: .....>" and then "Calabash iOS server version: CALABASH VERSION: 0.16.4."  It should look like this:


Now you are all set!  Frameworks are loaded into your iOS project, and the listener client is created.  If you remember, we already have our .feature file and step definitions, which we initially did for the android app.  All that is left is to plug in page support for the iOS app and we will be off to the races!  So next week we will walk through the irb calabash console for iOS, as well as coding in page support, followed by running the test on a device, so stay tuned.