A familiar challenge for most test automation experts is managing their Robot Framework dependencies. Updating them constantly is at best a tedious chore; at worst, you can break your whole CI pipeline with a single update.

However, if you don’t update your dependencies regularly, you will miss useful features and expose your pipeline to security risks. In this post, we look at a modern way you can manage your Robot Framework dependencies: automation.

Basic dependency management

First of all, the best way to control your Robot Framework dependencies is to have them all in a single requirements.txt file. 

robotframework==3.0.4

junitparser==1.2.2

requests==2.27.1

PyYAML==3.13

An example of four dependencies with pinned version numbers (major, minor, and patch)

In semantic versioning, the first two numbers of a version number should refer to major and minor versions. 

These versions should not be wildcards (*) in your development or main branch because the changes to them may break your CI pipeline. In other words, the versions should be pinned. 

Using a wildcard with patch versions is usually safe, but developers often interpret semantic versioning in different ways. An update one developer thought was an inconsequential patch release might still end up breaking your pipeline. 

On the other hand, it may be even riskier not to use a wildcard with patch versions. By not using a wildcard, you need to remember to follow the patch releases and update them manually. If (when) you eventually forget to do this, you once again expose your pipeline to security breaches.

Our two ways of versioning dependencies

Here at Eficode, we use two different approaches. One is more manual and the other more automated.

Pinning major and minor versions that are updated manually

In the first approach, you pin major and minor versions of dependencies in a requirements.txt file and manually update them periodically — typically every couple of months. 

As a general rule of thumb, in projects where the dependencies are complex, this works really well: any updates to major or minor versions usually require some manual work with the test harness anyway. 

Pinning the whole version and automating the pipeline

For relatively straightforward dependencies—especially security-critical ones—we recommend pinning the whole version (major, minor, and patch) and having an automated pipeline. 

Configure this pipeline to update the dependencies for you weekly and report if new versions are easy to update or if the update is going to break something. The pipeline can e.g., report directly to your Slack, so you don’t miss the report.

Although there are a million ways to make such a pipeline, here’s an example of a simple implementation:

# turn all pinned dependencies into wildcard dependencies
awk -F '==' '{print $1}' requirements.txt > requirements.txt.trial

# create virtualenv to install dependencies:
python3 -m venv newversions
source newversions/bin/activate

# install dependencies with wildcards and run tests:
pip install -r requirements.txt.trial
robot --nostatusrc my_tests/ # notice --nostatusrc: we do not want the job to end if tests fail

# and finally, create new candidate versions and post the status:
pip freeze > requirements.txt.candidate
python post_to_slack.py output.xml requirements.txt.candidate requirements.txt

Go see the post_to_slack.py script to see the rest of the example

After scheduling the job to run e.g. weekly, the team gets the following message if the job succeeds:

maintaining-dependencies-blog-pipeline

The team can then update the dependencies manually. 

Of course, you could make the pipeline even more elaborate by making it automatically open a merge request with new versions for pinned dependencies. With our example, we just want to demonstrate that even a relatively simple solution can make updating the dependencies a breeze.

To sum up: “lagom” is best

In the end, to maintain your test automation effectively, you also need to maintain the dependencies it uses. Don’t let the constant updating of dependencies interrupt your actual, valuable work and break your pipeline. But you do need to update them with some regularity to at least keep your pipeline secure. 

As with many things in life, the Swedish concept of lagom proves useful (thank you, Swedish colleagues). There is no direct English equivalent term, but it roughly translates to “the right amount is the best.” 

Published: September 5, 2022

DevOpsCI/CD