Thursday 30 August 2012

Root Cause Analysis


Root Cause Analysis nothing but analyzing possible risks raised during testing. This is done by Test Lead.

When we detect failures, we might try to track them back to their root cause, the real reason that they happened. There are several ways of carrying out root cause analysis, often involving a group brainstorming ideas and discussing them, so you may see different techniques in different organizations.

For example, suppose an organization has a problem with printing repeatedly failing. Some IT maintenance people get together to examine the problem and they start by brainstorming all the possible causes of the failures. Then they group them into categories they have chosen, and see if there are common underlying or root causes. Some of the obvious causes they discover might be:


  • Printer runs out of supplies (ink or paper).
  • Printer driver software fails.
  • Printer room is too hot for the printer and it seizes up.


These are the immediate causes. So in this way root cause analysis is a problem solving approach.

Tuesday 7 August 2012

Conditional statements (MonkeyTalk)


IF statement (Javascript form):
For using conditions like the IF we need to modify the javascript form of the code and add new code to the existing javascript. While this makes the script more powerful, one cannot return to the old regular MonkeyTalk script form. In order to export the script click on the javascript tab at the bottom of the editor window in MonkeyTalk IDE and then click on Export button at the top.

We will illustrate the use of If statement by using two scripts, driver and driven. The driver script will pass the username and password to the driven script twice (two iterations). In one of the iteration the password is invalid and therefore the page will throw error. The driven script verifies if that error exists and then executes certain part of the code else it executes some other part of the code.

Driver Script
Script ae.js Run username1 p1
Script ae.js Run username1 pass2

Driven Script
load("libs/<monkeytalk_project_name>.js");
<monkeytalk_project_name>.<driven_script_name>.prototype.run = function(user, pass) {
                    this.app.input("username").enterText(user);
                    this.app.input("password").enterText(pass);
                    this.app.button("LOGIN").tap();
                    var a = this.app.label("login_err").get("a");
                    /*
                     * The get() function returns a string which
                     * is displayed on the label having id as "login_err"
                     * This element is always displayed on the screen.
                     * When the login page throws no error the string is void
                     * i.e. it is equal to ""
                     * This returned string is stored in variable 'a'
                     */
                                if(a == "Sorry! Password must be 4 or more characters.")
                                                /*
                                                 *  The if statement, tests if the string captured in a
                                                 *  is equal to the same error message.
                                                 * 
                                                 *  If value returned is TRUE then
                                                 *  new set of username and passwords are entered followed
                                                 *  by user clicking the "forms" tab and then the "login" tab
                                                 * 
                                                 *  If value returned is FALSE then the user is logged in
                                                 *  and all we need to do is logut the user. Followed by
                                                 *  user clicking the "hierarchy" tab and then the "login" tab
                                                 */ 
                                {
                                                this.app.input("username").tap();
                            this.app.input("username").enterText("new username");
                            this.app.input("password").enterText("new password");
                            this.app.button("LOGIN").tap();
                            this.app.button("LOGOUT").tap({thinktime:"3000"});
                                                this.app.tabBar().select("forms", {thinktime:"3000"});
                                                this.app.tabBar().select("login", {thinktime:"3000"});
                        }
                        else
                        {
                                this.app.button("LOGOUT").tap({thinktime:"3000"});
                                                this.app.tabBar().select("hierarchy", {thinktime:"3000"});
                                                this.app.tabBar().select("login", {thinktime:"3000"});
                        }
};

Variable declaration:-
Variables can be initialized at the time of declaration:

Vars * Define usr=john pw=smith
Input username EnterText ${usr}
Input password EnterText ${pw}

The above script will enter john as username and smith as password.

However, if the above script is being driven by a driver script (as mentioned in example 2), which passes arguments then the values provided as arguments in the driver script trump the ones defined in the above script. Example:

Script driven.mt Run albert einstein

Also, mentioned in example 2 is that if a driver script only passes one argument then it is replaces the values stored in the first declared variable and the second one remains as it is.

Script driven.mt Run albert

Passing variable values through driver script (MonkeyTalk)


Value for variables can be passed as arguments in a driver script. The only requirement is that they should be provided in the same order as they are declared. We have two scripts here one is the main code (driven) script and the driver script.

