Date post: | 10-Oct-2014 |
Category: |
Documents |
Upload: | shehzad-lala |
View: | 449 times |
Download: | 1 times |
DeviceAnywhere AutomationTM Java Quick Start Guide
Copyright
Trademarks
Notice
Conventions used in this document The table below describes the documentation conventions. These conventions are used in all
DeviceAnywhere technical literature.
Term Meaning
Courier Courier font is used for text to be entered on a command line or in a program, or for text
output from a device.
Contents
DEVICEANYWHERE AUTOMATIONTM ..................................................................................... 1
JAVA QUICK START GUIDE ..................................................................................................... 1
1. INTRODUCTION ............................................................................................................ 4
1.1. Prerequisites ....................................................................................................... 4
1.2. Glossary of Terms ............................................................................................... 5
1.3. Recommended Workflow .................................................................................... 6
2. SETTING UP THE TUTORIAL WORKSPACE ................................................................ 6
2.1. Creating a Project in DA Studio ........................................................................... 6
2.2. Devices Used in this Tutorial ............................................................................... 8
2.3. Get Familiar with the Test Cases and Actions in Java Tutorial Project ................ 9
3. GETTING STARTED WITH ECLIPSE .......................................................................... 14
3.1. Creating a Project in Eclipse ............................................................................. 14
3.2. Creating Your First Java Test Case................................................................... 18
3.3. Executing Java Test Case in DA Studio ............................................................ 23
3.4. Executing Java Test Cases in Eclipse ............................................................... 25
3.5. Introduction to the Device API ........................................................................... 26
3.6. JavaDocs .......................................................................................................... 28
4. JAVA SCRIPTING MORE ADVANCED ........................................................................ 29
4.1. Passing Parameters to Action Calls .................................................................. 29
4.2. Reading Values from File – Data Driven Testing ............................................... 32
4.3. Calling a Test Cases from a Java Test Case ..................................................... 34
4.4. Process Results and save to XML ..................................................................... 36
4.5. Saving results to database of API executed Test Cases ................................... 47
4.6. Scheduling Runs ............................................................................................... 48
1. Introduction This guide is intended to help you get started using the using the Java scripting functionality in
the DeviceAnywhere Automation (DA) product. This document assumes that you have basic
familiarity with Visual Scripting in the DA Automation solution. The same concepts and best
practices of Visual Scripting are applicable when you begin building Test Cases and Actions in
Java. The added benefits you get when working with Java are:
• Ability to interact with other systems (databases, build machines, billing systems etc.)
required in your end to end automated test cases.
• Extend your existing test management system or automation framework to automate
testing of mobile applications
• Leverage 3rd party Java libraries
• Data driving test cases by reading in values from a text file or database
• Work in an industry-standard programming language
After completing this Guide, you will be able to:
• Implement Java Test Cases that call other Test Cases, Visual Actions and Java Actions
• Pass parameters to Test Cases, Visual Actions and Java Actions
• Implement Java Test Cases using the device API
• Edit Java Test Cases in Eclipse
• Execute Java Test Cases in Eclipse
• Use the javadocs to learn about the objects and methods that are available in the API
• Implement Java Test Cases that read values from a text file and database
1.1. Prerequisites
This document assumes that you are familiar with Visual Scripting in DA Automation. It also
assumes you understand your way around DA Studio. What you should already know how to
do before starting this tutorial:
• Setup a Project
• Implement Actions, States and Test Cases
• Execute Test Cases and Actions
• View Test Results in the Result Portal
• Acquire and interact with devices
If you don’t know how to do the tasks listed above, you can go through the following documents
to get up to speed before staring this Tutorial:
• DeviceAnywhere Test Center QuickStart Guide
• DeviceAnywhere Test Automation Getting Started
• DeviceAnywhere 5.0 Test Automation Best Practices
1.2. Glossary of Terms
The following terms will be used frequently throughout the document.
Project—An organization container for all test assets associated with that project,
including test cases, step groups, actions, states, and a device list.
Test Case – A Test Case is a script designed to validate one or more of your test
requirements. It is intended to be executable on any device in your project. It therefore
recommended that a test case only consists of calls to Actions and States and any control
logic (looping, branching) required to execute the end to end test case.
Action – An action is a sub-component of a test case. The use of actions is recommended
to make test cases able to execute on all devices in a project. An action is a step or set of
steps that applies to all devices in your project. Examples of commonly used Actions
are; Reset Device, Launch Browser, Go To URL, Send SMS etc.
Action Implementation — The Action Implementation is the device specific set of key
presses, touch events, gestures, checkpoints and or logic required to automate an Action
for the device under test.
Action Selection – The DA Automation framework will automatically select the Action
Implementation. The applies when running tests from within DA Studio or when
calling test cases and actions from your Java execution environment.
Visual Action – An Action can be implemented using the visual scripting editor or using
Java scripting. When an Action is implemented using the visual scripting editor, it is
referred to as a Visual Action.
Java Action - An Action can be implemented using the visual scripting editor or using
Java scripting. When an Action is implemented using Java scripting, it is referred to as a
Java Action.
Visual Test Case - A Test Case can be implemented using the visual scripting editor or
using Java scripting. When a Test Case is implemented using the visual scripting editor,
it is referred to as a Visual Test Case.
Java Test Case - A Test Case can be implemented using the visual scripting editor or
using Java scripting. When a Test Case is implemented using the visual scripting editor,
it is referred to as a Java Test Case.
State—A state represents a known device condition using reference screen image or
screen text.
Proof—screen capture or video of device taken during testing to validate that an
expected test result was achieved. Proofs may be captured manually or via an
automated script.
Java State – Java code that identifies a known condition. Typically used to identify a
condition NOT on a device (e.g. to enable a test on an application that interacts with a
device).
1.3. Recommended Workflow
When using Java scripting to develop your automated tests, the recommend approach is to:
• Create a Project in DA Studio
• Create a Project in your IDE of choice and configure the project to share the same
workspace as the DA Studio Project
• Implement Visual Actions using in the visual scripting editor
• Implement Java Test Cases in an IDE by calling Actions that were developed in DA
Studio
• Execute Java Test Cases in the IDE or in DA Studio
• View test results in the Result Portal
2. Setting up the Tutorial Workspace This section is a required setup phase for the remainder of the tutorial. Because this tutorial
assumes you are familiar with basic DA scripting concepts, you will import an existing project
containing Actions, States and a Visual Test Cases that have already been implemented. In this
section, you will get familiar with the Visual Test Cases and Visual Actions that are used
throughout the remainder of the tutorial.
2.1. Creating a Project in DA Studio
To setup the tutorial project, you will import the Java_Tutorial.zip project. If you do not have
this example project, contact [email protected]. The remainder of this tutorial
will use Visual Test Cases, Visual Actions, Java Test Cases, Java Actions, States and Java States in
this project.
Step 1: Right click in the Project frame and select Import Project.
Step 2: Browse the file system to the location of the Java_Tutorial.zip file.
Step 3: Name the project Java Tutorial, use DeviceAnywhere Version Control and make the
project viewable and editable by all users in your account.
Step 4: Open the project and you should see the Java Tutorial project.
2.2. Devices Used in this Tutorial
The examples included in the Java Tutorial are for the Apple iPhone 3G and the Blackberry
Curve (8530). The devices are included in the Test Automation Trial package in the
DeviceAnywhere shared environment. If you don’t have access to these devices because you are
working in a dedicated environment, it is recommended that you add one or two of your local
devices to the Java Tutorial project and implement the Actions, States and Test Cases that are
used in this tutorial.
2.3. Get Familiar with the Test Cases and Actions in Java Tutorial Project
In this section, we examine the Visual Actions that will be used for the remainder of the Tutorial.
Step 1: Play the Apple iPhone 3G Action Implementation of ‘Reset to Home’.
Step 2: Highlight the Action ‘Send SMS’ and select Properties.
Step 3: Edit the existing parameter ZipCode and you will see the following dialog box. This is the
definition of the ZipCode parameter and also where the Default value is set.
Step 4: Double click the ‘Type Zip’ command in the ‘Send SMS’ Action Implementation for the
iPhone. The Text to Send is populated with %ZipCode%. When the Action is called or executed,
this is how the parameter passed in is used within the Action Implementation. The percentage
‘%’ before and after are used to mark this as a variable and the DA Automation engine inserts the
passed in value at runtime.
Step 5: Play the Apple iPhone 3G Action Implementation of ‘Send SMS’. This Action has been
implemented to send a zip code to the weather.com short code 42278. When you play this
Action, a dialog box will appear allowing you to enter a zip code. The default value is 94402 but
feel free change it.
Step 6: Open the ‘Verify Result’ Action Implementation for the iPhone. Look at the Verify
Correct Forecast command. It is a WaitText command that takes a parameter %City%. Because it
is parameterized, you can pass in values from Visual Test Cases and Java Test Cases. We will use
this Action later in this Tutorial when covering passing parameters to Actions from Java Test
Cases and also when demonstrating data driven testing in Java.
Step 7: Play the ‘Verify Result’ Action Implementation for the iPhone. If you changed the default
Zip Code in Step 5 above, you should update the City parameter to make the Action run
successfully.
Step 8: Open the Verify Forecast Test Case
Step 9: View the Send Message ExecuteAction command. Notice that this command takes a
parameter for %ZipCode%. When an ExecuteAction command is called from the Visual Test
Case, the zip code is passed in. Also in the ExecuteAction command, you can specify the proof
capture type for the Action.
Step 10: Play the Test Case. The Test Case should run through to completion.
Step 11: Optional - Repeat steps 1-8 for Blackberry 8530 device.
You have now finished setting up the environment you will use for the remainder of the tutorial.
3. Getting Started with Eclipse DA Studio includes a built in Java editor to develop Java Test Cases. The Java editor is good for
creating basic scripts but doesn’t have many of the ease-of-use features that a commercial IDE
has. DA Studio has designed the solution so that Java Test Cases can be edited in Eclipse or most
other Java IDEs. This section will cover:
• Creating a Project in Eclipse and Configuring it with the DA Studio Workspace
• Editing a Java Test Case
• Executing a script in DA Studio
• Executing a script in Eclipse
3.1. Creating a Project in Eclipse
This document is intended to be used as a guide for configuring the Eclipse IDE for use with
DeviceAnywhere Studio to edit java-based test cases and actions created within the
DeviceAnywhere Studio software. This document assumes that you already have
DeviceAnywhere Studio installed, Eclipse installed, and you currently have a DeviceAnywhere
Test Automation License, and a valid DeviceAnywhere Test Center subscription.
Step 1: Launch Eclipse, and create a new Java Project
Note: If this is the first time you are launching Eclipse, please ensure you DO NOT set
your Eclipse workspace folder to the “workspace” folder inside DeviceAnywhere Studio.
This will cause problems when trying to use DeviceAnywhere Studio, as well as Eclipse.
Step 2: Leave the project name blank, and choose “Create project from existing source” and click
Browse…
Step 3: Browse to the project folder on your local disk. For this document, we will be using a
project called “Java Tutorial” under the login “[email protected]”. The path for this project is
as follows:
C:\Program Files\Mobile Complete\DeviceAnywhereStudio\workspaces\yourDAUsername\my_java_tutorial
Step 4: Once you have selected the folder, click OK and then choose Next and then Finish. This
will import the project directory structure. You may notice that the structure is not the same as
within DeviceAnywhere Studio.
Step 5: To view the directory structure in a similar fashion as DeviceAnywhere Studio, change
the package presentation to “Hierarchical”
You have now successfully configured Eclipse for editing your java test cases within Eclipse.
3.2. Creating Your First Java Test Case
Your Eclipse project is now configured to be the editor for scripting Java Test Cases and Java
Actions for your DA Studio project. In this section, you will create your first Java Test Case.
Step 1: In DA Studio, create a Java Test Case
Name the Java Test Case, ‘My First Java Test Case’
You should know see the Java Test Case editor in DA Studio. If you are familiar with Java and
the methods available in the device API, you can use DA Studio to edit test scripts. For ease of
use, we recommend using Eclipse or some other IDE to develop Java Test Cases.
Step 2: In Eclipse, refresh your project. After the refresh, you will see My First Java Test Case in
the project.
Step 3: Double click to open the Java Test Case
Step 4: Scroll to the bottom of the test case and put the cursor in the execute method.
Step 5: Start typing the first few characters of ‘Reset to Home’ and press the CTRL key and the
space bar simultaneously. This will bring up a menu of available objects. Because the Eclipse
project uses the same workspace as DA Studio, the Actions, States and Test Cases, are all
available in your Eclipse editor. Select the Reset to Home object.
Step 6: After inserting the Reset_to_Home, add the .instance.execute(device). This is the syntax
to call a Visual Action from a Java Test Case. Repeat the steps for Send SMS and Verify Forecast.
Once you are done, your code Java Test Case should look as follows:
@Override
protected ScriptReturn execute(Device device, IScriptContext
context) throws ScriptFailureException, InterruptedException,
DeviceExecutionException
{
Reset_to_Home.instance.execute(device);
Send_SMS.instance.execute(device);
Verify_Forecast.instance.execute(device);
return SUCCESS();
}
At the top of the Java Test Case, you will see the import statement for the Reset_to_Home action
is added to the Java Test Case automatically.
Step 7: Save your Java Test Case in Eclipse
Step 8: Go back to DA Studio and you will see the lines that you added to the Java Test Case from
the Eclipse editor and also displayed within DA Studio.
Lessons
- You can use an IDE such as Eclipse to edit your Java Test Cases by creating a project in
Eclipse that shares the same project files as your DA Studio workspace.
- Actions that were created in DA Studio can be called from a Java Test Case. Using this
approach you can leverage the easy to use Visual Scripting to rapidly implement Actions
in DA Studio and the power of Java to enhance your end to end test scenarios.
- By creating Java Test Cases that call Actions that are created in DA Studio, your test cases
can now be run on any device that has completed Action Implementations
3.3. Executing Java Test Case in DA Studio
Step 1: Select the device you would like to use to execute the test case.
Step 2: Press the Run button to execute that Java Test Case
Step 3: Press the View Result Link
Step 4: Press Upload Result button
Step 5: View the Test Results in the Result Portal
Lessons
- Test cases developed in Eclipse can be executed in DA Studio
- Test results for Java Test Cases are the same as Visual Test Cases
3.4. Executing Java Test Cases in Eclipse
Step 1: Open My First Java Test Case in Eclipse
Step 2: You will need to create a Run Configuration inside Eclipse for the test case you would like
to execute. For this document, we will use a test case called “My First Java Test Case”
Step 3: You will need to define 2 variables before Eclipse will successfully execute test cases.
These can be defined in the Arguments section of the run configuration.
The program argument is the MCD of the device. For this example, we are using MCD 4616. You
can find the MCD of a device inside DeviceAnywhere Studio by right-clicking on that device and
clicking Device Info:
The MC_HOME VM argument passes the DeviceAnywhere Studio directory to the JVM, which
allows DeviceAnywhere classes to find required resources at runtime:
-DMC_HOME=“C:\Program Files\Mobile Complete\DeviceAnywhereStudio”
Once these have been set, you will be able to run your test cases directly from Eclipse by choosing
run as, and selecting the run configuration you have created.
Step 4: Press the Run button in the Eclipse toolbar
Step 5: View the execution log in Eclipse
3.5. Introduction to the Device API
In this section, you will create an end to end test cases in Eclipse without calling any Actions that
were implemented in DA Studio. This example is created for a Blackberry Curve device.
Step 1: In DA Studio, create a Java Test Case called ‘Intro to Device API’
Step 2: Open the test case in Eclipse
Step 3: Type ‘device.se’ in the Java Test Case in Eclipse to get a drop down of all the methods
available in the Device object. Select the first instance of sendKeys.
Step 4: After selecting the first instance of sendKeys, add the keys and the mode to the code.
When complete it should look as follows.
Step 5: After sending [End][End][End] to the device, the device should be on the Home Screen.
From your Java Test Case, you can verify the device is at the Home Screen by using the WaitFor
Method to call into your State definition for the Home Screen.
Step 6:
3.6. JavaDocs
The latest Javadocs can be found at the following location:
http://dademo1.deviceanywhere.com/javadocs
4. Java Scripting More Advanced
4.1. Passing Parameters to Action Calls
- Pass in parameters to the Send SMS action using the ActionHelper.
- Call Reset Device
- Call Send SMS with ZipCode parameter
- Verify Result with ExpectedCity parameter
In Java TestCases action call can be passed parameters using Action Helper. How it is done is
shown below:
Step 1: First create a Visual Action with parameters. To add parameter to Action right click
on action name and then choose parameter.
Step 2: Now do your visual scripting in the created Action. Call Parameters in appropriate
SendKey Commands. Its written in SendKeys in between %Zip%.
Step 3: Create object of type ActionHelper.
ActionHelper myHelper = new ActionHelper();
Step 4: Set parameters using setParameter() method.
myHelper.setParameter("Number",”42278” );
myHelper.setParameter("Zip", “94402”);
myHelper.setPrimaryDevice(device);
The String Name in “myHelper.setParameter” should always be same as of Visual Action
Parameter.
Step 5: Execute Send_SMS Action in Testcase using ActionHelper object as argument.
Send_SMS.instance.execute(myHelper);
4.2. Reading Values from File – Data Driven Testing
- Read files from CSV file and pass them into Action call from Java Test Case
- Do the s
Step 1: Read data from file which has to be passed to Action call.
String inputFileName="D:/ZipCodes.csv";//Grabs ZIP codes from file
s = new Scanner(new BufferedReader(new FileReader(inputFileName)));
s.useDelimiter(",");
Step 2: Execuete Reset_to_Home Action.
Reset_to_Home.instance.execute(device);
Step 3: Create object of type ActionHelper.
ActionHelper myHelper = new ActionHelper();
Step 4: Set ActionHelper object parameters using setParameter() method.
myHelper.setParameter("Zip", zipCode);
myHelper.setParameter("City", City);
myHelper.setPrimaryDevice(device);
The String Name in “myHelper.setParameter()” should always be same as of Visual Action
Parameter (in this case Send_SMS).
Step 3: Execute Send_SMS Action in Testcase using ActionHelper object as argument.
Send_SMS.instance.execute(myHelper);
Step 4: Execute Verify_Result Action in Testcase using ActionHelper object as argument.
Verify_Result.instance.execute(myHelper);
4.3. Calling a Test Cases from a Java Test Case
- Call a sequence of Java Test Cases
Java Testcase can also be called in another Java Testcase.
Step 1: First create Java Test case which will be called in another Java Test case. Here in this
example a Java Testcase is created in which Text is extracted from received SMS. This extracted
text is saved to a String and this String is put in to Context, which is returned as ScriptReturn. In
this way the extracted text can be used in Action/Testcase in which this test case is called.
Step 2: Calling Testcase in a Testcase – First create an instance of called Testcase. Then execute
called Testcase using execute() method.
Step 3: Getting saved Context (extracted Text) from called Testcase and save extracted text to a
String.
Step 4: String manipulation – searching for City name in extracted String. If City name is found in
extracted string SUCCESS() is returned otherwise FAIL() is returned.
4.4. Process Results and save to XML
The sample code below shows how to execute a test case from the API, get the result, and
process it. If the result indicates a failure, the sample code does 3 things:
1. Save the result to the database
2. Traverse all steps to find the images captured before and after the failed step (these are
saved to disk)
3. Traverse all steps and generate an XML with the result structure (this is saved to disk)
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Collection;
import java.util.LinkedList; import java.util.List;
import javax.imageio.ImageIO;
import org.apache.xerces.dom.DOMImplementationImpl;
import org.apache.xerces.dom.DocumentImpl;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.ls.DOMImplementationLS;
import org.w3c.dom.ls.LSOutput; import org.w3c.dom.ls.LSSerializer;
import com.mc.api.common.GlobalContext;
import com.mc.api.device.Device;
import com.mc.api.device.exception.DeviceExecutionException;
import com.mc.api.device.exception.NoSuchDeviceException;
import com.mc.api.script.ScriptReturn;
import com.mc.api.script.ScriptReturn.ScriptReturnCode;
import com.mc.api.script.exception.ScriptFailureException;
import com.mc.api.script.result.ResultManager;
import com.mc.api.script.result.ScriptResult;
import com.mc.api.script.result.ScriptResultProof;
import com.mc.api.script.result.ScriptResultStep;
import com.mc.api.script.result.ScriptResultProof.ProofType; import com.mc.api.testcase.TestCase;
public class SampleCode
{ private static final String SCRIPT_RUN_KEY = "scriptRun";
private static final String SCRIPT_KEY = "script";
private static final String SCRIPT_NAME_KEY = "name";
private static final String SCRIPT_PATH_KEY = "path";
private static final String SCRIPT_DESCRIPTION_KEY = "description";
private static final String SCRIPT_STATUS_KEY = "status";
private static final String SCRIPT_LOCATION_KEY = "location";
private static final String SCRIPT_START_TIME_KEY = "start";
private static final String SCRIPT_STOP_TIME_KEY = "stop";
private static final String STEP_KEY = "step";
private static final String STEP_NAME_KEY = "name";
private static final String STEP_PATH_KEY = "path";
private static final String STEP_DESCRIPTION_KEY = "description";
private static final String STEP_STATUS_KEY = "status";
private static final String STEP_LINE_NUMBER_KEY = "lineNumber";
private static final String STEP_START_TIME_KEY = "start";
private static final String STEP_STOP_TIME_KEY = "stop";
public static void main(String[] args) throws NoSuchDeviceException,
ScriptFailureException
{
executeTestCase();
}
public static void executeTestCase() throws NoSuchDeviceException,
ScriptFailureException
{ // get the test case and device
// TODO: replace these references
TestCase testCase = com.mobilecomplete.cl.test_cases.a.a.instance; Device device = Device.get(121);
// lock the device
if (device != null) device.lock();
try
{
// execute the test case ScriptResult result = testCase.execute(device);
// print the result System.out.println(testCase.getClass().getName() + " Result is: " + result);
// find failure step (if any)
ScriptResultStep failedStep = findFailedStep(result);
if (failedStep != null)
{
// the test case failed
System.err.println("Test case " + testCase + " failed on step " + failedStep);
// upload result to database
ResultManager manager = new
ResultManager(GlobalContext.getGlobalContext());
manager.saveToDatabase(result);
// save the last images that were captured from the device before the failure
saveFailedImages(device, result, failedStep);
// generate result XML
saveResultXML(result);
}
}
finally
{
// unlock the device
if (device != null)
device.unlock();
} }
private static ScriptResultStep findFailedStep(ScriptResultStep result)
{
ScriptResultStep failedStep = null;
// loop through all steps and find the last failed step
for (ScriptResultStep step : result.getChildSteps())
{
// see if we can find a nested failure ScriptResultStep nestedStep = findFailedStep(step);
// if there was a nested failure, save it
if (nestedStep != null)
failedStep = nestedStep;
// if no nested failure was found but the step failed, save this step
else if (step.getScriptReturnCode() == ScriptReturnCode.FAIL)
failedStep = step; }
// if we found a nested failure, return it
if (failedStep != null)
return failedStep;
// no nested failure found
else if (result.getScriptReturnCode() == ScriptReturnCode.FAIL)
return result;
else
return null;
}
private static void saveFailedImages(Device device, ScriptResult result,
ScriptResultStep failedStep)
{
// print out information about the failed step
System.out.println(result.getScriptPath() + " failed at " + failedStep.getStepPath() + " in script " + failedStep.getScriptPath());
// find the image proofs before and after the failure (if they exist)
ScriptResultProof beforeProof = findLastImageBeforeStep(result, failedStep); ScriptResultProof afterProof = findNextImageAfterStep(result, failedStep);
if (beforeProof != null && beforeProof.getData().length > 0)
{
// format the image
String format = beforeProof.getFormat();
BufferedImage image = formatImage(beforeProof.getData()[0]);
String file = "before." + format;
System.out.println("found image before failed step " + failedStep.getStepPath() + "; saving to file " + file);
// save it to disk
try { ImageIO.write(image, format, new File(file)); }
catch (Exception e) { e.printStackTrace(); }
}
else
System.out.println("unable to find image before failed step " + failedStep.getStepPath());
if (afterProof != null && afterProof.getData().length > 0)
{
// format the image
String format = afterProof.getFormat();
BufferedImage image =
formatImage(afterProof.getData()[afterProof.getData().length - 1]);
String file = "after." + format;
System.out.println("found image after failed step " + failedStep.getStepPath() + "; saving to file " + file);
// save it to disk
try { ImageIO.write(image, format, new File(file)); }
catch (Exception e) { e.printStackTrace(); }
}
else
{
try
{
// capture the current image from the device
String format = "jpeg";
BufferedImage image = device.getCurrentImage();
String file = "after." + format;
System.out.println("captured latest image from device " + device.getID() + ";
saving to file " + file);
// save it to disk
ImageIO.write(image, format, new File(file));
}
catch (DeviceExecutionException e) { e.printStackTrace(); }
catch (IOException e) { e.printStackTrace(); }
}
}
private static ScriptResultProof findLastImageBeforeStep(ScriptResult result,
ScriptResultStep currentStep)
{
ScriptResultProof lastProof = null;
// first see if the current step contains before and after images. if so, we're done
Collection<ScriptResultProof> proofs = currentStep.getProofs();
for (ScriptResultProof proof : proofs)
{
// if we found an image sequence capture, return the first one
if (proof.getProofType() == ProofType.IMAGE_SEQUENCE &&
proof.getData().length > 1)
return proof;
// if we found multiple image captures, return the first one
else if (proof.getProofType() == ProofType.IMAGE && lastProof != null &&
lastProof.getProofType() == ProofType.IMAGE)
return lastProof;
// otherwise keep track of this image proof
else if (proof.getProofType() == ProofType.IMAGE)
lastProof = proof; }
// if the current step does not have image captures, find the last step before it that
does
ScriptResultStep lastStepWithImageProof = findLastStepWithImageProof(result,
currentStep, null);
lastProof = null;
if (lastStepWithImageProof != null)
{
// if we found a step with image proofs before the failure, get the last proof
for (ScriptResultProof proof : lastStepWithImageProof.getProofs())
{
if (proof.getProofType() == ProofType.IMAGE || proof.getProofType() ==
ProofType.IMAGE_SEQUENCE)
lastProof = proof;
} }
// and return
return lastProof;
}
private static ScriptResultStep findLastStepWithImageProof(ScriptResultStep
currentStep, ScriptResultStep failedStep, ScriptResultStep lastStep)
{
if (currentStep == failedStep)
return lastStep;
// go through every step and get the captured images, until we reach the failed
step
for (ScriptResultStep step : currentStep.getChildSteps())
{
// if this is a step that contains the failed step...
if (contains(step, failedStep))
{
// recursively find the last step and return
lastStep = findLastStepWithImageProof(step, failedStep, lastStep);
break;
}
else
{
// otherwise, just find the last step with image proofs
Collection<ScriptResultProof> proofs = step.getProofs();
for (ScriptResultProof proof : proofs)
{
// if this step has image proofs, keep track of it
if (proof.getProofType() == ProofType.IMAGE || proof.getProofType() ==
ProofType.IMAGE_SEQUENCE)
{
lastStep = step;
break;
}
}
lastStep = findLastStepWithImageProof(step, failedStep, lastStep);
} }
return lastStep;
}
private static ScriptResultProof findNextImageAfterStep(ScriptResult result,
ScriptResultStep currentStep)
{ ScriptResultProof lastProof = null;
// first see if the current step contains before and after images. if so, we're done Collection<ScriptResultProof> proofs = currentStep.getProofs();
for (ScriptResultProof proof : proofs)
{
// if we found an image capture, return the last one
if (proof.getProofType() == ProofType.IMAGE || proof.getProofType() ==
ProofType.IMAGE_SEQUENCE)
lastProof = proof;
}
if (lastProof == null)
{
// if the current step does not have image captures, find the next step after it that
does
ScriptResultStep nextStepWithImageProof = findNextStepWithImageProof(result,
currentStep);
if (nextStepWithImageProof != null)
{
// if we found a step with image proofs after the failure, get the first proof
for (ScriptResultProof proof : nextStepWithImageProof.getProofs())
{
// if we found an image capture, return the first one
if (proof.getProofType() == ProofType.IMAGE || proof.getProofType() ==
ProofType.IMAGE_SEQUENCE)
{
lastProof = proof;
break;
}
}
}
}
return lastProof;
}
private static ScriptResultStep findNextStepWithImageProof(ScriptResultStep
currentStep, ScriptResultStep failedStep)
{
ScriptResultStep nextStep = null;
boolean passedStep = false;
for (ScriptResultStep step : currentStep.getChildSteps())
{
// if the current step contains the failed step, find a step after the failed step with
an image capture
if (contains(step, failedStep))
{ nextStep = findNextStepWithImageProof(step, failedStep);
passedStep = true; }
// ignore any steps before the failed step
else if (passedStep)
{ nextStep = findNextStepWithImageProof(step, failedStep);
// if we did not find a nested step with image proofs, see if this step has any
if (nextStep == null)
{
Collection<ScriptResultProof> proofs = step.getProofs();
for (ScriptResultProof proof : proofs)
{
// if this step has image proofs, return it
if (proof.getProofType() == ProofType.IMAGE || proof.getProofType() ==
ProofType.IMAGE_SEQUENCE)
{
nextStep = step;
break;
}
}
}
}
if (nextStep != null)
break;
}
return nextStep;
}
private static boolean contains(ScriptResultStep step, ScriptResultStep childStep)
{
if (step == childStep) return true;
for (ScriptResultStep nestedStep : step.getChildSteps())
{
if (contains(nestedStep, childStep))
return true;
}
return false;
}
private static BufferedImage formatImage(byte[] b)
{
try
{
return ImageIO.read(new ByteArrayInputStream(b));
}
catch (IOException e)
{
e.printStackTrace();
return null;
} }
private static void saveResultXML(ScriptResult result)
{
// create XML elements
Document document = new DocumentImpl();
Element root = document.createElement(SCRIPT_RUN_KEY); Element script = createScriptElement(result, document);
// build XML structure
root.appendChild(script);
document.appendChild(root);
// write document to file
File file = new File("result.xml");
try
{
FileOutputStream stream = new FileOutputStream(file);
DOMImplementationLS ls = new DOMImplementationImpl();
LSOutput output = ls.createLSOutput(); output.setByteStream(stream);
// TODO: format result
LSSerializer serializer = ls.createLSSerializer();
serializer.getDomConfig().setParameter("format-pretty-print", true); serializer.write(script, output);
stream.flush();
stream.close();
System.out.println("saved result to " + file.getAbsolutePath() );
}
catch (IOException e)
{
e.printStackTrace();
} }
private static Element createScriptElement(ScriptResult result, Document document)
{
// create XML elements
Element scriptElement = document.createElement(SCRIPT_KEY);
Element descriptionElement =
document.createElement(SCRIPT_DESCRIPTION_KEY); Node description = document.createTextNode(SCRIPT_DESCRIPTION_KEY);
// build XML structure
descriptionElement.appendChild(description); scriptElement.appendChild(descriptionElement);
// get hostname where test case was run
String hostname = "Unknown Host";
try { hostname = InetAddress.getLocalHost().getHostName(); } catch (UnknownHostException e) { e.printStackTrace(); }
// set script attributes
scriptElement.setAttribute(SCRIPT_PATH_KEY, "" + result.getScriptPath());
scriptElement.setAttribute(SCRIPT_START_TIME_KEY, "" +
result.getStartTimestamp());
scriptElement.setAttribute(SCRIPT_STOP_TIME_KEY, "" +
result.getEndTimestamp());
scriptElement.setAttribute(SCRIPT_LOCATION_KEY, "" + hostname );
scriptElement.setAttribute(SCRIPT_NAME_KEY, result.getScriptPath());
scriptElement.setAttribute(SCRIPT_STATUS_KEY,
result.getScriptReturnCode().toString());
// get description
ScriptReturn scriptReturn = result.getReturn(); String strDescription = scriptReturn.getMessage();
if (!scriptReturn.isSuccess() && scriptReturn.getScriptException() != null)
{
// if the script threw an exception, save the stack trace in the description
Exception e = scriptReturn.getScriptException();
StringWriter stringWriter = new StringWriter();
e.printStackTrace(new PrintWriter(stringWriter));
strDescription += "\n" + e.getMessage() + ":\n" + stringWriter.toString(); }
// set description description.setNodeValue(strDescription);
// create step elements
for (Element step : createStepElements(result, document))
{
scriptElement.appendChild(step); }
return scriptElement; }
private static List<Element> createStepElements(ScriptResultStep parentStep,
Document document)
{
List<Element> stepElements = new LinkedList<Element>();
for (ScriptResultStep step : parentStep.getChildSteps())
{
// create XML elements
Element stepElement = document.createElement(STEP_KEY);
Element descriptionElement =
document.createElement(STEP_DESCRIPTION_KEY);
Node description = document.createTextNode(STEP_DESCRIPTION_KEY);
// build XML structure
descriptionElement.appendChild(description);
stepElement.appendChild(descriptionElement);
// set step attributes
stepElement.setAttribute(STEP_NAME_KEY, step.getStepPath());
stepElement.setAttribute(STEP_STATUS_KEY, "" + step.getScriptReturnCode());
stepElement.setAttribute(STEP_START_TIME_KEY, "" +
step.getStartTimestamp());
stepElement.setAttribute(STEP_STOP_TIME_KEY, "" + step.getEndTimestamp());
stepElement.setAttribute(STEP_PATH_KEY, "" + step.getScriptPath());
stepElement.setAttribute(STEP_LINE_NUMBER_KEY, "" + step.getPosition());
// get description
description.setNodeValue(step.getDescription());
for (Element childElement : createStepElements(step, document))
{
stepElement.appendChild(childElement); }
// add to the list
stepElements.add(stepElement);
}
return stepElements;
} }
4.5. Saving results to database of API executed Test Cases
The code below displays how to make a call to a test case and write the results to the
DeviceAnywhere database.
package com.mobilecomplete.example.test_cases;
import com.mc.api.device.Device;
import com.mc.api.device.exception.DeviceExecutionException;
import com.mc.api.script.exception.ScriptFailureException;
import com.mc.api.script.IScriptContext;
import com.mc.api.script.result.ScriptResult;
import com.mc.api.script.ScriptReturn;
import com.mc.api.testcase.TestCase;
import com.mc.api.common.GlobalContext;
import com.mc.api.script.result.ResultManager;
public class CallTestCaseWithResults extends TestCase
{
/*** GENERATED CODE -- DO NOT MODIFY (ANY CHANGES WILL BE
OVERWRITTEN) ***/
public static final CallTestCaseWithResults instance = new CallTestCaseWithResults();
private CallTestCaseWithResults()
{
super();
}
/**
* @param args
* @throws ScriptFailureException
*/
public static void main(String[] args) throws ScriptFailureException
{
// get the devices
Device primaryDevice = getPrimaryDeviceFromArgs(args);
// lock all devices
primaryDevice.lock();
TestCase testCase = CallTestCaseWithResults.instance;
try
{
ScriptResult result = testCase.execute(primaryDevice); System.out.println(testCase.getClass().getName() + " Result is: " + result);
ResultManager manager = new
ResultManager(GlobalContext.getGlobalContext().getDataAccess());
manager.saveToDatabase(result);
}
finally
{
// unlock all devices primaryDevice.unlock();
} }
/*** END GENERATED CODE ***/
@Override
protected ScriptReturn execute(Device device, IScriptContext context) throws
ScriptFailureException, InterruptedException, DeviceExecutionException
{
TestCase testCase = com.mobilecomplete.example.test_cases.tc1.tc1.instance;
testCase.execute(device);
return SUCCESS();
}
}
4.6. Scheduling Runs
The example code below displays how to schedule runs periodically in Java. The run method
below will need to be filled with the call to the testcase(s).
// create a runnable to execute the script Runnable script = new Runnable() { @Override
public void run() {
// TODO call script here } };
// create an executor service to schedule the script ScheduledExecutorService scheduler =
Executors.newSingleThreadScheduledExecutor();
// schedule the script to run every 10 minutes scheduler.schedule(script, 10, TimeUnit.MINUTES);