Mobile Software Test Automation: Running the project on iOS

Last week we finished getting everything set up for the iOS project, so now we are ready to run the project for iOS.  I recommend you use a physical device to run tests on, and you can find my reasons for that here.  In the past, there was the issue of paying to be set up as an apple developer if you wanted to run on a physical device, but with Apple's changes to how they charge for developers, you can get everything you need for free so long as you don't submit to the app store.  Also, those of you developing for a company will likely already be added to the developer profile for your app.  However, just in case, I'll show you how to run these tests on both a physical device and on a simulator.  

Running the project on a physical device

Device Setup

I know you are ready to jump in, but there are a few things we need to do, in order to make sure this will work.  First, plug in your device to the computer.  If this is the first time connecting this device to your computer, you will have to click that you trust the computer and all that jazz.  After that, make sure that your phone and computer are connected to the same wifi network.  On the device, go to Settings, Wi-Fi, click the blue information circle, and write down your IP Address.  Go back to the Settings menu, and scroll down to the Developer menu item.  Make sure that "Enable UI Automation" is turned on.  That's all we have to do on the device.  I'll recap in bullet points for those of you that skip to the action items:

  • Connect Device
  • Make sure that device and computer are on the same Wi-Fi
  • Get IP Address from device
  • Make sure that "Enable UI Automation" is turned on in the Settings > Developer menu item

Load app onto device

Now, you will want to launch Xcode and build the calabash scheme onto your device.  For those of you using the sample calculator app from last week, there shouldn't be any issues, so don't worry. But if this is for an app from your company, you will have to make sure that your device UDID is in the provisioning profile, which is managed on the apple developer portal in the member center.  Also, make sure your team is correctly set, and under the build settings menu, in the code signing section, make sure you are using the correct provisioning profile.  If you can build the app on a simulator, but can't get it on a device, it is almost certain you have a provisioning profile issue.  

Stick with it, but you may have to get a teammate involved to get everything set up in the member center.  As a side note, when I was first setting this up for my company, I had many of the issues I just mentioned.  Once they were fixed, it still didn't work, and I was perplexed.  Turns out, the bundle identifier/provisioning profile combo I was using wasn't set up to allow debugging (something most apps turn off for release profiles for good reason).  Since we couldn't change that, I ended up using a dev bundle id/provisioning profile for a beta version, so don't be afraid to get creative if you have to.  

Anyways, getting back to and run the app on your device. Make sure you have the appropriate -Calabash scheme selected, and pointed to the connected device, then hit the play button.

Once the app is on your phone, hit the stop button to kill the app.  

Get the UDID of the device

Since you already have Xcode up, go ahead and press Shift Command 2 on your computer. You can also navigate to the Window menu tab, and click the Devices menu item.  What you are looking for is the Device Identifier, or UDID.  So select your device from the side menu, and you should see the Identifier labeled near the top.  It should look like this:

Configure cucumber.yml file

You should already have this file in your project, since we created it when running the android project, but if not, you will need to create one either via Sublime text, or using the nano text editor in the terminal, which we learned how to do a while back.  Either way, we need to add the following lines to it:

ios: PLATFORM=ios APP_BUNDLE_PATH=calculator-ios-app/Calculator-Calabash-1.0 BUNDLE_ID=com.mglagola.Calculator-Calabash DEVICE_ENDPOINT= DEVICE_TARGET=your_device_UDID_here -r features/support -r features/ios/support -r features/ios/helpers -r features/step_definitions -r features/ios/pages

Note that there are no returns in this code. Everything should be on one line in your cucumber.yml file, but has been formatted above.  Also, you are welcome to specify the APP_BUNDLE_PATH, DEVICE_ENDPOINT, and DEVICE_TARGET environment variables on the command line at run time, but it's easier to do it here.  Also note that the APP_BUNDLE_PATH is the path to you .app file, relative to your project folder (where you run the project from in the terminal), and also make sure you include the port number 37265 after your IP Address.  I know I didn't explain this much when we ran the Android project, but the cucumber.yml file is basically a cucumber profile, which we are accessing using the -p command at runtime, followed by the environment, and is how the code knows which files to compile (since we have matching page support files for both platforms).

(Actually) running the project

Now is the time to watch all our hard work in action. Simply go to the terminal, cd into your project folder, and type the command:

$ bundle exec cucumber -p ios

You should be able to see the project run on your device, and you will also see the cucumber running in the terminal. The output should look like this:

If you have gotten this far, Great Job!  You now have automated an app for iOS and android, both running on actual devices.  This is no small feat, so go ahead and give yourself a pat on the back.

Running the project in the simulator

For those of you wanting to run the project on the simulator, the changes aren't all that different from what we had for a physical device.  First, launch Xcode and build the app to a simulator of your choice.  Then kill the app by pressing the stop button, just like we did when running on a physical device.  You can now close the simulator.  It is launched when we run the project.  But if it is left up, it will close it out before relaunching, so it doesn't really matter if you close it out or not.

Updating the cucumber.yml file (again)

Go ahead and make another profile named ios_sim.  You could also make changes to the ios profile, but this is easier in my opinion.  Remove the APP_BUNDLE_PATH and DEVICE_ENDPOINT variables all together. Also, change DEVICE_TARGET to match either your simulator name, or the UDID of the simulator.  In the end, it should look like this:

ios_sim: PLATFORM=ios BUNDLE_ID=com.mglagola.Calculator-Calabash DEVICE_TARGET='iPhone 6s (9.2)' -r features/support -r features/ios/support -r features/ios/helpers -r features/step_definitions -r features/ios/pages


Finally, you will need to put the .xcodeproj file in your project folder.  This is because the .app file was not built with the simulator architecture and thus, won't work on the sim.  Anyways, it's now time to run the project.  In the terminal, cd into the project directory and run:

$ bundle exec calabash -p ios_sim should see the simulator launch, and the tests running on the simulator and in the command line.  

Wrapping up and next steps

Great job today.  You really should feel proud of yourself for coming this far.  But we aren't slowing down.  Now that you have the basics under your belt, I will be going though some more advanced topics over the next few weeks.  Starting next week with some wait helper steps, then more advanced queries, performing swipes and other more advanced touch methods, updating calabash gems and dependencies, using tags, integrating automation into an existing build server/CI process, and so much more, so stay tuned!