How to write Robot Framework tests for Plone¶
This is a brief tutorial for writing Robot Framework test for Plone with plone.app.robotframework. plone.app.robotframework provides Robot Framework -compatible resources and tools for writing functional Selenium tests (including acceptance tests) for Plone CMS and its add-ons. (See also Known plone.app.robotframework-examples for more ideas).
Require plone.app.robotframework¶
Update
setup.py
to require plone.app.robotframework:
extras_require={
'test': [
...
'plone.app.robotframework',
],
},
All you need is plone.app.robotframework. It will require the rest (selenium, robotframework, robotframework-selenium2library and also robotsuite).
Note
Selenium-bindings for Python use Firefox as the default browser. Unless you know how to configure other browsers to work with Selenium you should have Firefox installed in your system
Define functional testing layer¶
Plone add-on testing requires defining a custom test layer, which setups Plone-sandbox, the dependent add-ons and any custom configuration required by the tests.
Update your
src/my/product/testing.py
to include:
from plone.testing import z2
from plone.app.testing import FunctionalTesting
from plone.app.robotframework.testing import AUTOLOGIN_LIBRARY_FIXTURE
MY_PRODUCT_ROBOT_TESTING = FunctionalTesting(
bases=(MY_PRODUCT_FIXTURE, AUTOLOGIN_LIBRARY_FIXTURE,
z2.ZSERVER_FIXTURE),
name="MyProduct:Robot")
Note
AUTOLOGIN_LIBRARY_FIXTURE is optional, but it will allow you to write faster Selenium tests, because tests don't need to spend time on login forms. Also note that the order of the bases matters.
If you don't have any testing layers for your product yet, or want to know more about them, please read plone.app.testing-documentation.
Install Robot-tools¶
plone.app.robotframework ships with two main helper scripts for writing tests:
-
bin/robot-server
starts a temporary Plone site with the given test layer set up -
bin/robot
executes Robot Framework'spybot
-runner so that it will run the given test suite against the runningrobot-server
, ensuring that tests will be run in isolation (database is cleaned between the tests)
Update
buildout.cfg
:
[buildout]
parts =
...
robot
[robot]
recipe = zc.recipe.egg
eggs =
Pillow
${test:eggs}
plone.app.robotframework
Note
Robot-tools are optional, but will ease and speed up your test development.
Start test server¶
Once the buildout with Robot-tools is run, start the test server with:
$ bin/robot-server my.product.testing.MY_PRODUCT_ROBOT_TESTING
Once the test server has started, there should be a test Plone-site served at http://localhost:55001/plone/ (by default). This allows you to play with the sandbox while writing the tests.
Note
The default admin user for
plone.app.testing-based Plone-sandbox is
admin
and password is
secret
.
Write your first test suite¶
Robot tests are written in test suites, which are plain
text files, usually ending with
.robot
(and older ones with
.txt
).
The first test can be written anywhere in the filesystem.
For example, a
test_hello.robot
:
*** Settings ***
Force Tags wip-not_in_docs
Resource plone/app/robotframework/selenium.robot
Test Setup Open test browser
Test Teardown Close all browsers
*** Test Cases ***
Plone is installed
Go to ${PLONE_URL}
Page should contain Powered by Plone
Robot is all about running test clauses called keywords (or, to be more exact, keyword calls with parameters). Every test case may contain one or more keywords, which are run sequentially -- usually until the first of them fails. Keywords are separated from their arguments (and arguments from each other) using at least two spaces.
Keywords are defined in keyword libraries and as user keywords. Keyword libraries can be Python libraries or XML-RPC-services. User keywords are just lists of test clauses reusing existing keywords or other user keywords. User keywords are described in the test suite, or imported from resource files.
Here is a more complicated example with some user keywords in action:
*** Settings ***
Force Tags wip-not_in_docs
Resource plone/app/robotframework/selenium.robot
Library Remote ${PLONE_URL}/RobotRemote
Test Setup Open test browser
Test Teardown Close all browsers
*** Variables ***
${ADMIN_ROLE} Site Administrator
*** Test Cases ***
Site Administrator can access control panel
Given I'm logged in as a '${ADMIN_ROLE}'
When I open the personal menu
Then I see the Site Setup -link
*** Keywords ***
I'm logged in as a '${ROLE}'
Enable autologin as ${ROLE}
Go to ${PLONE_URL}
I open the personal menu
Click link css=#user-name
I see the Site Setup -link
Element should be visible css=#personaltools-plone_setup
Please, stop for a while end read the example above again. Once you understand how you can stack keyword calls with user keywords, you are ready to unleash the power of Robot Framework all the way to building your own domain specific test language.
Note
We use
.robot
as the Robot Framework test suite file extension to make
it easier for developers to configure Robot Framework
syntax highlighting for their editors (otherwise
.txt
would work also).
Run your first test suite¶
Once the
bin/robot-server
has been started and a test suite has been written, the
new test suite can be run with
bin/robot
:
$ bin/robot test_hello.robot
Note
bin/robot
is mostly just a wrapper for Robot Framework's pybot
test runner, but it does inject necessary options to
enable plone.testing's test isolation for Plone when
used together with
bin/robot-server
.
Integrate with Zope-testrunner¶
It's often convenient to run Robot tests with other Plone tests (e.g. on Jenkins or Travis-CI). To achieve that, we integrate Robot tests to be run with other tests so that all tests can be run with zope.testrunner.
For zope.testrunner integration, create
src/my/product/tests/test_robot.py
:
import unittest
import robotsuite
from my.product.testing import MY_PRODUCT_ROBOT_TESTING
from plone.testing import layered
def test_suite():
suite = unittest.TestSuite()
suite.addTests([
layered(robotsuite.RobotTestSuite('test_hello.robot'),
layer=MY_PRODUCT_ROBOT_TESTING),
])
return suite
Note
For this to work and
zope.testrunner
to discover your robot test suite, remember to move
test_hello.robot
under
my/product/tests
.
RobotSuite is our package for wrapping Robot Framework tests into Python unittest compatible test cases. It's good to know that this registration pattern is the same as how doctest-suites are registered to support zope.testrunner's layers (see https://pypi.python.org/pypi/plone.testing for layered doctest examples).
Running tests with zope.testrunner¶
Once your robot test have been integrated with
zope.testrunner using
test_robot.py
-module (or any other module returning RobotTestSuite),
you can list your integrated robot test cases with
command:
$ bin/test --list-tests
And run robot tests cases with all other test cases with command:
$ bin/test
You can filter robot test using
-t
-argument for zope.testrunner*:
$ bin/test -t robot
And it's also possible to filter test by Robot Framework tags:
$ bin/test -t \#mytag
Or exclude matching tests from being run:
$ bin/test -t \!robot
How to write more tests¶
The most difficult part in writing robot tests with Selenium-keywords is to know the application you are testing: which link to click when and to which field to input test data.
At first, you should have a brief idea about the available keywords:
Then, learn to use pause test execution to make it easier to figure out, what to do next:
*** Settings ***
Force Tags wip-not_in_docs
Resource plone/app/robotframework/selenium.robot
Library Remote ${PLONE_URL}/RobotRemote
Test Setup Open test browser
Test Teardown Close all browsers
*** Test Cases ***
Let me think what to do next
Enable autologin as Site Administrator
Go to ${PLONE_URL}
Import library Dialogs
Pause execution
Robot Framework ships with a few selected standard libraries. One of them is the Dialogs-library, which provides a very useful keyword: Pause execution. By importing Dialogs-library (while developing the test) and adding the Pause execution keyword, you can pause the test at any point to make it possible to figure out what to do next. (Dialogs depend on TkInter-library.)
Note
Be sure to remove Import libary and Pause execution keyword calls before committing your tests to avoid pausing your tests on CI.
Note
plone.app.robotframework ships with an optional collection of Plone-specific user keywords, which already include Pause keyword as a shortcut for Pause execution keywords. You can include and use the collection with:
*** Settings ***
Force Tags wip-not_in_docs
...
Resource plone/app/robotframework/keywords.robot
*** Test Cases ***
Let me think what to do next
...
Pause