Posts Tagged ‘automated testing’

Recap: Getting Started with Mobile Test Automation & Appium [Webinar]

May 18th, 2015 by Bill McGee

Thanks to everyone who joined us for our last webinar, Getting Started with Mobile Test Automation &  Appium, featuring Siva Anna from InfoStretch and Abhijit Pendyal from Sauce Labs. The webinar covered best practices in implementing Appium to quickly automate mobile application testing. Topics covered included:

  • Mobile Automation Tools and Landscape
  • Setting  Up an Appium Environment & Object Inspectors
  • Writing a Basic Automation Script for Android and iOS platforms
  • Running an Analysis Execution in Appium and Sauce Labs

Missed the presentation, want to hear it again, or share with a colleague?

Listen to the recording HERE and view the slides below.

Interested in learning more about Appium and how to get started? Download our free Getting Started with Appium guide.

Decreasing False Positives in Automated Testing [RECAP]

March 30th, 2015 by Bill McGee

Thanks for joining us for our last webinar, Decreasing False Positives in Automated Testing, featuring Anand Ramakrishnan of QASource.

In this webinar, Anand covered: (more…)

Repost: Lessons Learned from Automating iOS Apps – What To Do When Tests Require Camera Roll Resources?

March 18th, 2015 by Bill McGee

This post comes from our friend Jay Sirju at Animoto, who is leveraging Sauce, Appium, and CI methodologies to automate mobile testing for their iOS application.  Check out the original post on their blog.

Here at Animoto, the mobile application development team had spent some time over the past year investigating and implementing CI methodologies into the development cycle of the Animoto Video Maker application for iOS. A major part of this initiative involved creating automated test cases that would run at various times and circumstances.

First a bit of background. When we started this, we had already implemented a good amount of automation for the Animoto website. We had chosen to use Selenium and ran our automated tests against various browsers using Sauce Labs. We decided to extend our existing infrastructure to support running automated tests using theAppium library against Sauce Labs.   For those unfamiliar with mobile testing on Sauce Labs, they use the iOS and Android Simulators to run tests. I know, not ideal, but we can get to that another time.

The Problem

For anyone who has ever launched a fresh iOS Simulator (before Xcode 6), the OS is in it’s factory state. The Animoto Video Maker App transforms your pictures, video, and text, into professional looking videos… see where I’m going?

Screen-Shot-2015-02-18-at-11.31.04-AM

A lot of user flows depend on having some photos in the camera roll. A factory-fresh simulator without any photos means there are man flows we can’t automate. Unfortunately, at the time of writing, Sauce Labs does not have a way to upload assets to populate the Camera Roll, and the simulators are reset after executing each test case. Starting with XCode 6, the Camera Roll does have some images out of the box, but what was really needed were meaningful pictures and videos. So what is needed is a way to populate the Camera Roll while working within the constraints of running tests in Sauce Labs. Well, the app already reads images and pictures from Camera Roll, what about writing to it as well?

Adding or Altering Configuration Profile

Before we get to actually populating the Camera Roll, we need a mechanism to ensure that this logic is performed only when the intent is to run automation. Out of the box, Xcode provides 3 build configurations (Debug, Release, and Distribution). We can edit these configurations, add new ones, or even delete unnecessary ones. In this case, we can simply add a Test configuration to the mix. Once we did that, we were able to change various build settings to help create hooks for app automation. We can start out by adding a Preprocessor Macro for the Test build configuration, so that we can tell the pre-processor when to compile test hooks into the build.

animoto 2

Okay, now we can do some fun stuff with the build. For the sake of brevity, let’s focus specifically on the original issue: Getting pictures and videos into the Camera Roll.

Change Test Configuration Profile Settings

First things first – how does one get pictures and videos up to Sauce Labs? We can simply add them to the iOS project, but that would increase the size of the application bundle regardless of which build configuration is being used. Definitely not ideal. A better choice would be to store them somewhere externally and copy them to the application bundle when the Test configuration is used. This can be done by running a script when building the project.