MonkeyTalk form:-
Driven script
Vars * Define pass user
Input username EnterText ${user}
Input password EnterText ${pass}
Button LOGIN Tap %thinktime=500
Button LOGOUT Tap %thinktime=3000

Driver Script
Script <driven_script_name>.mt Run username1 "password1"
Script <driven_script_name>.mt Run username2 "password2" %thinktime=3000
Test message

Javascript form:
Driven script
load("libs/<monkey_talk_project_name>.js");
<monkey_talk_project_name>.<driven_script_name>.prototype.run = function(pass, user) {
                this.app.input("username").enterText(user);
                this.app.input("password").enterText(pass);
                this.app.button("LOGIN").${empty}({thinktime:"500"});
                this.app.button("LOGOUT").${empty}({thinktime:"3000"});
};

Driver script
load("libs/<monkey_talk_project_name>.js");
<monkey_talk_project_name>.<driver_script_name>.prototype.run = function() {
                this.app.<dri>().run("john1", "password1");
                this.app.gj1().run("john2", "password2", {thinktime:"3000"});
};

Think Time at the end of second line of the driver script is important because when a script is executed the second time the first script needs some time to process the logout operation before starting the second script. Likewise, we can also provide a think time to the first script if it were to be followed by a test setup method/script while requires some processing.

Order of variables: It can be observed that in the driven script the password variable is declared first followed by the username variable. So all the values passed in as the first argument in the driver script are assigned to the pass variable. Although one might want to believe that since user variable is used first in the script the first value passed as argument would be the assigned to user, that is NOT correct.

Variables values that contain spaces can also be passed using the driven script. To prevent the space within the variable value from being interpreted as a separator between two arguments, one has to pass the argument within double quotes. For example: one can pass a password as “this is my password”

Datadriven Script (MonkeyTalk)


This basically requires three files all placed in the root folder of your MonkeyTalk Project.

1.  MonkeyTalk code script. This is the one where you all the automation code.
2.  A driver script. This script is the one which we will run to execute the test. This script just calls the main MonkeyTalk code script and passes a csv (comma separated value) file with it. Think of this script as a main method in a java class file which is invoked first and others are invoked as the thread of main method progresses
3. CSV file. This file contains all the arguments that you want to pass for each variable in the driven script. The order of the

Main MonkeyTalk code script (or the driven script) in MonkeyTalk form:-

Vars * Define user pass
Input username Tap
Input username EnterText ${user}
Input password EnterText ${pass}
Button LOGIN Verify LOGIN %thinktime=1000
Button LOGIN Tap
Label * Verify "Welcome, ${user}!" %thinktime=3000
Button LOGOUT VerifyNot LOGIN
Button LOGOUT Tap %thinktime=5000

Driver Script in MonkeyTalk form:-

Script <name_of_driven_script>.mt RunWith <name_of_csv_file>.csv

CSV file:-

user pass
username1, password1
username2, password2
username3, password3

Notice that the first line (row) in the CSV file is the variable name and the contents of second row are the values in the variable.

Iterations: The number of rows in the csv file is the number of times the script is iterated. So in this case the script is run 3 times. In the first iteration the csv file passes the value username1 to the user variable and password1 to pass variable and so on.

Variable initiation: It does not matter whether the declared variable in the driven script is initialized or not. Even if the declared variable is initialized with some value that value will be wiped of that variable during the first iteration and the new value as mentioned in the script will be assigned to the variable. This is based on the assumption that the declared variable is mentioned in the script.

Do I need mention all the variables in the csv file even if I don’t want to change their value in each iteration? No. Mention only that variable that you want to iterate in each iteration.

Leaving a blank value for a var in csv: Leaving a value blank for a variable in csv file leaves the variable empty (technically, null). Even if it is the second iteration the variable does not contain the value provided to it in the first iteration. This means that the var is wiped off even when there are not values to be assigned to it the second iteration.

Note: Just make sure that you hit the play or run button when you are using browsing the driver script and not the driven script.


Javascript form of the Monkey Script:-

load("libs/<monkey_project_name>.js");
<monkey_project_name>.<driven_script_name>.prototype.run = function(user, pass) {
                this.app.input("username").tap();
                this.app.input("username").enterText(user);
                this.app.input("password").enterText(pass);
                this.app.button("LOGIN").verify("LOGIN", {thinktime:"1000"});
                this.app.button("LOGIN").tap();
                this.app.label().verify("Welcome, " + user + "!", {thinktime:"3000"});
                this.app.button("LOGOUT").verifyNot("LOGIN");
                this.app.button("LOGOUT").tap({thinktime:"5000"});
};

