culebra

Diego Torres Milano edited this page Mar 18, 2015 · 51 revisions

Culebra helps you create AndroidViewClient scripts generating a working template that can be modified to suit more specific needs.

Also Culebra with its user friendly GUI is a very powerful tool for generating ready-to-execute scripts for Black box testing. The GUI has too many features that help testers and developers in manipulating their devices or test-agents by just using a (mouse & a keyboard) while creating ready-to-execute script in the background and save it to a python file.

Documentation about Culebra GUI can be found in its own page

It's really beneficial here to mention that, even testers with zero-knowledge in scripting can use the tool to record their test cases to script files and re-run them easily on the test agents without any issues. Simply because they don't really need to edit, change or even know what's in those files.

The generated script files are just ready for execution! after recording.

And they contain this culebra so you can easily recognize them

                      __    __    __    __
                     /  \  /  \  /  \  /  \ 
____________________/  __\/  __\/  __\/  __\_____________________________
___________________/  /__/  /__/  /__/  /________________________________
                   | / \   / \   / \   / \   \___
                   |/   \_/   \_/   \_/   \    o \ 
                                           \_____/--<

@author: diego
@author: Jennifer E. Swofford (ascii art snake)

Introduction

culebra is another extremely valuable tool in AndroidViewClient toolbox.

Its main use is to generate templates or scripts that can later be adapted to suit the most demanding needs. It conveys the full power of AndroidViewClient and python together.

culebra, independently of the use of the GUI feature, can generate 3 different type of scripts or snippets:

  • full python unittest script that you can just run to verify some case or cases
  • full python script that you can just to verify some simple case or produce some action on the target device or emulator
  • python unittest method that can be later included as an additional test in a previously generated test case class

dump is on of the tools and it helps obtaining the dump of the content of the screen currently present on a device or emulator. dump provides the result as a tree of Views representing the logical content of the screen.

In a similar fashion, culebra generates a script, the logically represents and verifies the content of the screen, unless contrary it's indicated, but instead of comparing bitmaps or using optical character recognition it uses View properties as main concept.

In this script culebra can find and verify the existence of Views having a specific ID, some text or text matching some pattern or content descriptions.

Some time ago, I wrote an article about visual image comparison in monkeyrunner, which is also a valid approach for some situations, but the ability to obtain the tree of Views provides a flexibility and effectiveness very difficult to parallel using graphical methods. One of the advantages is the device, screen, resolution and density independence that allows to run the same test on different devices without being affected by this change.

Environment