[code language=”ruby”]if [ ${CONFIGURATION} == "Test" ]; then
cp -r ${PICTURE_AND_VIDEO_LOCATION}/ ${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app
fi[/code]

Populating the Camera Roll

Now we have an application bundle that contains a bunch of sample pictures and videos. This is great because when the application gets uploaded to Sauce Labs for testing, so do all the sample data.   The following code example assumes all the sample images are in a folder within the application bundle named ‘TestImages’:

[code language=”ruby”]+ (void) populateCameraRoll
{
NSString* absolutePicturePath = [[NSBundle mainBundle] pathForResource:@"TestImages" ofType:nil];
NSArray* pictureList = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:absolutePicturePath error:nil];

for(int i = 0; i < [pictureList count]; i++)
{
NSString* absolutePictureFilePath =[ NSString stringWithFormat:@"/%@/%@", absolutePicturePath,[pictureList objectAtIndex: i]];

NSData *jpeg = [NSData dataWithContentsOfFile:absolutePictureFilePath];

UIImage *image = [UIImage imageNamed:absolutePictureFilePath];

CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)jpeg, NULL);
CFDictionaryRef imageMetaDataRef = CGImageSourceCopyPropertiesAtIndex(source,0,NULL);
NSDictionary *imageMetadata = CFBridgingRelease(imageMetaDataRef);
CFRelease(source);

if (image != nil)
{
ALAssetsLibrary* library = [[ALAssetsLibrary alloc] init];

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
dispatch_semaphore_t sema = dispatch_semaphore_create(0);

[library writeImageToSavedPhotosAlbum:[image CGImage] metadata:imageMetadata completionBlock:^(NSURL *assetURL, NSError *error)
{
dispatch_semaphore_signal(sema);
}];
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
});
}
}
}
@end[/code]

The above code makes a bunch of assumptions. First, it only works for images. Another folder consisting of sample videos can be created, and the using similar logic and the writeImageToSavedPhotosAlbum method. Next, calling writeImageToSavedPhotosAlbum can indeed fail. For the sake of keeping this example code more readable, error handling was excluded. Retry logic should be included if an error is returned.

Finally, you may have noticed the use of a semaphore in the example code. Writing images to the Camera Roll is actually an asynchronous call, meaning that the call returns immediately while a separate thread processes writing the image data to the Camera Roll. The writeImageToSavedPhotosAlbum method can fail if there are too many threads trying to write image data simultaneously. The semaphore is used ensure that images are written to the Camera Roll sequentially. This makes using the writeImageToSavedPhotosAlbum method much more stable.

Okay, so now that is left is to call the method when running the Test configuration. This can easily be done using the Preprocessor Macro setting that was above mentioned.

[code language=”ruby”]#if TEST
[ANTestClass populateCameraRoll];
#endif[/code]

It is recommended to call the method somewhere deterministic (ie -a button tap). Simply populating the Camera Roll at start-up may mess up launching Apples Instrumentation library because of the Alert displayed when the app accesses the Camera Roll for the first time. This lesson was learned the hard way.

This opens up the ability to add more automated test hooks into the application under test, but as a word of warning; the more hooks added, the more the test configuration of the app diverges from what is being released to customers.

 

Have an idea for a blog post, webinar, or more? We want to hear from you! Submit topic ideas (or questions!) here.

Automated Testing News: Link Round-Up

January 23rd, 2015 by Bill McGee
Happy Friday! Here’s a quick round-up of some pieces on automated testing, why functional and performance testing should be done simultaneously, the case for Continuous Testing in the Cloud,  how to take your career to the next level, QTP/UFT VS Selenium, and what the top 10 tools were this week on Stackshare.  See below for snippets and links to the full articles.

(more…)

Mobile Testing Talk: What’s New With Appium [RECAP]

December 19th, 2014 by Bill McGee

appium_logo_with_sauce_NEW

Thanks for joining us last week for our latest webinar, Mobile Testing Talk: What’s New With Appium, which featured Jonathan Lipps, the Chief Architect for the Appium Project.

