Add a short description here
Project description
unittest-observability
This is a Python project for unittest observability.
Features
This library provides several mixins to enhance unittest with observability features:
TimingMixin: Integrates withunittest.TestCaseto automatically measure and report the execution time of each test method. It now usestime.monotonic()for more accurate duration measurements, helping in identifying slow tests and performance bottlenecks. Its proxy methods (timing_class_setup,timing_class_teardown,timing_method_setup,timing_method_teardown) now return detailed timing information or explanatory strings.InventoryMixin: Designed forunittest.TestCase, this mixin now discovers alltest_*methods within a class duringsetUpClass. IntearDownClass, it reports on the total number of tests discovered, how many actually ran, and identifies any tests that were skipped or not executed. This provides a comprehensive inventory and helps diagnose missing or skipped tests. Its proxy methods (inventory_class_setup,inventory_class_teardown,inventory_method_setup,inventory_method_teardown) now return inventory statistics or explanatory strings.ResultMixin: Extendsunittest.TestResultto gather detailed information about the outcome of each test, including success, failure, errors, skips, and execution duration. It also usestime.monotonic()for precise duration tracking and provides full tracebacks for issues. This provides a rich dataset for analysis and reporting.
Usage
TimingMixin and InventoryMixin
To use TimingMixin or InventoryMixin, simply inherit from them in your unittest.TestCase classes. It's recommended to place unittest.TestCase first in the inheritance list for conventional Method Resolution Order (MRO).
Important: The mixins provide proxy methods that must be explicitly called within your unittest.TestCase's setUpClass, tearDownClass, setUp, and tearDown methods to enable their functionality. Remember to call super().setUpClass()/super().setUp() first in your setup methods, and super().tearDownClass()/super().tearDown() last in your teardown methods.
import unittest
from unittest_observability import TimingMixin, InventoryMixin
class MyTests(unittest.TestCase, TimingMixin, InventoryMixin): # Updated inheritance order
@classmethod
def setUpClass(cls):
super().setUpClass() # Call parent setUpClass first
cls.inventory_class_setup() # Initialize InventoryMixin for the class
cls.timing_class_setup() # Initialize TimingMixin for the class
@classmethod
def tearDownClass(cls):
# Call mixin teardown methods to get results before parent tearDownClass
inventory_stats = cls.inventory_class_teardown()
timing_stats = cls.timing_class_teardown()
print(f"Class Inventory Stats: {inventory_stats}")
print(f"Class Timing Stats: {timing_stats}")
super().tearDownClass() # Call parent tearDownClass last
def setUp(self):
super().setUp() # Call parent setUp first
self.inventory_method_setup() # Initialize InventoryMixin for the method
self.timing_method_setup() # Initialize TimingMixin for the method
def tearDown(self):
# Call mixin teardown methods to get results before parent tearDown
method_inventory = self.inventory_method_teardown()
method_timing = self.timing_method_teardown()
print(f"Method Inventory: {method_inventory}")
print(f"Method Timing: {method_timing}")
super().tearDown() # Call parent tearDown last
def test_example(self):
# Your test code
self.assertTrue(True)
# To access inventory (after tests have run):
# expected_inventory = MyTests.get_expected_inventory()
# ran_inventory = MyTests.get_test_inventory()
The proxy methods (timing_class_setup, timing_class_teardown, etc.) now return data (strings, lists, or dictionaries) which you can capture and process as needed, rather than just printing to sys.stdout.
ResultMixin
ResultMixin extends unittest.TestResult and is designed to be used with a unittest.TextTestRunner (or similar test runner) by passing it as the resultclass argument. This allows it to collect detailed results from all tests run by the runner.
import unittest
from unittest_observability import ResultMixin
# Assuming you have a TestSuite or individual TestCases
suite = unittest.TestSuite()
# suite.addTest(...)
runner = unittest.TextTestRunner(resultclass=ResultMixin)
result = runner.run(suite)
# Access collected results
detailed_results = result.get_collected_results()
for test_info in detailed_results:
print(test_info)
Development and Publishing
This project uses GitHub Actions for continuous integration and publishing. A workflow is configured to build and publish the package to TestPyPI on pushes to the main branch or when a new tag (e.g., v1.0.0) is created. The CI pipeline now also includes coverage measurement to ensure code quality. Ensure you have a TEST_PYPI_API_TOKEN GitHub Secret configured for publishing.
For local development, you can run tests with coverage using the provided batch script:
run_tests_with_coverage.bat
Changelog
See CHANGELOG.md for a history of changes.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file unittest_observability-0.2.0.tar.gz.
File metadata
- Download URL: unittest_observability-0.2.0.tar.gz
- Upload date:
- Size: 20.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d1e03df8de7b0ff76ae3cd6f72d3f67ca5a67a664483514ce72519ea5e3bc889
|
|
| MD5 |
ad20dd2888918de1e13de05eb18cfbf5
|
|
| BLAKE2b-256 |
1f34d563bc5c67952f9cc3842a5335d23dca2db1b20d3ab53127d83a3879ea29
|
Provenance
The following attestation bundles were made for unittest_observability-0.2.0.tar.gz:
Publisher:
publish.yml on Eki23/unittest-observability
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
unittest_observability-0.2.0.tar.gz -
Subject digest:
d1e03df8de7b0ff76ae3cd6f72d3f67ca5a67a664483514ce72519ea5e3bc889 - Sigstore transparency entry: 2047501545
- Sigstore integration time:
-
Permalink:
Eki23/unittest-observability@9fb58092f876fc5dcadf9902dd777547e5d2a14d -
Branch / Tag:
refs/heads/main - Owner: https://github.com/Eki23
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@9fb58092f876fc5dcadf9902dd777547e5d2a14d -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file unittest_observability-0.2.0-py3-none-any.whl.
File metadata
- Download URL: unittest_observability-0.2.0-py3-none-any.whl
- Upload date:
- Size: 13.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
587525c5853abfb61467a332e04227a6a3c89db86c480cad4e6a21e863acfbb5
|
|
| MD5 |
72c9041711f64d648203975f923fd9af
|
|
| BLAKE2b-256 |
ed51630f41dfd4e12af0aa522b6a492aaed2678af66befb4a7e390f537b93acb
|
Provenance
The following attestation bundles were made for unittest_observability-0.2.0-py3-none-any.whl:
Publisher:
publish.yml on Eki23/unittest-observability
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
unittest_observability-0.2.0-py3-none-any.whl -
Subject digest:
587525c5853abfb61467a332e04227a6a3c89db86c480cad4e6a21e863acfbb5 - Sigstore transparency entry: 2047501575
- Sigstore integration time:
-
Permalink:
Eki23/unittest-observability@9fb58092f876fc5dcadf9902dd777547e5d2a14d -
Branch / Tag:
refs/heads/main - Owner: https://github.com/Eki23
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@9fb58092f876fc5dcadf9902dd777547e5d2a14d -
Trigger Event:
workflow_dispatch
-
Statement type: