It focuses on the installation procedures for Linux, so if you use Windows or Mac then adjust accordingly. The actual tests and use of Robot and Selenium are platform independent.
Clients and your code
In formal, and usually large, projects run by big companies, you will find dedicated Business Analysts, Software Engineers, Systems Analysts, Developers, Designers, UX Specialists and, of course, a team of Testers covering the whole code base.
This team of testers will include people from the client side who understand the requirements and purpose of the software and will know the business processes and procedures inside out. Great secure and reliable code (hopefully) gets released into the big wide world once everyone has signed off. I've been there, seen it, done it. They have the necessary budget to spend to ensure it all works.
What happens though for those small projects – particularly web ones – where you don't have those teams of people?
Testing is important, we all know that… but it is such a chore and is not viewed as a critical element as if it seems to work, why do you need to bother with testing, "it's working isn't it?". If you do test, you'll usually get your dev. team doing it (they do, after all, wear many different types of hat).
Do you find they go about testing a bit like headless chickens? No structure, no sets of test data, no reports, repeating what they do time and time again? If a change is made, either through a fix in the test process or once code has been released, do you find them having to test the general principles of the system again...and again...and again.
Without any formal test data in place, test scripts – even just pseudo-code type instructions – your testing is either very time consuming or not very rigorous – or both.
Invariably, the developers will conduct the 'technical' tests, consisting of unit and integration tests, as part of the normal work flow. Once they are happy they pass it to the client for UAT (User Acceptance Tests). How many of your clients address testing properly? Do they actually know how? Are they rigorous in their application of test scenarios?
If this rings a bell with you then read on. Banish that 'hope for the best' attitude and stop wasting time with ineffective testing.
Products for the complete lifecyle of your business
Using Robot Framework
The Robot Framework enables you to run automated User Acceptance Tests and Integrated Tests over virtually any environment. What this means is that you can introduce consistency, repeatability and rigour into your release processes and be confident that any changes made, will work and not break the application.
Using the 'Test Setup' functionality will allow you to create test data, set up environments, seed databases etc and then run the tests with known and expected data. Similarly, 'Test Teardown' can be used to remove unwanted test data and database entries and leave your environment clean and tidy.
As a benefit, you will be able to build up a library of tests that can be used across all of your projects – for example a catalogue of invalid and valid login credentials – can be used. Reporting and audit trails of tests can be used to show clients of the processes you undertake to ensure the quality of your code.
To get you started, the main example, within this article, is written to show how you can start to understand how easy it is to test HTML pages and websites by using Selenium with the Robot Framework and there are also some very basic Python based tests to check Selenium is operating as expected.
The Robot Framework is a plain test framework that can use Python, Java and other languages to leverage the tests that are written. The libraries that are available are comprehensive and are also fully extendable. Also, due to its use of Python and Java, the Robot Framework is totally platform independent and will work happily across Linux, Mac and Windows.
Selenium and Robot Framework Installation
Check/install PIP on your machine
sudo apt-get install python-pip
Then install the Robot Framework
sudo pip install robotframework
<br>
Then install Selenium
sudo pip install -U selenium
Then install the Selenium drivers for the browsers in which we are interested. I think at this stage we are only after Chrome and Firefox; we'll think about other browsers as and when they become necessary.
This link will take you to the Firefox driver
This link will take you to the Chrome drivers download page
These two files unzip to create a 'geckodriver' and a 'chromedriver' file; both of these need to be copied to /usr/bin/ or somewhere on an include path of your machine.
mv geckodriver /usr/bin
and
mv chromedriver /usr/bin
Final stage is install the extended library for Selenium2
sudo pip install robotframework-extendedselenium2library
Optional: Install and configure pyCharm
Integration between PyCharm and the Robot Framework is relatively mature and it is a great Python environment. (Other IDEs may have Robot integration...I just haven't investigated).
Download PyCharm from the JetBrains website. Install on your machine at machine, rather than user, level.
cd /Downloads
sudo tar xvf pycharm-community*.gz -C /opt/
To run PyCharm you need to create a menu item in KDE or Gnome that references the location of the shell executable or you can run it from the command line.
sh /opt/pycharm-community-2017.3.3/bin/pycharm.sh
Next you need to configure PyCharm to use the syntax highlighting necessary for the Robot files. To do this you need to go to File->Settings->Plugins->Browse repositorys and search for, and install, the Intellibot plugin. By default all Robot specification files should have a .robot extension.
Simple test to ensure Selenium is working
We're now ready to try out some simple tests to ensure Selenium is set up correctly. Create a new python file in PyCharm with these contents:
from selenium import webdriver
browser = webdriver.Firefox()
browser.get('https://5and3.co.uk/')
A more advanced test, with some form input, can also be run:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
browser = webdriver.Chrome()
browser.get('https://www.google.co.uk')
assert 'Google' in browser.title
elem = browser.find_element_by_name('q') # Find the search box
elem.send_keys('5and3' + Keys.RETURN)
#browser.quit()
Running both of these Python programs through the CLI or an IDE will result in a browser window opening, one Firefox and the other Chrome and navigating to a certain page.
The second example shows a very simple example on how text can be injected into a form, which is then submitted, and the resulting page checked for certain text.
Run as is, and the code will complete without any errors, but try changing the assert line to another phrase and you will see what happens when the test fails.
Also, in a fully automated test, you don't want to leave your test machine littered with browsers that have been opened by the testing process. Uncomment the last line in the second example and the browsers will close once the test has been completed.
These are easy to understand and show the basics of using Selenium, but they aren't something you can really show to your clients and nor does it report back on what has occurred. Also, you really have to be a programmer to understand what is going on. This is where Robot Framework steps in. Plain language tests can be written, that a client would understand, reports show comprehensive test results and audits can be kept.
Using the Robot Framework
Enter the text below into a text file called "onefilesample.robot".
*** Settings ***
Documentation A simple example to test a login page
Library Selenium2Library
Test Setup Run Keywords
... Open Browser https://domain.com/login firefox AND
... Maximize Browser Window
Test Teardown Close Browser
*** Variables ***
${username_input} email
${password_input} password
${submit_login} //button[contains(text(),"Login")]
${whoisit} //html/body/aside/ul/li[1]
*** Test Cases ***
TEST_01: Login to some page
Input Text ${username_input} login@domain.com
Input Text ${password_input} password
Click button ${submit_login}
Element Text Should Be ${whoisit} Welcome Joe
In the example above we have set up a very simple test that will:
- open a browser
- go to a url
- enter a user name
- enter a password
Test Setup opens a browser and navigates to a URL; you need to change the URL to a login page that you use. When creating Test Setup and Test Teardown procedures ensure that you ensure a trailing "AND" to join to the next line and that the next line starts with "...". The "Run Keywords" ensures that the Robot Framework will execute the kewords in sequence.
*** Variables ***
Variables are used within the scope of the tests and, in this case, define the input box used for the user name, an input box using for the password, a form submit button and an xpath location on the successful page with the welcome message.
${username_input} and ${password_input} shows how Robot will use the id or name of an HTML element of "email" and "password" respectively. For you to test, you need to identify the id or name of the input boxes that ask for the user name and password on the system you are testing. In my sample, shown below
<form action="domain.com/login" method="post" accept-charset="utf-8">
<div class="form-group">
<label for="email" class="control-label">Email Address</label>
<input type="email" id="email" class="form-control" autofocus="1">
</div>
<div class="form-group">
<label for="password" class="control-label">Password</label>
<input type="password" id="password" class="form-control"></div>
<div class="checkbox">
<label for="remember">
<input type="checkbox" id="remember" >Remember me</label>
</div>
<div class="form-group">
<button type="submit" class="btn btn-info btn-block">Login</button>
</div>
<div class="form-group">
<a href="https://domain.com/forgot_password">Forgot Password?</a>
</div>
</form>
you can see the inputs that we are interested in have the id's set to email and password. You need to make the relevant changes to identify your input/submit elements.
${submit_login} indicates button on the page that contains the text "Login". We have resorted to this to show the other ways of identifying elements where they don't have an id or name set, and where classes are not unique enough.
${whoisit} is an XPATH element specifier that identifies a location on the page. In the example I use, the 'Welcome Joe' message appears as the first element in a list on the page once you successfuly log in. You can change this to identify another location on your page that would confirm the user has logged in successfully.
*** Test Cases ***
This is where the tests are actually run and will use the variables that have been defined above. Where it states 'login@domain.com' and, on the line below, 'password', you need to enter your login username and password respectively, as text replacing those two items. For example, something along these lines:
......
Input Text ${user_input} mickey@disney.com
Input Text ${password_input} iloveD0naldandDa1sy
.......
Running this from the command line:
robot onefilesample.robot
should result in a successful test, assuming you have modified the variables to reflect the system you are trying to login to.
You will also receive a log and report html file with details of the test.
Better presentation and logic (for the client)
That file is fine, it works but it doesn't really show the plain English capabilities of the system and it isn't something that you could really show to a client and nor does it show how data and variables can be extracted into a reusable system.
Although the following may be viewed as a little bit of overkill for such a simple test scenario, it will show how you can start to break your data and tests out into separate files to start to leverage those qualities of the previous paragraph.
We are going to break out the above into three files. One to store variables as a Python file and two Robot files that separate routines, or resources, from the main process file.
The Robot resource file needs to be created, and in this case called resource_login.robot and placed in a sub directory called resources.
*** Variables ***
${username_input} email
${password_input} password
${submit_login} //button[contains(text(),"Login")]
${whoisit} //html/body/aside/ul/li[1]
*** Keywords ***
Log in with correct credentials
Input Text ${username_input} ${username}
Input Text ${password_input} ${password}
Click button ${submit_login}
Check user name is Joe
Element Text Should Be ${whoisit} Welcome Joe
You will recognise in the example above, that a couple more items have been added. We have created the routines using plain text descriptive statements - Log in with correct credentials and Check user name is Joe and also that the two input text elements now refer to variables ${username} and ${password} rather than the hard-coded text. These two variables are stored in a Python file located in resources/variables.py. Create that file with this data
username = "login@domain.com"
password = "password"
browser = "firefox"
server = "https://domain.com/login"
substituting your data where required. You will also spot two more variables that we have extracted out from the main file.
The main Robot, called organised.robot, now contains:
*** Settings ***
Documentation A simple example to test a login page
Library Selenium2Library
Resource ./resources/resource_login.robot
Variables ./resources/variables.py
Test Setup Run Keywords
... Open Browser ${server} ${browser} AND
... Maximize Browser Window
Test Teardown Close Browser
*** Test Cases ***
TEST_01: Login to some page
Log in with correct credentials
Check user name is Joe
This is obviously a cleaner and easier file to read. We have referenced the two resource files and parameterised the URL and the browser. The client could be shown this file and they would understand the test, i.e. Log in with correct credentials and Check user name is Joe are simple.
Running this test
robot organised.robot
should produce the same result as previously.
This just scratches the surface but half an hour here will show how the power of Selenium and Robot Framework can start to be used.
Useful to know
- A gotcha to watch out for: Robot needs AT LEAST two spaces between functions/variables. If your code doesn't work as you think it should, please double check that two or more spaces are separating the different parts of the statements.
- XPATH locators can be copied using the inspection tools available through browsers. For example, in Firefox, right click on an element in your browser window, select Inspect and then from the HTML code that opens in the inspection panel, right-click again, hover over Copy and you will be shown various copy 'flavours'
Useful Links
Robot Framework - Details, docs and examples on the Robot Framework
Selenium - Selenium, with further documentation and examples
PyCharm - Great Python IDE with full support for Robot and Selenium
Python - Main Python website
Selenium browser drivers
Firefox driver
Chrome driver
Edge driver
Safari driver
About the Author
Simon Dawson / Technical Director
I am 5and3's Technical Director and it is my responsibility to ensure all of our work is technically and logically sound and of a high quality. I oversee our work practices to ensure work for our clients is consistent and rigorous.
Throughout my career I have been responsible for the development and implementation of ground breaking, award winning solutions having learnt my trade working for the likes of AIG and Barclays. Now that experience and those skills are put to use working for 5and3's clients.
If you have any questions at all please feel free to message me on Twitter @simon5and3.