Testscenarios
Testscenarios is a Python library that extends `unittest` to provide clean dependency injection, enabling a single test method to be run with multiple scenarios. This is particularly useful for interface testing (testing many implementations via a single test suite) or for classic dependency injection, where test dependencies are provided externally. The library is currently at version 0.5.0, offering a stable approach to scenario-based testing.
Warnings
- gotcha When using `TestWithScenarios` as a mixin, it must be the first class in the MRO (Method Resolution Order) of your `unittest.TestCase` subclass. Additionally, you must not override the `run()` or `__call__()` methods in your test class, as `TestWithScenarios` relies on these to generate and execute tests for each scenario.
- gotcha If using `per_module_scenarios` for dependency injection, ensure all access to the module under test goes through the attribute set by the scenario on the test object (e.g., `self.my_module`). Directly importing the module within the test file will bypass the scenario's injected dependency, potentially leading to incorrect test results or unexpected behavior.
- gotcha Modifying the `scenarios` attribute dynamically after a test has been loaded but before it runs can lead to unexpected behavior if not handled carefully. Multiple tests might share a single `scenarios` attribute, so altering it for one test could unintentionally affect others.
- gotcha The GitHub repository indicates support for Python 3.10 and newer, while the PyPI `requires_python` metadata is `None`. Using `testscenarios` with Python versions older than 3.10 may lead to compatibility issues or unexpected behavior.
Install
-
pip install testscenarios
Imports
- TestWithScenarios
from testscenarios.testscenarios import TestWithScenarios
from testscenarios import TestWithScenarios
- load_tests_apply_scenarios
from testscenarios import load_tests_apply_scenarios
Quickstart
import unittest
from testscenarios import TestWithScenarios
class MyScenarioTest(TestWithScenarios, unittest.TestCase):
# Define scenarios as a list of (name, dictionary_of_parameters) tuples
scenarios = [
('addition_scenario', dict(num1=5, num2=3, expected_sum=8)),
('subtraction_scenario', dict(num1=10, num2=4, expected_difference=6)),
('multiplication_scenario', dict(num1=2, num2=6, expected_product=12))
]
def test_addition(self):
"""Test addition operation using scenario parameters."""
# Parameters from the current scenario are automatically available as instance attributes
actual_sum = self.num1 + self.num2
self.assertEqual(actual_sum, self.expected_sum)
def test_subtraction(self):
"""Test subtraction operation using scenario parameters."""
actual_difference = self.num1 - self.num2
self.assertEqual(actual_difference, self.expected_difference)
def test_multiplication(self):
"""Test multiplication operation using scenario parameters."""
actual_product = self.num1 * self.num2
self.assertEqual(actual_product, self.expected_product)
if __name__ == '__main__':
unittest.main()