To recap, Jonathan gave listeners a tour of Appium version 1.3.x, including the stability improvements and features the team has added since the Appium 1.0 release back in May of 2014. He also touched on the following:

  •  Appium 1.3.x release features and improvements
  •  New platforms
  •  Better hybrid support
  •  Examples of maturing Appium clients & more

We had great feedback on the content and an influx of interesting questions that got addressed in the Q&A at the end.

Missed the webinar, need to hear it again, or want share it with your team? Check out the slides below (more…)

Puppet Labs + Sauce Labs: Testing Made Awesome [VIDEO]

August 1st, 2014 by Bill McGee

A few weeks back, we sat down with Engineering Manager Dominic Maraglia of Puppet Labs to hear how they use Sauce.

Puppet Labs is the leading provider of IT automation software, so naturally automating processes internally is a high priority. We were pleased to hear that Sauce Labs fit easily into their testing process, and that after automating their tests and using Sauce’s infrastructure, the time they spent on testing went from 30 days to 3 days.

Watch the video below to learn more.

Want to share your story? We want to hear from you! Submit a request here.

Appium Bootcamp – Chapter 4: Your First Test

July 31st, 2014 by Bill McGee

appium_logoThis is the fourth post in a series called Appium Bootcamp by noted Selenium expert Dave Haeffner

Read:  Chapter 1 Chapter 2 | Chapter 3 | Chapter 4 | Chapter 5 | Chapter 6 | Chapter 7 | Chapter 8

Dave recently immersed himself in the open source Appium project and collaborated with leading Appium contributor Matthew Edwards to bring us this material. Appium Bootcamp is for those who are brand new to mobile test automation with Appium. No familiarity with Selenium is required, although it may be useful. This is the fourth of eight posts; two new posts will be released each week.

There are a good deal of similarities between Selenium and Appium tests. We will be using similar actions (like click) along with some kind of wait mechanism (e.g., an explicit wait) to make our tests more resilient. There will also be an assertion used to determine if our actions were successful or not.

In order to put these concepts to work, let’s consider the basic structure of the test apps we’ve been working with. They are straightforward in that they both have text elements that, when clicked, take you to a dedicated page for that element (e.g., Accessibility triggers the Accessibility page). Let’s step through our first set of test actions (in the console) that we’ll use to automate this behavior; verifying that each element brings us to the correct page.

Let’s dig in with some examples.

An iOS Example

The behavior of our app can be easily mapped to test actions by first using a text match to find the element we want, and clicking it. We can then make sure we are in the right place by performing another text match (this time an exact text match). When we wire this up to our test framework, this match will be responsible for passing or failing the test. More on that in the next post.

text('Buttons, Various uses of UIButton').click
text_exact 'Buttons'

The only problem with this approach is that it is not resilient. The global wait for each test action (a.k.a. an implicit wait) is set to 0 seconds by default. So if there is any delay in the app, the test action will not complete and throw an element not found exception instead.

To overcome these timing problems we can employ an explicit wait around our test actions (both the click and the exact text match). This is simple enough to do with the wait command.

wait { text('Buttons, Various uses of UIButton').click }
wait { text_exact 'Buttons' }

These test actions are resilient now, but they’re inflexible since we were using statically coded values. Let’s fix that by using dynamic values instead.

cell_1 = wait { text 2 }
cell_title = cell_1.name.split(',').first

wait { cell_1.click }
wait { text_exact cell_title }

Now we’re finding the first text by it’s index. Index 2 contains the first element (a.k.a. a cell), whereas index 1 is the table header. After that, we’re extracting the name and dynamically finding the title. Now our test will continue to work if there are any text changes.

This is good, but now let’s expand things to cover the rest of the app.

cell_names = tags('UIATableCell').map { |cell| cell.name }

cell_names.each do |name|
  wait { text_exact(name).click }
  wait { text_exact name.split(',').first }
  wait { back }
end

We first grab the names of each clickable cell, storing them in a collection. We then iterate through the collection, finding each element by name, clicking it, performing an exact match on the resulting page, and then going back to the main screen. This is repeated until each cell is verified.

This works for cells that are off the screen (e.g., out of view) since Appium will scroll them into view before taking an action against them.

An Android Example

Things are pretty similar to the iOS example. We perform a text match, click action, and exact text match.

text('Accessibility').click
text_exact 'Accessibility Node Provider'

We then make things resilient by wrapping them in an explicit wait.

wait { text('Accessibility').click }
wait { text_exact 'Accessibility Node Provider' }

We then make our selection more flexible by upgrading to dynamic values.

cell_1 = wait { text 2 }

wait { cell_1.click }
wait { find_exact 'Accessibility Node Provider' }

We then expand things to exercise the whole app by collecting all of the clickable elements and iterating through them.

cell_names = tags('android.widget.TextView').map { |cell| cell.name }

cell_names[1..-1].each do |cell_name|
  wait { scroll_to_exact(cell_name).click }
  wait_true { ! exists { find_exact cell_name } }
  wait { back }
  wait { find_exact('Accessibility'); find_exact('Animation')  }
end

A few things to note.

The first item in the cell_names collection is a header. To discard it, we use cell_name[1..-1] which basically says start with the second item in the collection (e.g., [1) and continue (e.g., ..) all the way until the end (e.g.,-1]).

In order to interact with cells that are off the screen, we will need to use the scroll_to_exact command, and perform a click against that (instead of a text match).

Since each sub-screen doesn’t have many unique attributes for us to verify against, we can at the very least verify that we’re no longer on the home screen. After that, we verify that we are brought back to the home screen.

Outro

Now that we have our test actions sussed out, we’re ready to commit them to code and plug them into a test runner.

Read:  Chapter 1 Chapter 2 | Chapter 3 | Chapter 4 | Chapter 5 | Chapter 6 | Chapter 7 | Chapter 8

About Dave Haeffner: Dave is a recent Appium convert and the author of Elemental Selenium (a free, once weekly Selenium tip newsletter that is read by thousands of testing professionals) as well as The Selenium Guidebook (a step-by-step guide on how to use Selenium Successfully). He is also the creator and maintainer of ChemistryKit (an open-source Selenium framework). He has helped numerous companies successfully implement automated acceptance testing; including The Motley Fool, ManTech International, Sittercity, and Animoto. He is a founder and co-organizer of the Selenium Hangout and has spoken at numerous conferences and meetups about acceptance testing.

Follow Dave on Twitter – @tourdedave

 

Sign Up for the First-Ever Appium Roadshow on August 20th in New York City

July 30th, 2014 by Bill McGee

appium_logoWe don’t know if you heard, but mobile is kind of a big deal.

Naturally, Appium – the only open source, cross-platform test automation tool for native, hybrid, and mobile web apps – emerged out of the need to Test All The (Mobile) Things.  Last May, battle-tested Appium 1.0 was released, and now this Appium show is hitting the road!

Details and ticket links below. Hope to see you in New York!

*****

Sign Up for the First-Ever Appium Roadshow on August 20th

Appium Roadshow – NYC is a two part, day-long event held on Wednesday, August 20 at Projective Space – LES in Manhattan’s Lower East Side.

Part 1 – Appium in the Wild

8:30 AM – 1:00 PM – Free

The morning session will showcase presentations from Gilt Groupe, Sharecare, Softcyrlic, and Sauce Labs. Topics will cover real-world examples, lessons learned, and best practices in mobile app test automation using Appium. Featured speakers include:

  • Matthew Edwards – Mobile Automation Lead, Aquent
  • Daniel Gempesaw – Software Testing Architect, Sharecare
  • Matt Isaacs – Engineer, Gilt Groupe
  • Jonathan Lipps – Director of Ecosystem and Integrations, Sauce Labs
  • Sundar Sritharan – Delivery Manager, Softcrylic

This event is free. Breakfast and lunch included. Reserve your seat now – register here.

