Keyword-driven testing with Squish and Robot Framework

Last edited on

Introduction

Keyword-driven testing is a software testing methodology which uses keywords (or action words) to symbolize a functionality to be tested. This method separates the description of the tests from its implementation and therefore reduces the future maintenance time caused by changes in the AUT. In the case of GUI changes in the AUT, only very small changes or even no changes have to be completed in test case documentation. Some changes need to be applied to keyword documentation only.

Robot Framework is a test automation framework which utilizes the keyword-driven testing approach. Its advantage is that users can create new higher-level keywords from existing ones. To integrate the Squish GUI Testing tool with Robot Framework, the keywords library needs to be implemented with Python using the squishtest module.

As an example, the Qt AddressBook application was chosen, which ships with Squish. Using a similar approach, we can automate Java, Windows, Mac, iOS, Android and Web applications.

Test case

A test case can be defined in a plain text file with the txt extension. Test cases are constructed in test case tables and built from the available keywords. Keywords can be imported from test libraries or resource files (e.g. resource.txt). The first column in the test case table contains test case names (e.g. Add Entry, Empty AddressBook). The second column normally contains keyword names (e.g. New Addressbook, Add Entry), columns after the keyword name contain possible arguments for the specified keyword (e.g. Tom Paw tom@m.com 12345). Please note, keywords and arguments are tab separated. Additionally we can define test setup and teardown actions. A test setup is something that is executed before a test case, and a test teardown is executed after a test case. In the example below the Start AddressBook action is executed before every test case.

*** Settings ***
Documentation     A test suite with two tests for addressbook.
...
...               This test has a workflow that is created using keywords in
...               the imported resource file.
Resource          resource.txt
Test Setup        Start AddressBook

*** Test Cases ***
Add Entry
        New AddressBook
        Add Entry       Tom     Paw     tom@m.com       12345
        Entries Should Be       1

Empty AddressBook
        New AddressBook
        Entries Should Be       0
add_entry.txt

Keywords resource file

A resource file contains keywords definitions used in test cases. To define keywords we utilize low level keywords provided by the SquishLibrary.

*** Settings ***
Documentation     A resource file with reusable keywords and variables.
...
...               The system specific keywords created here form our own
...               domain specific language. They utilize keywords provided
...               by the imported SquishLibrary.
Library           SquishLibrary

*** Variables ***
${WRAPPER}        Qt

*** Keywords ***
Start AddressBook
        Start Application   addressbook ${WRAPPER}
        Set ObjectMap   /home/tomasz/suites/suite_addressbook/objects.map

New AddressBook
        Click Button  :Address Book.New_QToolButton

Add Entry
        [Arguments]     ${forename}     ${surname}      ${mail}         ${phone}
        Click Button    :Address Book - Unnamed.Add_QToolButton
        Enter   :Forename:_LineEdit     ${forename}
        Enter   :Surname:_LineEdit      ${surname}
        Enter   :Email:_LineEdit        ${mail}
        Enter   :Phone:_LineEdit        ${phone}
        Click Button    :Address Book - Add.OK_QPushButton

Entries Should Be
        [Arguments]     ${num}
        Property Should Be      :Address Book - Unnamed.File_QTableWidget       rowCount        ${num}
resource.txt

SquishLibrary

SquishLibrary is a static keyword library which utilise Python module squishtest. It allows us to use Squish API and Application Convenience API, in our example Qt Convenience API. This is initial version of SquishLibrary with a very limited functionality, presented here as an example to build your own SquishLibrary by extending it.

import squishtest

class SquishLibrary:
    """ This is initial version of Squish Library for Robot Framework"""

    ROBOT_LIBRARY_SCOPE = 'TEST CASE'

    def __init__(self):
        pass

    def start_application(self, aut, wrapper):
        """ Starts AUT, args=(aut, wrapper) """
        squishtest.setTestResult("xml3.2", "results.xml")
        print "*INFO* Starting AUT: "+str(aut)+" with "+wrapper+" wrapper"

        # Remove double quotes for setWrappersForApplication
        if aut.startswith( '"' ):
            aut = aut[1:]
        if aut.endswith( '"' ):
            aut = aut[0:-1]
        squishtest.testSettings.setWrappersForApplication(aut, wrapper)

        # Add double quotes for startApplication
        if ' ' in aut:
            aut = '"' + aut + '"'
        squishtest.startApplication(aut)

    def set_objectmap(self, objMap):
        """ Sets Object Map for AUT, args=(objMap)"""
        squishtest.objectMap.load(objMap)

    def click_button(self, objName):
        """ Clicks on button, args=(objName)"""
        squishtest.clickButton(squishtest.waitForObject(objName))

    def enter(self, objName, txt):
         """ Enters given text into TextField, args=(objName, txt) """
         print "*INFO* Entering \""+txt+"\" into object \""+objName+"\""
         squishtest.type(squishtest.waitForObject(objName), txt)

    def property_should_be(self, objName, prop, expected):
        """ Verifies that given object has property with expected value, args= (objName,prop,expected)"""
        print "*INFO* Got arguments (%s,%s,%s)" % (objName, prop, expected)
        obj = squishtest.waitForObject(objName)
        val = getattr(obj, prop)
        if not (str(val) == expected):
                raise AssertionError("Expected value is "+expected+", but got: "+str(val))
        print "*INFO* Assertion passed, value is "+str(val)
SquishLibrary.py

Execution

To run our test suite we need to start squishserver and call pybot addressbook_tests.

==============================================================================
Addressbook Tests
==============================================================================
Addressbook Tests.Add Entry :: A test suite with a single test for addressb...
==============================================================================
Add Entry
Add Entry                                                             | PASS |
------------------------------------------------------------------------------
Empty AddressBook
Empty AddressBook                                                     | PASS |
------------------------------------------------------------------------------
Addressbook Tests.Add Entry :: A test suite with a single test for... | PASS |
2 critical tests, 2 passed, 0 failed
2 tests total, 2 passed, 0 failed
==============================================================================
Addressbook Tests                                                     | PASS |
2 critical tests, 2 passed, 0 failed
2 tests total, 2 passed, 0 failed
==============================================================================
Output:  /home/tomasz/robot/SquishDemo/output.xml
Log:     /home/tomasz/robot/SquishDemo/log.html
Report:  /home/tomasz/robot/SquishDemo/report.html

Additional notes

  1. To run tests the following environment variables need to be defined.

    export SQUISH_PREFIX=<location of Squish>
    # on linux:
    export PYTHONPATH=$SQUISH_PREFIX/lib:/home/tomasz/robot/lib
    # on macos:
    export DYLD_LIBRARY_PATH=$SQUISH_PREFIX/lib
    # on linux:
    export LD_LIBRARY_PATH=$SQUISH_PREFIX/lib:$SQUISH_PREFIX/python/lib
    On Linux & macOS
    set SQUISH_PREFIX=<location of Squish>
    set PYTHONPATH=%SQUISH_PREFIX%\bin;c:\users\tomasz\robot\lib
    set PATH=%SQUISH_PREFIX%\bin;%PATH%
    On Windows
  2. The presented solution was prepared using:

    • 64bit Ubuntu Linux
    • Squish 5.1
    • robotframework 2.8.4
  3. Directory structure

lib/SquishLibrary.py SquishDemo/addressbook_tests/add_entry.txt SquishDemo/addressbook_tests/resource.txt


# Related Information

-   [Using Squish as a module in other Python scripts, applications](/squish/howto/using-squish-module-python-scripts-applications/)