Skip to main content

Parallel test runner for Robot Framework

Project description

Pabot

中文版

Version Downloads


A parallel executor for Robot Framework tests. With Pabot you can split one execution into multiple and save test execution time.

Pabot presentation at robocon.io 2018

Table of Contents


Installation:

Pabot can be installed in the following ways:

From PyPI

pip install -U robotframework-pabot

From source (standard install)

Clone this repository and run:

python setup.py install

From source (editable / development mode)

Clone this repository and run:

pip install --editable .

Note

Starting from Pabot version 5.2.0, the Pabot installation only requires Robot Framework to function.

The previously used dependency natsort has been replaced with a pure Python implementation.

In addition, robotframework-stacktrace has been moved to an optional dependency. If it is installed, Pabot will continue to use it when running sub-Robot processes to improve fail/error logging both in Pabot’s own log file and on the command line.

You can install the optional stacktrace support with:

pip install -U robotframework-pabot[stacktrace]

Basic use

Split execution to suite files.

 pabot [path to tests]

Split execution on test level.

 pabot --testlevelsplit [path to tests]

Run same tests with two different configurations.

 pabot --argumentfile1 first.args --argumentfile2 second.args [path to tests]

For more complex cases please read onward.

Contact

Join Pabot Slack channel in Robot Framework slack. Get invite to Robot Framework slack.

Contributing to the project

There are several ways you can help in improving this tool:

  • Report an issue or an improvement idea to the issue tracker
  • Contribute by programming and making a pull request (easiest way is to work on an issue from the issue tracker)

Before contributing, please read our detailed contributing guidelines:

Command-line options

pabot [--verbose|--testlevelsplit|--command .. --end-command|
        --processes num|--no-pabotlib|--pabotlibhost host|--pabotlibport port|
        --processtimeout num|
        --shard i/n|
        --artifacts extensions|--artifactsinsubfolders|
        --resourcefile file|--argumentfile[num] file|--suitesfrom file
        --ordering file [static|dynamic] [skip|run_all]|
        --chunk|
        --pabotprerunmodifier modifier|
        --no-rebot|
        --pabotconsole [verbose|dotted|quiet|none]|
        --help|--version]
      [robot options] [path ...]

PabotLib remote server is started by default to enable locking and resource distribution between parallel test executions.

Supports all Robot Framework command line options and also following pabot options:

--verbose
More output from the parallel execution.

--testlevelsplit
Split execution on test level instead of default suite level. If .pabotsuitenames contains both tests and suites then this will only affect new suites and split only them. Leaving this flag out when both suites and tests in .pabotsuitenames file will also only affect new suites and add them as suite files.

--command [ACTUAL COMMANDS TO START ROBOT EXECUTOR] --end-command
RF script for situations where robot is not used directly.

--processes [NUMBER OF PROCESSES]
How many parallel executors to use (default max of 2 and cpu count). Special option "all" will use as many processes as there are executable suites or tests.

--no-pabotlib
Disable the PabotLib remote server if you don't need locking or resource distribution features.

--pabotlibhost [HOSTNAME]
Connect to an already running instance of the PabotLib remote server at the given host (disables the local PabotLib server start). For example, to connect to a remote PabotLib server running on another machine:

  pabot --pabotlibhost 192.168.1.123 --pabotlibport 8271 tests/

The remote server can also be started and executed separately from pabot instances:

  python -m pabot.pabotlib <path_to_resourcefile> <host> <port>
  python -m pabot.pabotlib resource.txt 192.168.1.123 8271

This enables sharing a resource with multiple Robot Framework instances.

Additional details:

  • The default value for --pabotlibhost is 127.0.0.1.
  • If you provide a hostname other than 127.0.0.1, the local PabotLib server startup is automatically disabled.

--pabotlibport [PORT]
Port number of the PabotLib remote server (default is 8270). See --pabotlibhost for more information.

Behavior with port and host settings:

  • If you set the port value to 0 and --pabotlibhost is 127.0.0.1 (default), a free port on localhost will be assigned automatically.

--processtimeout [TIMEOUT]
Maximum time in seconds to wait for a process before killing it. If not set, there's no timeout.

