how to sikuli and robot framework

http://blog.mykhailo.com/2011/02/how-to-sikuli-and-robot-framework.html

Feb 7, 2011

How-To: Sikuli and Robot Framework Integration


Introduction
Integration Details
Step 0: Installation
Step 1: Run Sikuli Script from command line
Step 2: Upgrade Sikuli Scripts to Test Libraries
Step 3: Tips and Tricks
Summary
References

Introduction

Sikuli and  Robot Framework are both freely available open source tools that provide interesting possibilities for automation testers, QA and other IT people.

Sikuli introduces new way of automated testing - test using screenshots and images, without using any internal API of objects under test. This approach (using purely images/screenshots and generating mouse and keyboard events) is more similar to manual testing activities performed by real people which have just monitor, mouse and keyboard.

Robot Framework is an excellent implementation of keyword- and data-driven approaches to test automation and besides it includes a lot of interesting features and tools, such as:
and much more...

Integration Details

Robot Framework is written on python and provides tools for running test cases using either python or jython. Sikuli scripts are run using jython.
Taking into account all statements above, it is possible to run test cases using "jybot" tool, where keywords are implemented in Sikuli scripts. In other words, Sikuli scripts will play role of Test Libraries for Robot Framework.

Pic. 1 - Sikuli and Robot Framework Integration Architecture

The following integration how-to is splited on four main steps:
  1. Installation
  2. Run Sikuli Scripts using command line
  3. Upgrade Sikuli Scripts to Test Libraries
  4. Tips and tricks
Step 0: Installation

First of all this how-to is for Windows XP SP3, although everything should work on Windows 7 also.
The following software should be installed on your test machine:

1)  Java Runtime Environment (JRE 6_23) to run jython scripts.
2)  Jython 2.5.1 itself.
3)  Python 2.7.1 (it is required by Robot Framework exe distribution. See a note below).
4)  Robot Framework 2.5.5 (exe distribution)
5)  Sikuli X.

NOTE: It is actually possible to install the framework using Jython without having Python installed at all, but this requires using the source distribution. More information could be found on the  Instalation wiki page.

In case you are planning to use RobotFramework2.5.5.jar instead of installing the exe distribution you only need JRE and Sikuli X because Jython is already packed in RobotFramework2.5.5.jar.

Step 1: Run Sikuli Script from command line

Lets write simple Sikuli script for testing standart Windows calculator:

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
                        
                        
from __future__ import with_statement
from sikuli.Sikuli import *
 
class Calculator ( object ):
def __init__ ( self ):
self . appCoordinates = ( 0 , 0 , 1024 , 768 )
def startApp ( self ):
calcApp = App ( "Calculator" )
if not calcApp . window ():
App . open ( "calc.exe" ); wait ( 2 )
calcApp . focus (); wait ( 1 )
 
def verifyApp ( self ):
# check application
if exists ( "CalcApp.png" ):
print ( "PASS: Calculator window appeared" )
else :
print ( "FAIL: No calculator window" )
 
def performAction ( self , * args ):
# get application region
find ( "CalcApp.png" )
match = getLastMatch ()
self . appCoordinates = ( match . getX (), match . getY (), match . getW (), match . getH ())
appRegion = Region ( * self . appCoordinates )
#rewrite action
action = args [ 1 ]
if args [ 1 ] == '+' :
action = 'Plus'
elif args [ 1 ] == 'exp' :
action = 'Exp'
with appRegion :
click ( "btnC.png" )
 
click ( "btn %s .png" % ( args [ 0 ],) )
click ( "btn %s .png" % ( action ,) )
click ( "btn %s .png" % ( args [ 2 ],) )
 
click ( "btnEqual.png" )
 
def verifyResult ( self , * args ):
expected_result = str ( eval ( '' . join ( args )))
actual_result = self . getResultFromClipboard ()
#verification
if actual_result == expected_result :
print ( "PASS: Action performed correctly and result equals %s " % expected_result )
else :
print ( "FAIL: Actual result ' %s ' is not equal to expected result ' %s '" % ( actual_result , expected_result ))
def getResultFromClipboard ( self ):
type ( 'c' , KEY_CTRL )
return str ( Env . getClipboard ())
def runTest ( self ):
self . startApp ()
self . verifyApp ()
actions = '2+2'
self . performAction ( * actions )
self . verifyResult ( * actions )
 
if __name__ == "__main__" :
calc = Calculator ()
calc . runTest ()
view raw calc.py hosted with ❤ by  GitHub

I assume that you made following screenshots:

  • calcApp.png  - screenshot of Calculator application
  • btn2.png, btnC.png, ... - screenshot of corresponding buttons of the calculator
So far you should be able to run this Sikuli script from Sikuli IDE. 

All what we want now is to be able to run this script from the command line without using Sikuli IDE.