Simple Login (MonkeyTalk)


MonkeyTalk form:-

Input username EnterText test
Input password EnterText test
Button LOGIN tap %thinktime=3000
Button LOGOUT tap %thinktime=3000
Input username tap
Input username EnterText test1
Input password EnterText test1
Button LOGIN tap %thinktime=3000
Button LOGOUT tap %thinktime=3000
Input username tap
Input username EnterText test2
Input password EnterText test
Button LOGIN tap %thinktime=3000
Button LOGOUT tap %thinktime=3000

Javascript form:-

load("libs/<monkey_project_name>.js");
<monkey_project_name>. <script_name>.prototype.run = function() {
                this.app.input("username").enterText("test");
                this.app.input("password").enterText("test");
                this.app.button("LOGIN").tap({thinktime:"3000"});
                this.app.button("LOGOUT").tap({thinktime:"3000"});
                this.app.input("username").tap();
                this.app.input("username").enterText("test1");
                this.app.input("password").enterText("test1");
                this.app.button("LOGIN").tap({thinktime:"3000"});
                this.app.button("LOGOUT").tap({thinktime:"3000"});
                this.app.input("username").tap();
                this.app.input("username").enterText("test2");
                this.app.input("password").enterText("test");
                this.app.button("LOGIN").tap({thinktime:"3000"});
                this.app.button("LOGOUT").tap({thinktime:"3000"});
};

Writing script in MonkeyTalk


Before we start writing scripts let us understand the syntax of MonkeyTalk’s scripting language

Syntax:


MonkeyTalk commands are newline terminated and have the following syntax:

ComponentType  MonkeyId  Action  Args…  Modifiers…

ComponentType (required) – The type of component on which to perform the action. Examples include Button and TextArea. Component types are not case sensitive. ComponentTypes can extend other ComponentTypes, as described below, and inherit any defined actions as well as Arguments. ComponentTypes are typically the logical name of the UI component (like Button rather than UIButton), but can also have platform-specific aliases.  All UI components inherit from the View component type, and so specifying View on a command is like specifying a wildcard that will match any component type. 

For example:

# Tap on any component labeled "OK"
View OK Tap

MonkeyId (required) - An identifier that is used to distinguish between components of the same type being displayed simultaneously. MonkeyId can be specified as asterisk (*), which finds the first matching component.

MonkeyId’s can also be specified as a 1-based (not zero-based) index of the form #N. In this case, the MonkeyId identifies the Nth component of the specified type that’s currently displayed. Components are indexed according to upper-left-most position, i.e., by sorting components by (x,y) coordinate.

Action (required) – The action to be performed. Examples include Tap, Select, and EnterText. Actions are not case sensitive.

Arguments/Args (required according to ComponentType and Action) – A space-separated list of one or more arguments. Arguments are assumed to begin at the fourth token. Although always specified as strings, args are interpreted as necessary by the command. If an Argument is required but not specified (left off the end of the list), it takes on a default value. An Arg may be specified as an asterisk (*) to force it to take on it’s default value,

Modifiers… (optional) - A space-separated list of named arguments of the form %name=value, where the % prefix identifies it as a Modifier. There are three system-defined modifiers:

%timeout - how long in ms to continue retrying a command before timing out
%thinktime - how long in ms to wait before executing the command for the first time
%retrydelay - how long in ms to delay between retry attempts

Once you install the MonkeyTalk IDE and the make the necessary changes to the source code of the app provided by the developer, you can connect the MonkeyTalk to the emulator/device that app is installed on and you can start writing scripts.

It is suggested that before writing scripts one should record multiple actions on the app and let monkey record (write) the script for you. This way one can learn which action is related to which command.

A MonkeyTalk script can write in three forms:-

  1.  Table View
  2. MonkeyTalk script
  3. Javascript

These are just three different representations of same script. In the background both these run in exact same manner.

Script examples:
1. Simple Login script Click here
2. Data driven script Click here
3. Passing variables script Click here
4. Conditional statement script Click here