Part 2 – Appium Workshop

1:30 PM – 5:30 PM – $100

Matthew Edwards, a leading contributor to the Appium project, will provide a hands-on workshop to help you kick start your Appium tests.  He’ll talk you through how to set up the environment needed for native iOS and Android automation with Ruby.  You’ll then download and configure the Appium.app to enable test writing. Then, Matthew will demonstrate how to kick up an Appium server and then run a test.

This event is limited to just 40 participants. Reserve your seat now – register here.

 

Appium Bootcamp – Chapter 3: Interrogating Your App

July 29th, 2014 by Bill McGee

appium_logoThis is the third post in a series called Appium Bootcamp by noted Selenium expert Dave Haeffner

Read:  Chapter 1 Chapter 2 | Chapter 3 | Chapter 4 | Chapter 5 | Chapter 6 | Chapter 7 | Chapter 8

Dave recently immersed himself in the open source Appium project and collaborated with leading Appium contributor Matthew Edwards to bring us this material. Appium Bootcamp is for those who are brand new to mobile test automation with Appium. No familiarity with Selenium is required, although it may be useful. This is the third of eight posts; a new post will be released each week.

Writing automated scripts to drive an app in Appium is very similar to how it’s done in Selenium. We first need to choose a locator, and use it to find an element. We can then perform an action against that element.

In Appium, there are two approaches to interrogate an app to find the best locators to work with. Through the Appium Console, or through an Inspector (e.g., Appium Inspector, uiautomatorviewer, or selendroid inspector).

Let’s step through how to use each of them to decompose and understand your app.

Using the Appium Console

Assuming you’ve followed along with the last two posts, you should have everything setup and ready to run.

Go ahead and startup your Appium server (by clicking Launch in the Appium GUI) and start the Appium Ruby Console (by running arc in a terminal window that is in the same directory as your appium.txt file). After it loads you will see an emulator window of your app that you can interact with as well as an interactive prompt for issuing commands to Appium.

The interactive prompt is where we’ll want to focus. It offers a host of readily available commands to quickly give us insight into the elements that make up the user interface of the app. This will help us easily identify the correct locators to automate our test actions against.

The first command you’ll want to know about is page. It gives you access to every element in the app. If you run it by itself, it will output all of the elements in the app, which can be a bit unwieldy. Alternatively you can specify additional arguments along with it. This will filter the output down to just a subset of elements. From there, there is more information available that you can use to further refine your results.

Let’s step through some examples of that and more for both iOS and Android.

An iOS Example

To get a quick birds eye view of our iOS app structure, let’s get a list of the various element classes available. With the page_class command we can do just that.

[1] pry(main)> page_class
get /source
13x UIAStaticText
12x UIATableCell
4x UIAElement
2x UIAWindow
1x UIATableView
1x UIANavigationBar
1x UIAStatusBar
1x UIAApplication

UIAStaticText and all of the others are the specific class names for types of elements in iOS. You can see reference documentation for UIAStaticText here. If you want to see the others, go here.

With the page command we can specify a class name and see all of the elements for that type. When specifying the element class name, we can either specify it as a string, or a symbol (e.g., 'UIAStaticText' or:UIAStaticText).

[2] pry(main)> page :UIAStaticText
get /context
post /execute
{
    :script => "UIATarget.localTarget().frontMostApp().windows()[0].getTree()"
}
UIAStaticText
   name, label, value: UICatalog
UIAStaticText
   name, label: Buttons, Various uses of UIButton
   id: ButtonsTitle   => Buttons
       ButtonsExplain => Various uses of UIButton
UIAStaticText
   name, label: Controls, Various uses of UIControl
   id: ControlsExplain => Various uses of UIControl
       ControlsTitle   => Controls
UIAStaticText
   name, label: TextFields, Uses of UITextField
   id: TextFieldExplain => Uses of UITextField
       TextFieldTitle   => TextFields
...