In order to run culebra and any other AndroidViewClient(https://github.com/dtmilano/AndroidViewClient) script some environment variables should be provided containing the right values that allow the script to find other components.

PATH

You need python and AndroidViewClient tools in the path. If you installed AndroidViewClient using easy_install or pip everything has been done for you.

ANDROID_VIEW_CLIENT_HOME

ANDROID_VIEW_CLIENT_HOME contains the path to the AndroidViewClient directory. This is the directory containing src/ and tools/.

For example:

export ANDROID_VIEW_CLIENT_HOME=/home/user/workspace/AndroidViewClient

PYTHONPATH

PYTHONPATH alternatively this variable can be used to locate modules. This is very useful when scripts are run from Eclipse using PyDev.

Usage

usage: culebra [OPTION]... [serialno]

Options:
  -H, --help                       prints this help                             
  -V, --verbose                    verbose comments                             
  -v, --version                    prints version number and exists             
  -I, --ignore-secure-device
  -E, --ignore-version-check       ignores ADB version check                    
  -F, --force-view-server-use
  -S, --do-not-start-view-server
  -k, --do-not-ignore-uiautomator-killed don't ignore UiAutomator killed              
  -w, --window=WINDOW              use WINDOW content (default: -1, all windows)
  -i, --find-views-by-id=BOOL      whether to use findViewById() in script      
  -t, --find-views-with-text=BOOL  whether to use findViewWithText() in script  
  -d, --find-views-with-content-description=BOOL whether to use findViewWithContentDescription
  -r, --use-regexps                use regexps in matches                       
  -C, --verbose-comments
  -U, --unit-test-class            generates unit test class and script         
  -M, --unit-test-method=NAME      generates unit test method. Can be used with or without -U
  -j, --use-jar=BOOL               use jar and appropriate shebang to run script (deprecated)
  -D, --use-dictionary=BOOL        use a dictionary to store the Views found    
  -K, --dictionary-keys-from=VALUE dictionary keys from: id, text, content-description
  -R, --auto-regexps=LIST          auto regexps (i.e. clock), implies -r. help list options
  -a, --start-activity=COMPONENT   starts Activity before dump                  
  -o, --output=FILENAME            output filename                              
  -A, --interactive                interactive                                  
  -p, --prepend-to-sys-path        prepend environment variables values to sys.path
  -f, --save-screenshot=FILENAME   save screenshot to file                      
  -W, --save-view-screenshots=DIR  save View screenshots to files in directory  
  -G, --gui                        presents the GUI (EXPERIMENTAL)              
  -u, --do-not-verify-screen-dump  do not verify screen state after dump        
  -P, --scale=FLOAT                scale percentage (i.e. 0.5)                  
  -O, --orientation-locked         orientation locked in generated test         
  -s, --serialno=LIST              device serial number (can be more than 1)    
  -m, --multi-device               enables multi-device test generation         
  -L, --log-actions                log actions using logcat                     

-H, --help

Prints the help message and command line usage

-V, --verbose

Sets the verbose mode for the script.

-v, --version

Prints the culebra version information and exists.

For example:

culebra 9.2.0

-I, --ignore-secure-device

Ignores that a device is in secured as explained in secure mode.

This is useful when used in combination with LocalViewServer.

-E, --ignore-version-check

Ignores the adb version check which is performed at the beginning.

If you receive an error like this one

RuntimeError: ERROR: Incorrect ADB server version 00040022 (expecting one of ['00040020', '0004001f'])

which happens when the target device has an adb server version not compatible with [AndroidViewClient], -E can be used to override the check. However, because the adb version is not know it may fail later.

-F, --force-view-server-use

Forces the use of ViewServer even if the conditions to use UiAutomator are present. These conditions are depicted in Select the correct implementation. Basically, if the device run on API 16 or greater it can use UiAutomator, but if for some reason you want to still use the previous ViewServer method you can force it using this option.

ViewServer is much slower than UiAutomator, so it seems there are no reasons to use it when the latter is available. However there is one reason that may have some weight and this is the availability of the same View ID's used in the layouts.

-S, --do-not-start-view-server

Avoids starting the ViewServer even when it's not present on the device.

This is useful when used in combination with LocalViewServer.

-o, --output=FILE

Saves the output of this tool to FILE. FILE execute permission is also set when this option is used to be able to run it.

-i, --find-views-by-id=BOOL

Whether to use findViewById() in the generated script.

-t, --find-views-with-text=BOOL

Whether to use findViewByWithText() in the generated script.

-d, --find-views-with-content-description=BOOL

Whether to sue findViewWithContentDescription() in the generated script.

-r, --use-regexps

Use regexps in matches. Every time a selection is done it will use a regexp match instead of text.

-C, --verbose-comments

Generates verbose comments in the script.

-U, --unit-test

Generates unit test script.

-j, --use-jar=BOOL

Whether to use the jar and appropriate shebang to run script.

-D, --use-dictionary=BOOL

Use a dictionary to store the Views found.

-R, --auto-regexps=LIST

When used in conjunction with -r or --use-regexps some cases are identified and the pattern is automatically replaced by pre-existing patterns. LIST is the list of replacements to apply separated by ,. The supported pre-existing matches are:

  • help: prints this help
  • all: includes all the available regexps
  • date: (Mon|Tue|Wed|Thu|Fri|Sat|Sun), (January|February|March|April|May|June|July|August|September|October|November|December) [0123]\d
  • battery: Charging, \d\d%
  • clock: [012]?\d:[0-5]\d Matches clock values (HH:MM) that may appear in some places like the statusbar.

-G, --gui

Starts culebra GUI. Complete information about this mode can be found at Culebra-GUI.

serialno

Specifies the serial number of the device to use if the device serial number cannot be determined automatically for some reason or if there are several devices connected.

Examples

Finding Views with specific content description (emulator, version 4.2)

This examples uses UiAutomator as the API 16 present in the emulator allows it.

Command line

The following command line creates the script not using IDs, using content description regexps to find the views and using the AndroidViewClient jar file

$ culebra -i false -d true -r -j true

the script obtained is

#! /usr/bin/env shebang monkeyrunner -plugin $ANDROID_VIEW_CLIENT_HOME/bin/androidviewclient-2.3.11.jar @!
# -*- coding: utf-8 -*-
'''
Copyright (C) 2013  Diego Torres Milano
Created on 2013-04-16 by Culebra v0.9.5

                      __    __    __    __
                     /  \  /  \  /  \  /  \ 
____________________/  __\/  __\/  __\/  __\_____________________________
___________________/  /__/  /__/  /__/  /________________________________
                   | / \   / \   / \   / \   \___
                   |/   \_/   \_/   \_/   \    o \ 
                                           \_____/--<
@author: diego
@author: Jennifer E. Swofford (ascii art snake)
'''


import re
import sys
import os


from com.dtmilano.android.viewclient import ViewClient

from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice

device, serialno = ViewClient.connectToDeviceOrExit()
vc = ViewClient(device, serialno)

no_id9 = vc.findViewWithContentDescriptionOrRaise(re.compile('Apps'))
no_id10 = vc.findViewWithContentDescriptionOrRaise(re.compile('Widgets'))
no_id15 = vc.findViewWithContentDescriptionOrRaise(re.compile('Analog clock'))
no_id20 = vc.findViewWithContentDescriptionOrRaise(re.compile('API Demos'))
no_id25 = vc.findViewWithContentDescriptionOrRaise(re.compile('ApiDemos'))
no_id30 = vc.findViewWithContentDescriptionOrRaise(re.compile('Bookmark'))
no_id35 = vc.findViewWithContentDescriptionOrRaise(re.compile('Bookmarks'))
no_id40 = vc.findViewWithContentDescriptionOrRaise(re.compile('Calendar'))

Brief description

The generated script uses shebang as shebang to be able to easily locate AndroidViewClient and simplify imports. Then the usual device connection and ViewClient instantiation. Once the ViewClient reference is obtained a series of method calls are generated locating the Views currently on the device screen. In this particular case, because we specified it in culebra command line we are generating only content description calls and using regular expressions as arguments. You can take a look at the screenshot presented before and check that the main Views, having a valid content description, are the ones in the script.

Because no serialno was specified on the command line the regular expression .* that matches any device or emulator is used. In this case the only device present is the emulator-5554.

It's not possible to determine the serial number for the emulator and thus the warning tells us that emulator-5554 was assumed.

Executing the generated script

If we save the generated script we can execute it at a later time.

Now, when we execute the script, and the device contains the same screen, that is the same Views (strictly speaking Views with the same content description as before as we are not imposing any other rules in this simple example) the script will exit with no errors

$ ./example1.py

However, if we change the screen, let's say manually selecting the Apps tab and run the script again

$ ./example1.py
...
com.dtmilano.android.viewclient.ViewNotFoundException: Couldn't find View with content-desc that matches 'Analog clock' in tree with root=ROOT
...

We receive the exception telling us that a View with a content description matching 'Alarm clock' was not found.