--shard [INDEX]/[TOTAL]
Optionally split execution into smaller pieces. This can be used for distributing testing to multiple machines.

--artifacts [FILE EXTENSIONS]
List of file extensions (comma separated). Defines which files (screenshots, videos etc.) from separate reporting directories would be copied and included in a final report. Possible links to copied files in RF log would be updated (only relative paths supported). The default value is png.

Examples:

 --artifacts png,mp4,txt

The artifact naming conventions are described in the README.md section: Output Files Generated by Pabot.

--artifactsinsubfolders
Copy artifacts located not only directly in the RF output dir, but also in it's sub-folders.

--resourcefile [FILEPATH]
Indicator for a file that can contain shared variables for distributing resources. This needs to be used together with pabotlib option. Resource file syntax is same as Windows ini files where a section is a shared set of variables.

--argumentfile[INTEGER] [FILEPATH]
Run same suites with multiple argumentfile options.

For example:

 --argumentfile1 arg1.txt --argumentfile2 arg2.txt

--suitesfrom [FILEPATH TO OUTPUTXML]
Optionally read suites from output.xml file. Failed suites will run first and longer running ones will be executed before shorter ones.

--ordering [FILEPATH] [MODE] [FAILURE POLICY]
Optionally give execution order from a file. See README.md section: Controlling execution order, mode and level of parallelism

  • MODE (optional): [ static (default) | dynamic ]
  • FAILURE POLICY (optional, only in dynamic mode): [ skip | run_all (default) ]

--chunk
Optionally chunk tests to PROCESSES number of robot runs. This can save time because all the suites will share the same setups and teardowns.

--pabotprerunmodifier [PRERUNMODIFIER MODULE OR CLASS]
Like Robot Framework's --prerunmodifier, but executed only once in the pabot's main process after all other --prerunmodifiers. But unlike the regular --prerunmodifier command, --pabotprerunmodifier is not executed again in each pabot subprocesses. Depending on the intended use, this may be desirable as well as more efficient. Can be used, for example, to modify the list of tests to be performed.

--no-rebot
If specified, the tests will execute as usual, but Rebot will not be called to merge the logs. This option is designed for scenarios where Rebot should be run later due to large log files, ensuring better memory and resource availability. Subprocess results are stored in the pabot_results folder.

--pabotconsole [MODE] The --pabotconsole option controls how much output is printed to the console. Note that all Pabot’s own messages are always logged to pabot_manager.log, regardless of the selected console mode.

The available options are:

  • verbose (default): Prints all messages to the console, corresponding closely to what is written to the log file.

  • dotted: Prints important messages, warnings, and errors to the console, along with execution progress using the following notation:

    • PASS = .
    • FAIL = F
    • SKIP = s

    Note that each Robot Framework process is represented by a single character. Depending on the execution parameters, individual tests may not have their own status character; instead, the status may represent an entire suite or a group of tests.

  • quiet: Similar to dotted, but suppresses execution progress output.

  • none: Produces no console output at all.

--help
Print usage instructions.

--version
Print version information.

Example usages:

 pabot test_directory
 pabot --exclude FOO directory_to_tests
 pabot --command java -jar robotframework.jar --end-command --include SMOKE tests
 pabot --processes 10 tests     
 pabot --pabotlibhost 192.168.1.123 --pabotlibport 8271 --processes 10 tests
 pabot --artifacts png,mp4,txt --artifactsinsubfolders directory_to_tests
 # To disable PabotLib:
 pabot --no-pabotlib tests

PabotLib

pabot.PabotLib provides keywords that will help communication and data sharing between the executor processes. These can be helpful when you must ensure that only one of the processes uses some piece of data or operates on some part of the system under test at a time.

PabotLib Docs are located at https://pabot.org/PabotLib.html.

Note that PabotLib uses the XML-RPC protocol, which does not support all possible object types. These limitations are described in the Robot Framework documentation in chapter Supported argument and return value types.

PabotLib example:

test.robot

  *** Settings ***
  Library    pabot.PabotLib
  
  *** Test Case ***
  Testing PabotLib
    Acquire Lock   MyLock
    Log   This part is critical section
    Release Lock   MyLock
    ${valuesetname}=    Acquire Value Set  admin-server
    ${host}=   Get Value From Set   host
    ${username}=     Get Value From Set   username
    ${password}=     Get Value From Set   password
    Log   Do something with the values (for example access host with username and password)
    Release Value Set
    Log   After value set release others can obtain the variable values