Sikuli 10.2
Here you can find detailed tutorial with steps and settings required for using Sikuli 10.2 from the command line. Briefly, what we should do according to the tutorial above:
  1. Copy sikuli-script.jar from Sikuli installation directory (by default "C:\Program Files\Sikuli") to the directory of your Sikuli project.
  2. Extract "Lib" directory from sikuli-script.jar to the directory of your Sikuli project.
  3. Add the following statement to the beginning of your Sikuli script:
     1 from sikuli.Sikuli import *
     2 
    
As a result your Sikuli project layout should look as below:

Pic. 2 - Sikuli project layout

runtest.bat file is a batch file for running your Sikuli script:

123
                         
                         
@ echo off
 
java -Dpython.path =Lib -jar sikuli-script.jar calc.sikuli
view raw runtest.bat hosted with ❤ by  GitHub
NOTE: Above steps, as you may notice, is for Sikuli version 10.2. For Sikuli X we need extra steps described below.

Sikuli X
  1. Copy libs from Sikuli installation (by default: C:\Program Files\Sikuli X\libs) to the Temp directory (C:\Documents and Settings\Local Settings\Temp\tempdir\).
Actually path to the Sikuli libs is added to the Path environment variable, but in my case I get java.lang.UnsatisfiedLinkError unless I copy these libraries.
  1. Add path to the JRE bin directory (by default: C:\Program Files\Java\jre6\bin) to the Path environment variable.
Starting from Sikuli X some Java dll-s are required by Sikuli libraries. For example: Win32Util.dll depends on jawt.dll.

That's all what you need to be able to run your Sikuli script from the command line. One more thing here (I noticed, when I was writing this How-To):

NOTE: Using Sikuli X you can skip steps 1 and 2 (coping sikuli-script.jar and Lib directory) and just run your Sikuli script using following command. You even do not need explicitly to indicate path to the Lib directory as it is automatically added to the PYTHONPATH variable.

 C:\work\> java -jar "C:\Program Files\Sikuli X\sikuli-script.jar" calc.sikuli




2. Upgrade Sikuli Scripts to Test Libraries

Now we can run our Sikuli script using Java Runtime Environment. To use our script from Robot Framework it should be updated to support one of available  Library APIs.

According to the Robot Framework  User Guide, Library Static API:
The simplest approach is having a module (in Python) or a class (in Python or Java) with methods which map directly to  keyword names. Keywords also take the same  arguments as the methods implementing them. Keywords  report failures with exceptions,  log by writing to standard output and can  return values using the  return statement.
Taking into account all above our Sikuli script is already a Test Library implemented using Static API. Thus no further changes required except one line of code in order to find images/screenshots:

 3 
 4 addImagePath("calc.sikuli")
 5 

addImagePath() has been added since Sikuli X, for older version of Sikuli use  setBundlePath() instead.

What we need now that is to write a new Test Case for Robot Framework using keywords from the Sikuli script.

12345678910111213141516
                         
                         
***Settings***
Library calc.Calculator WITH NAME Calculator
 
***Test Cases***
Verify that 2 + 2 = 4
Start App
Verify App
Perform Action 2 + 2
Verify Result 4
 
Verify that 2 + 2 = 5
Start App
Verify App
Perform Action 2 + 2
Verify Result 5
view raw verify_operations.txt hosted with ❤ by  GitHub

Lets place this test case under  robot_suite directory. At this point, there are two way of using Robot Framework:

  • use robotframework-2.5.5.jar without any further installation.
  • install robotframework-2.5.5.exe and use jybot.bat.
    For this case, Python (required by Robot Framework exe distribution) and Jython (required by jybot) should be installed.


Run test cases using robotframework.jar.
  1. Download robotframework-2.5.5.jar file and place it to your Sikuli project directory.
  2. Run test cases using robottest.bat file, that is shown below, using command:
     C:\work\> robottest.bat robot_suite\verify_operations.txt
    
    
Below is the content of  robottest.bat. As you can see, this is simple run of java command with CLASSPATH parameter, that import two jar files and some extra parameters for Robot Framework: such as where to put logs and reports, log level and path to your Sikuli script added to python path.

1234567891011
                           
                           
@ echo off
 
set sikuli_jar =C:\Program Files\Sikuli X\sikuli-script.jar
 
java -cp "robotframework-2.5.5.jar;%sikuli_jar%" ^
-Dpython.path = "%sikuli_jar%/Lib" ^
org.robotframework.RobotFramework ^
--pythonpath =calc.sikuli ^
--outputdir =results ^
--loglevel =TRACE ^
%*
view raw robottest.bat hosted with ❤ by  GitHub