Note the get and post (just after we issue the command but before the element list). It is the network traffic that is happening behind the scenes to get us this information from Appium. The response to post /execute has a script string. In it we can see which window this element lives in (e.g., windows()[0]).

This is important because iOS has the concept of windows, and some elements may not appear in the console output even if they’re visible to the user in the app. In that case, you could list the elements in other pages (e.g.,page window: 1). 0 is generally the elements for your app, whereas 1 is where the system UI lives. This will come in handy when dealing with alerts.

Finding Elements

Within each element of the list, notice their properties — things like namelabelvalue, and id. This is the kind of information we will want to reference in order interact with the app.

Let’s take the first element for example.

UIAStaticText
   name, label, value: UICatalog

In order to find this element and interact with it, we can can search for it with a couple of different commands: findtext, or text_exact.

> find('UICatalog')
...
#
> text('UICatalog')
...
#
> text_exact('UICatalog')
...
#

We’ll know that we successfully found an element when we see a Selenium::WebDriver::Element object returned.

It’s worth noting that in the underlying gem that enables this REPL functionality, if we end our command with a semi-colon it will not show us the return object.

> find('UICatalog')
# displays returned value

> find('UICatalog');
# returned value not displayed

To verify that we have the element we expect, let’s access the name attribute for it.

> find('UICatalog').name
...
"UICatalog"

Finding Elements by ID

A better approach to find an element would be to reference its id, since it is less likely to change than the text of the element.

UIAStaticText
   name, label: Buttons, Various uses of UIButton
   id: ButtonsTitle   => Buttons
       ButtonsExplain => Various uses of UIButton

On this element, there are some IDs we can reference. To find it using these IDs we can use the id command. And to confirm that it’s the element we expect, we can ask it for its name attribute.

> id('ButtonsTitle').name
...
"Buttons, Various uses of UIButton"

For a more thorough walk through and explanation of these commands (and some additional ones) go here. For a full list of available commands go here.

An Android Example

To get a quick birds eye view of our Android app structure, let’s get a list of the various element classes available. With the page_class command we can do just that.

[1] pry(main)> page_class
get /source
12x android.widget.TextView
1x android.view.View
1x android.widget.ListView
1x android.widget.FrameLayout
1x hierarchy

android.widget.TextView and all of the others are the specific class names for types of elements in Android. You can see reference documentation for TextView here. If you want to see the others, simply do a Google search for the full class name.

With the page command we can specify a class name and see all of the elements for that type. When specifying the element class name, we can specify it as a string (e.g., 'android.widget.TextView').

[2] pry(main)> page 'android.widget.TextView'
get /source
post /appium/app/strings

android.widget.TextView (0)
  text: API Demos
  id: android:id/action_bar_title
  strings.xml: activity_sample_code

android.widget.TextView (1)
  text, desc: Accessibility
  id: android:id/text1

android.widget.TextView (2)
  text, desc: Animation
  id: android:id/text1
...

Note the get and post (just after we issue the command but before the element list). It is the network traffic that is happening behind the scenes to get us this information from Appium. get /source is to download the source code for the current view and post /appium/app/strings gets the app’s strings. These app strings will come in handy soon, since they will be used for some of the IDs on our app’s elements; which will help us locate them more easily.

Finding Elements

Within each element of the list, notice their properties — things like text and id. This is the kind of information we will want to reference in order interact with the app.

Let’s take the first element for example.

android.widget.TextView (0)
  text: API Demos
  id: android:id/action_bar_title
  strings.xml: activity_sample_code

In order to find that element and interact with it, we can search for it by text or by id.

> text('API Demos')
...
#
> id('android:id/action_bar_title')
...
#

We’ll know that we successfully found an element when we see a Selenium::WebDriver::Element object returned.

It’s worth noting that in the underlying gem that enables this REPL functionality, if we end our command with a semi-colon it will not show us the return object.

> text('API Demos')
# displays returned value

> text('API Demos');
# returned value not displayed

To verify we’ve found the element we expect, let’s access the name attribute for it.

> text('API Demos').name
...
"API Demos"

