This is a pytest plugin for creating/editing testplans or testruns based on pytest markers. The results of the collected tests will be updated against the testplan/testrun in TestRail.
Version 3.0 brings major modernization:
- Python 3.10+ required (Python 2 support dropped)
- Full type hints throughout the codebase
- Support for TestRail API pagination (TestRail 6.7+)
- Proper exception handling with custom exception classes
- API key authentication support (recommended over password)
- Connection pooling via requests Session
- Automatic retry on rate limiting (HTTP 429)
- Logging instead of print statements
Using uv (recommended):
uv add pytest-testrail
Or using pip:
pip install pytest-testrail
Add a marker to the tests that will be picked up to be added to the run.
from pytest_testrail.plugin import pytestrail
@pytestrail.case('C1234', 'C5678')
def test_foo():
# test code goes here
# With defect tracking
@pytestrail.case('C1234')
@pytestrail.defect('BUG-123', 'JIRA-456')
def test_bar():
# test code goes hereNote
The @testrail decorator is deprecated. Please use @pytestrail.case instead.
See a more detailed example here.
- Settings file template config:
[API]
url = https://yoururl.testrail.net/
email = user@email.com
# Use API key (recommended) or password
api_key = your-api-key
# password = your-password
# timeout = 30
[TESTRUN]
assignedto_id = 1
project_id = 2
suite_id = 3
# Optional settings
# plan_id = 100
# milestone_id = 1
# include_all = false
[TESTCASE]
# custom_comment = Additional info appended to resultsOr
- Set command line options (see below)
Basically, the following command will create a testrun in TestRail, add all marked tests to run. Once the all tests are finished they will be updated in TestRail:
pytest --testrail --tr-config=<settings file>.cfgAPI keys are more secure than passwords and can be revoked without changing your password. Generate an API key in TestRail under My Settings.
pytest --testrail --tr-url=https://example.testrail.net --tr-email=user@example.com --tr-api-key=your-api-key --tr-testrun-project-id=1 --tr-testrun-suite-id=1--testrail Create and update testruns with TestRail
--tr-config=TR_CONFIG
Path to the config file containing information about
the TestRail server (defaults to testrail.cfg)
--tr-url=TR_URL TestRail address you use to access TestRail with your
web browser (config file: url in API section)
--tr-email=TR_EMAIL Email for the account on the TestRail server (config
file: email in API section)
--tr-password=TR_PASSWORD
Password for the account on the TestRail server
(config file: password in API section)
--tr-api-key=TR_API_KEY
API key for the account on the TestRail server
(recommended over password)
(config file: api_key in API section)
--tr-timeout=TR_TIMEOUT
Set timeout for connecting to TestRail server
(config file: timeout in API section)
--tr-testrun-assignedto-id=TR_TESTRUN_ASSIGNEDTO_ID
ID of the user assigned to the test run (config file:
assignedto_id in TESTRUN section)
--tr-testrun-project-id=TR_TESTRUN_PROJECT_ID
ID of the project the test run is in (config file:
project_id in TESTRUN section)
--tr-testrun-suite-id=TR_TESTRUN_SUITE_ID
ID of the test suite containing the test cases (config
file: suite_id in TESTRUN section)
--tr-testrun-suite-include-all
Include all test cases in specified test suite when
creating test run (config file: include_all in TESTRUN
section)
--tr-testrun-name=TR_TESTRUN_NAME
Name given to testrun, that appears in TestRail
(config file: name in TESTRUN section)
--tr-testrun-description=TR_TESTRUN_DESCRIPTION
Description given to testrun, that appears in TestRail
(config file: description in TESTRUN section)
--tr-run-id=TR_RUN_ID
Identifier of testrun, that appears in TestRail. If
provided, option "--tr-testrun-name" will be ignored
--tr-plan-id=TR_PLAN_ID
Identifier of testplan, that appears in TestRail. If
provided, option "--tr-testrun-name" will be ignored
--tr-version=TR_VERSION
Indicate a version in Test Case result.
--tr-no-ssl-cert-check
Do not check for valid SSL certificate on TestRail
host
--tr-close-on-complete
Close a test plan or test run on completion.
--tr-dont-publish-blocked
Do not publish results of "blocked" testcases in
TestRail
--tr-skip-missing Skip test cases that are not present in testrun
--tr-milestone-id=TR_MILESTONE_ID
Identifier of milestone, to be used in run creation
(config file: milestone_id in TESTRUN section)
--tc-custom-comment=TC_CUSTOM_COMMENT
Custom comment, to be appended to default comment for
test case (config file: custom_comment in TESTCASE
section)
You can also use the API client directly in your code:
from pytest_testrail import APIClient, TestRailError
# Create client
client = APIClient(
base_url="https://example.testrail.net",
user="user@example.com",
password="your-api-key" # Can be API key or password
)
# Use context manager for automatic cleanup
with client:
# Get a test case
case = client.send_get("get_case/1")
# Add a result
result = client.send_post("add_result/1", {
"status_id": 1,
"comment": "Test passed!"
})
# Handle paginated results
for test in client.get_paginated("get_tests/1", "tests"):
print(test["case_id"])from pytest_testrail import (
APIClient,
TestRailError,
TestRailAPIError,
TestRailAuthenticationError,
TestRailRateLimitError
)
try:
client = APIClient(base_url, user, api_key)
result = client.send_get("get_case/1")
except TestRailAuthenticationError:
print("Invalid credentials")
except TestRailRateLimitError:
print("Rate limit exceeded")
except TestRailAPIError as e:
print(f"API error: {e.message}")
except TestRailError as e:
print(f"General error: {e}")This project uses uv for dependency management.
# Clone and install
git clone https://github.com/allankp/pytest-testrail.git
cd pytest-testrail
uv sync
# Run tests
uv run pytest
# Run linting
uv run ruff check pytest_testrail tests
uv run mypy pytest_testrail
# Test with different Python versions
uv run --python 3.10 pytest
uv run --python 3.12 pytestSee CHANGELOG.md for version history.