valueset.dat

  [Server1]
  tags=admin-server
  HOST=123.123.123.123
  USERNAME=user1
  PASSWORD=password1
  
  [Server2]
  tags=server
  HOST=121.121.121.121
  USERNAME=user2
  PASSWORD=password2

  [Server3]
  tags=admin-server
  HOST=222.222.222.222
  USERNAME=user3
  PASSWORD=password4

pabot call using resources from valueset.dat

  pabot --pabotlib --resourcefile valueset.dat test.robot

Controlling execution order, mode, and level of parallelism

.pabotsuitenames file contains the list of suites that will be executed. This file is created during pabot execution if it does not already exist. It acts as a cache to speed up processing when re-executing the same tests. The file can be manually edited partially, but a simpler and more controlled approach is to use:

--ordering <FILENAME> [static|dynamic] [skip|run_all]
  • FILENAME – path to the ordering file.
  • mode – optional execution mode, either static (default) or dynamic.
    • static executes suites in predefined stages.
    • dynamic executes tests as soon as all their dependencies are satisfied, allowing more optimal parallel execution.
  • failure_policy – determines behavior when dependencies fail. Used only in dynamic mode. Optional:
    • skip – dependent tests are skipped if a dependency fails.
    • run_all – all tests run regardless of failures (default).

The ordering file syntax is similar to .pabotsuitenames but does not include the first 4 hash rows used by pabot. The ordering file defines the execution order and dependencies of suites and tests.
The actual selection of what to run must still be done using options like --test, --suite, --include, or --exclude.

Controlling execution order

There different possibilities to influence the execution:

  • The order of suites can be changed.
  • If a directory (or a directory structure) should be executed sequentially, add the directory suite name to a row as a --suite option. This usage is also supported when --testlevelsplit is enabled. As an alternative to using --suite options, you can also group tests into sequential batches using {} braces. (See below for details.) Note that if multiple --suite options are used, they must not reference the same test case. This means you cannot specify both parent and child suite names at the same time. For instance:
--suite Top Suite.Sub Suite
--suite Top Suite
  • If the base suite name is changing with robot option --name / -N you can use either the new or old full test path. For example:
--test New Suite Name.Sub Suite.Test 1
OR
--test Old Suite Name.Sub Suite.Test 1
  • You can add a line with text #WAIT to force executor to wait until all previous suites have been executed.
  • You can group suites and tests together to same executor process by adding line { before the group and } after. Note that #WAIT cannot be used inside a group.
  • You can introduce dependencies using the word #DEPENDS after a test declaration. This keyword can be used several times if it is necessary to refer to several different tests.
    • The ordering algorithm is designed to preserve the exact user-defined order as closely as possible. However, if a test's execution dependencies are not yet satisfied, the test is postponed and moved to the earliest possible stage where all its dependencies are fulfilled.
    • Please take care that in case of circular dependencies an exception will be thrown.
    • Note that each #WAIT splits suites into separate execution blocks, and it's not possible to define dependencies for suites or tests that are inside another #WAIT block or inside another {} braces.
    • Ordering mode effect to execution:
      • Dynamic mode will schedule dependent tests as soon as all their dependencies are satisfied. Note that in dynamic mode #WAIT is ignored, but you can achieve same results with using only #DEPENDS keywords.
      • Static mode preserves stage barriers and executes the next stage only after all tests in the previous stage finish.
    • Note: Within a group {}, neither execution order nor the #DEPENDS keyword currently works. This is due to limitations in Robot Framework, which is invoked within Pabot subprocesses. These limitations may be addressed in a future release of Robot Framework. For now, tests or suites within a group will be executed in the order Robot Framework discovers them — typically in alphabetical order.
  • An example could be:
--test robotTest.1 Scalar.Test With Environment Variables #DEPENDS robotTest.1 Scalar.Test with BuiltIn Variables of Robot Framework
--test robotTest.1 Scalar.Test with BuiltIn Variables of Robot Framework
--test robotTest.2 Lists.Test with Keywords and a list
#WAIT
--test robotTest.2 Lists.Test with a Keyword that accepts multiple arguments
{
--test robotTest.2 Lists.Test with some Collections keywords
--test robotTest.2 Lists.Test to access list entries
}
--test robotTest.3 Dictionary.Test that accesses Dictionaries
--test robotTest.3 Dictionary.Dictionaries for named arguments #DEPENDS robotTest.3 Dictionary.Test that accesses Dictionaries
--test robotTest.1 Scalar.Test Case With Variables #DEPENDS robotTest.3 Dictionary.Test that accesses Dictionaries
--test robotTest.1 Scalar.Test with Numbers #DEPENDS robotTest.1 Scalar.Test With Arguments and Return Values
--test robotTest.1 Scalar.Test Case with Return Values #DEPENDS robotTest.1 Scalar.Test with Numbers
--test robotTest.1 Scalar.Test With Arguments and Return Values
--test robotTest.3 Dictionary.Test with Dictionaries as Arguments
--test robotTest.3 Dictionary.Test with FOR loops and Dictionaries #DEPENDS robotTest.1 Scalar.Test Case with Return Values
  • By using the command #SLEEP X, where X is an integer in the range [0-3600] (in seconds), you can define a startup delay for each subprocess. #SLEEP affects the next line unless the next line starts a group with {, in which case the delay applies to the entire group. If the next line begins with --test or --suite, the delay is applied to that specific item. Any other occurrences of #SLEEP are ignored. Note that #SLEEP has no effect within a group, i.e., inside a subprocess.

The following example clarifies the behavior:

pabot --processes 2 --ordering order.txt data_1

where order.txt is:

#SLEEP 1
{
#SLEEP 2
--suite Data 1.suite A
#SLEEP 3
--suite Data 1.suite B
#SLEEP 4
}
#SLEEP 5
#SLEEP 6
--suite Data 1.suite C
#SLEEP 7
--suite Data 1.suite D
#SLEEP 8

Possible output could be:

2025-02-15 19:15:00.408321 [0] [ID:1] SLEEPING 6 SECONDS BEFORE STARTING Data 1.suite C
2025-02-15 19:15:00.408321 [1] [ID:0] SLEEPING 1 SECONDS BEFORE STARTING Group_Data 1.suite A_Data 1.suite B
2025-02-15 19:15:01.409389 [PID:52008] [1] [ID:0] EXECUTING Group_Data 1.suite A_Data 1.suite B
2025-02-15 19:15:06.409024 [PID:1528] [0] [ID:1] EXECUTING Data 1.suite C
2025-02-15 19:15:09.257564 [PID:52008] [1] [ID:0] PASSED Group_Data 1.suite A_Data 1.suite B in 7.8 seconds
2025-02-15 19:15:09.259067 [1] [ID:2] SLEEPING 7 SECONDS BEFORE STARTING Data 1.suite D
2025-02-15 19:15:09.647342 [PID:1528] [0] [ID:1] PASSED Data 1.suite C in 3.2 seconds
2025-02-15 19:15:16.260432 [PID:48156] [1] [ID:2] EXECUTING Data 1.suite D
2025-02-15 19:15:18.696420 [PID:48156] [1] [ID:2] PASSED Data 1.suite D in 2.4 seconds

Programmatic use

Library offers an endpoint main_program that will not call sys.exit. This can help in developing your own python program around pabot.

import sys
from pabot.pabot import main_program

def amazing_new_program():
    print("Before calling pabot")
    exit_code = main_program(['tests'])
    print(f"After calling pabot (return code {exit_code})")
    sys.exit(exit_code)

Global variables

Pabot will insert following global variables to Robot Framework namespace. These are here to enable PabotLib functionality and for custom listeners etc. to get some information on the overall execution of pabot.

  PABOTQUEUEINDEX - this contains a unique index number for the execution. Indexes start from 0.
  PABOTLIBURI - this contains the URI for the running PabotLib server
  PABOTEXECUTIONPOOLID - this contains the pool id (an integer) for the current Robot Framework executor. This is helpful for example when visualizing the execution flow from your own listener.
  PABOTNUMBEROFPROCESSES - max number of concurrent processes that pabot may use in execution.
  CALLER_ID - a universally unique identifier for this execution.

