Tavern: API Testing Framework
Tavern is a Python library, pytest plugin, and command-line tool designed for automated testing of APIs, including RESTful, MQTT, and gRPC services. It utilizes a simple, concise, and flexible YAML-based syntax for defining tests, making it highly customizable for complex scenarios. Currently at version 3.3.3, Tavern maintains an active development status and integrates seamlessly with the pytest ecosystem for comprehensive test management and reporting.
Common errors
-
Expected only one document in this file but found multiple
cause This error typically occurs when a `.tavern.yaml` file contains multiple top-level YAML documents (separated by `---`) but only one `test_name` is expected, or when `is_defaults: true` is misused.fixEnsure each logical test or set of tests is correctly structured as separate documents if intended, or that `is_defaults: true` is correctly applied to a single defaults document at the top of the file. Each test needs its own `test_name`. -
KeyError: 'test_name'
cause A test definition in a `.tavern.yaml` file is missing the required `test_name` key.fixAdd a unique `test_name` string to each test definition in your YAML file, e.g., `test_name: My API Test`. -
tavern.util.exceptions.MissingExtFunctionError: Could not find external function 'your_function' in any of [...]
cause Tavern cannot locate a Python function referenced using `!ext` in your YAML test file. This often means the Python file containing the function is not on the Python path or the function name is incorrect.fixEnsure the directory containing your Python module with the external function is included in the `PYTHONPATH` environment variable. Double-check the function name and module path in your YAML file. -
yaml.scanner.ScannerError: mapping values are not allowed here
cause This is a general YAML syntax error, usually caused by incorrect indentation, missing colons, or improper use of special characters in the `.tavern.yaml` file.fixCarefully review the YAML syntax around the indicated line and column in the error message. Pay close attention to indentation, colons, and valid YAML structure. Use a YAML linter if available.
Warnings
- gotcha When using `!include` for shared YAML snippets (e.g., common stages or configurations), ensure the `TAVERN_INCLUDE` environment variable is set with the absolute path to the directory containing included files, or use correct relative paths. Otherwise, Tavern might not locate the included files.
- gotcha Files containing Tavern tests intended for execution with `pytest` must follow the `test_*.tavern.yaml` naming convention for automatic discovery. Files not adhering to this pattern will be ignored by pytest.
- gotcha The `is_defaults: true` flag for sharing common configuration across multiple tests in a single YAML file should only be used in the *first* document within that file. Subsequent documents will merge its contents, with test-specific values taking precedence. The defaults document itself cannot contain test definitions.
- deprecated Older versions of Tavern (prior to 0.26.5) experienced breaking compatibility with `pytest` versions 4.6.0 and above due to internal API changes in `pytest`. While this was addressed in newer Tavern releases, users on older Tavern versions might face issues.
Install
-
pip install tavern
Imports
- run
from tavern.core import run
- tavern
import tavern
- validate_jwt, validate_regex, validate_content, check_jmespath_match
from tavern.helpers import validate_jwt, validate_regex, validate_content, check_jmespath_match
- BaseRequest, BaseResponse
from tavern.request import BaseRequest from tavern.response import BaseResponse
Quickstart
import pytest
import os
# Create a dummy test_example.tavern.yaml file
with open('test_example.tavern.yaml', 'w') as f:
f.write("""
---
test_name: Get some fake data from the JSON placeholder API
stages:
- name: Make sure we have the right ID
request:
url: https://jsonplaceholder.typicode.com/posts/1
method: GET
response:
status_code: 200
json:
id: 1
""")
# Run pytest (this assumes pytest is installed and finds the .tavern.yaml file)
# In a real scenario, you'd run 'pytest' from the command line.
# For programmatic execution, you would use tavern.core.run directly.
print("Created test_example.tavern.yaml. Run 'pytest -v test_example.tavern.yaml' in your terminal.")
# For demonstration, we'll simulate running it (actual pytest.main() might exit the interpreter)
# pytest.main(['-v', 'test_example.tavern.yaml'])