Finding Elements by ID

A better approach to find an element would be to reference its ID, since it is less likely to change than the text of the element.

In Android, there are a two types of IDs you can search with — a resource ID, and strings.xml. Resource IDs are best. But strings.xml are a good runner-up.

android.widget.TextView (10)
  text, desc: Text
  id: android:id/text1
  strings.xml: autocomplete_3_button_7

This element has one of each. Let’s search using each with the id command.

# resource ID
> id('android:id/text1')
...
#

# strings.xml
> id('autocomplete_3_button_7')
...
#

You can see a more thorough walk through of these commands here. For a full list of available commands go here.

Ending the session

In order to end the console session, input the x command. This will cleanly quit things for you. If a session is not ended properly, then Appium will think it’s still in progress and block all future sessions from working. If that happens, then you need to restart the Appium server by clicking Stop and then Launch in the Appium GUI.

x only works within the console. In our test scripts, we will use driver.quit to kill the session.

Using An Inspector

With the Appium Ruby Console up and running, we also have access to the Appium Inspector. This is another great way to interrogate our app to find locators. Simply click the magnifying glass in the top-right hand corner of the Appium GUI (next to the Launch button) to open it. It will load in a new window.

Once it opens, you should see panes listing the elements in your app. Click on an item in the left-most pane to drill down into the elements within it. When you do, you should see the screenshot on the right-hand side of the window auto-update with a red highlight around the newly targeted element.

You can keep doing this until you find the specific element you want to target. The properties of the element will be outputted in the Details box on the bottom right-hand corner of the window.

It’s worth noting that while the inspector works well for iOS, there are some problem areas with it in Android at the moment. To that end, the Appium team encourages the use of uiautomatorviewer (which is an inspector tool provided by Google that provides similar functionality to the Appium inspector tool). For more info on how to set that up, read this.

For older Android devices and apps with webviews, you can use the selendroid inspector. For more information on, go here.

There’s loads more functionality available in the inspector, but it’s outside the scope of this post. For more info I encourage you to play around with it and see what you can find out for yourself.

Outro

Now that we know how to locate elements in our app, we are ready to learn about automating some simple actions and putting them to use in our first test.

Read:  Chapter 1 Chapter 2 | Chapter 3 | Chapter 4 | Chapter 5 | Chapter 6 | Chapter 7 | Chapter 8

About Dave Haeffner: Dave is a recent Appium convert and the author of Elemental Selenium (a free, once weekly Selenium tip newsletter that is read by thousands of testing professionals) as well as The Selenium Guidebook (a step-by-step guide on how to use Selenium Successfully). He is also the creator and maintainer of ChemistryKit (an open-source Selenium framework). He has helped numerous companies successfully implement automated acceptance testing; including The Motley Fool, ManTech International, Sittercity, and Animoto. He is a founder and co-organizer of the Selenium Hangout and has spoken at numerous conferences and meetups about acceptance testing.

Follow Dave on Twitter – @tourdedave

Jason Huggins Takes a Leave of Absence at Sauce Labs to Work on HealthCare.gov 2.0

June 24th, 2014 by Bill McGee

nerds healthcare

Last year Sauce Labs cofounder Jason Huggins was part of the tech surge team of advisors who worked to fix the site and home of “Obamacare” through the power of test automation. He’s decided to take another leave of absence from Sauce to help the Ad Hoc and the Marketplace 2.0 teams to further this great cause.

Here’s what Jason had to say about the state of the government and automation:

Long term, government needs to get better at software development, including test automation. For now, the best way to fight that fight is by example. If the Marketplace 2.0 team can help the government avoid last year’s drama when open enrollment begins again in October, then we’ll have a good story to share with other departments and agencies. But if we get a repeat of last year, then it’ll be a lot harder to convince government officials to change their ways.

-Jason Huggins, June 23, 2014

Read Jason’s inspiring, original post here. You can follow his adventures on Twitter at @hugs.

While we’ll miss him around the office, we’re confident this is a worthy cause.