Output Files Generated by Pabot

Pabot generates several output files and folders during execution, both for internal use and for analysis purposes.

Internal File: .pabotsuitenames

Pabot creates a .pabotsuitenames file in the working directory. This is an internal hash file used to speed up execution in certain scenarios.
This file can also be used as a base for the --ordering file as described earlier. Although technically it can be modified, it will be overwritten during the next execution.
Therefore, it is recommended to maintain a separate file for the --ordering option if needed.

Output Directory Structure

In addition to the standard log.html, report.html, and output.xml files, the specified --outputdir will contain:

  • A folder named pabot_results, and
  • All defined artifacts (default: .png files)
  • Optionally, artifacts from subfolders if --artifactsinsubfolders is used

Artifacts are copied into the output directory and renamed with the following structure:

TIMESTAMP-ARGUMENT_INDEX-PABOTQUEUEINDEX

If you use the special option notimestamps at the end of the --artifacts command, (For example: --artifacts png,txt,notimestamps) the timestamp part will be omitted, and the name will be in the format:

ARGUMENT_INDEX-PABOTQUEUEINDEX
  • TIMESTAMP = Time of pabot command invocation (not the screenshot's actual timestamp), format: YYYYmmdd_HHMMSS
  • ARGUMENT_INDEX = Optional index number, only used if --argumentfileN options are given
  • PABOTQUEUEINDEX = Process queue index (see section Global Variables)

pabot_results Folder Structure

The structure of the pabot_results folder is as follows:

pabot_results/
├── [N]/                     # Optional: N = argument file index (if --argumentfileN is used)
│   └── PABOTQUEUEINDEX/     # One per subprocess
│       ├── output.xml
│       ├── robot_argfile.txt
│       ├── robot_stdout.out
│       ├── robot_stderr.out
│       └── artifacts...
└── pabot_manager.log        # Pabot's own main log.

Each PABOTQUEUEINDEX folder contains as default:

  • robot_argfile.txt – Arguments used in that subprocess
  • robot_stdout.out and robot_stderr.out – Stdout and stderr of the subprocess
  • output.xml – The partial output file to be merged later
  • Artifacts – Screenshots or other files copied from subprocess folders

Note: The entire pabot_results folder is considered temporary and will be deleted/overwritten on the next pabot run using the same --outputdir.

Artifacts Handling and Parallel Execution Notes

Due to parallel execution, artifacts like screenshots should ideally be:

  • Embedded directly into the XML using tools like SeleniumLibrary with the EMBED option
    Example:
    Library SeleniumLibrary screenshot_root_directory=EMBED
  • Or saved to the subprocess’s working directory (usually default behavior), ensuring separation across processes

If you manually specify a shared screenshot directory in your test code, all processes will write to it concurrently, which may cause issues such as overwriting or missing files if screenshots are taken simultaneously.

Project details


Release history Release notifications | RSS feed

This version

5.2.0

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

robotframework_pabot-5.2.0.tar.gz (106.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

robotframework_pabot-5.2.0-py3-none-any.whl (71.5 kB view details)

Uploaded Python 3

File details

Details for the file robotframework_pabot-5.2.0.tar.gz.

File metadata

  • Download URL: robotframework_pabot-5.2.0.tar.gz
  • Upload date:
  • Size: 106.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for robotframework_pabot-5.2.0.tar.gz
Algorithm Hash digest
SHA256 f212f6f4b02b60407cdeb5e0ec7f824e8590480f5d2cbf31b9b72a0ec8f03770
MD5 3985861510239e282e121af134ff133b
BLAKE2b-256 8f929d109bc13352e3b6650f2de4f62e0358f69797124711c4a662e897b84a9d

See more details on using hashes here.

File details

Details for the file robotframework_pabot-5.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for robotframework_pabot-5.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1a7df94eb423ecdd8ea4fcad92f66ec81d3efec7b3331656c481b589c0c5aabb
MD5 89acd46e6b7368af094632e6d760f3fd
BLAKE2b-256 a5182c4ca64a8e9ab4e6a129938daee51ab8f2d00555913e93808f0e90432cd4

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page