Run test using jybot.bat.

  1. Install Python, Jython and Robot Framework
  2. Add pathes to Python/Script (jybot.bat is there) and Jython (jython.bat is there) directories to the PATH environment variable (by default "C:\Python27\Scripts;C:\jython2.5.1")
  3. Run test cases using jybottest.bat file, that is shown below, using command:
     C:\work\> jybottest.bat robot_suite\verify_operations.txt
    
    
This is the content of  jybottest.bat. Here  JYTHONPATH variable contains path to the Lib directory under sikuli-script.jar file.

1234567891011
                         
                         
@ echo off
 
set sikuli_jar =C:\Program Files\Sikuli X\sikuli-script.jar
 
set CLASSPATH = %sikuli_jar%
set JYTHONPATH = %sikuli_jar% /Lib
 
jybot --pythonpath =calc.sikuli ^
--outputdir =results ^
--loglevel =TRACE ^
%*
view raw jybottest.bat hosted with ❤ by  GitHub
That's all what you need to be able to run test cases that consist of keywords implemented by Sikuli scripts from Robot Framework. What to use: robotframework.jar or jybot.bat to run your test cases - depends on you and requirements of the project.

3. Tips and tricks

So far we easily can edit our Sikili scripts in Sikuli IDE, edit our test cases in Robot IDE and run all that from the command line.

What is explained in this section?
- Benefits that we can achieve from Sikuli and Robot Framework Integration, particularly detailed logs, that are accompanied by screenshots.
Such logs can significantly decrease time for result analysis, to find the reasons of failures and errors in the test suite.

Here is the example of log file where Find Failed Exception raised by Sikuli is used for getting info about a source image and a region within this image was searched.

Pic. 3 - Robot Framework log file with screenshoots

Implementation of such logging features is quite simple. All what we need is 
  • a wrapper for the Sikuli functions and classes 
  • a custom Robot Logger class

Lets have a deep look at both.


Global Sikuli functions, e.g.  click(), exists(), find() that are actually methods of  Screen class are moved to the global level using a hack (manually push methods to the internal  globals dictionary, for details).
To wrap these global functions we can use similar hack. Look at code below:

 9 
10 # =============================================== #
11 #          Overwritten sikuli methods             #
12 # =============================================== #
13 
14 # function for calling native sikuli methods
15 def sikuli_method(name, *args, **kwargs):
16     return sys.modules['sikuli.Sikuli'].__dict__[name](*args, **kwargs)
17 
18 # overwritten Screen.exists method
19 def exists(target, timeout=None):
20     addFoundImage(getFilename(target))
21     return sikuli_method('exists', target, timeout)
22 

Here  sikuli_method() is a way to call native Sikuli global function and  exists() is an example of overwritten method.

Even easier situation is with Sikuli classes. You can extend them in natural object oriented way. What you need is just to import Sikuli class with alternative name (for example SikuliRegion), in order to use original name (for example Region) in Sikuli scripts. have a look at code below.

 3 from sikuli.Sikuli import Region as SikuliRegion

23 # =============================================== #
24 #          Overwritten sikuli classes             #
25 # =============================================== #
26 
27 # overwriten Sikuli Region class
28 class Region(SikuliRegion, BaseLogger):
29 
30     def click(self, target, modifiers=0):
31         try:
32             return SikuliRegion.click(self, target, modifiers)
33         except FindFailed, e:
34             self.log.html_img("Find Filed", "images/" + getFilename(target))
35             self.log.screenshot(msg="Region", region=(self.getX(), self.getY(), self.getW(), self.getH()))
36             raise e
37     def exists(self, target, timeout=None):
38         img = getFilename(target)
39         reg = (self.getX(), self.getY(), self.getW(), self.getH())
40         addFoundImage(img, reg)
41         return SikuliRegion.exists(self, target, timeout)


So far we have our overwritten Sikuli methods and as you may notice have a possibility to use them in Sikuli scripts - no changes required to our Sikuli scripts, except importing  sikuliwrapper module instead of  sikuli.Sikuli.

The purpose of the Sikuli wrapper module is to gather an additional info about what image is being searched and a region within it is being looked for. Such information later is used by Robot Logger.

Robot Logger


Robot Logger is an derived class from Python's standard  Logger class from  logging module.
What is added there is the following:

  • a custom handler for printing messages in Robot Framework's style, e.g. "*INFO* Message text"
  • special methods for passed and failed statuses of test cases
  • methods for making screenshots of desired regions and adding them as html records to the Robot log
The whole  logger.py file can be found  here


Summary

I tried to show how easy to work with open source test automation tools where all undocumented problems can be solved in one quick look into source code, in spite of limitation you may find with similar commerce tools.

I really like both Sikuli and Robot Framework tools, and hope this how-to describes some of their advantages, its flexibly and extendability.

I added all code mentioned here on  github. Feel free to clone and have a look at it.

I look forward to hearing from you, especially about your tips and tricks with these amazing tools.


References


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值