Extensions to the Python standard library unit testing framework
Enhanced TestCase class that extends unittest.TestCase with additional assertion methods, content attachments, fixture support, and improved error reporting capabilities.
Extended test case with matcher-based assertions, content attachment support, and enhanced error reporting.
class TestCase(unittest.TestCase):
"""
Enhanced test case extending unittest.TestCase.
Provides additional assertion methods, content attachments,
and improved error reporting for comprehensive testing.
"""
def assertThat(self, matchee, matcher, message='', verbose=False):
"""
Assert that matchee matches the given matcher.
Args:
matchee: Object to be matched
matcher: Matcher instance to apply
message (str): Optional failure message
verbose (bool): Include detailed mismatch info
Raises:
MismatchError: If matcher does not match matchee
"""
def expectThat(self, matchee, matcher):
"""
Check expectation without failing immediately.
Allows multiple expectations to be checked, with failures
reported at test completion.
Args:
matchee: Object to be matched
matcher: Matcher instance to apply
"""
def addDetail(self, name, content_object):
"""
Add debugging detail to test result.
Args:
name (str): Detail identifier
content_object (Content): Content to attach
"""
def getDetails(self):
"""
Get all attached details.
Returns:
dict: Mapping of detail names to Content objects
"""
def patch(self, obj, attribute, new_value):
"""
Apply a patch for the duration of the test.
Args:
obj: Object to patch
attribute (str): Attribute name to patch
new_value: New value for attribute
"""
def useFixture(self, fixture):
"""
Use a fixture for the test's duration.
Args:
fixture: Fixture instance with setUp/cleanUp methods
Returns:
The fixture instance
"""Placeholder classes for tests that failed to load or haven't been implemented yet.
class PlaceHolder(TestCase):
"""
Placeholder for tests not yet implemented.
Useful for creating test structure before implementation.
"""
def __init__(self, test_id, short_description=None, details=None, outcome='addSuccess'):
"""
Create a placeholder test.
Args:
test_id (str): Unique test identifier
short_description (str): Brief test description
details (dict): Additional test details
outcome (str): Expected test outcome
"""
class ErrorHolder(PlaceHolder):
"""
Placeholder for tests that failed to load.
Represents tests that couldn't be imported or constructed
due to errors in the test definition.
"""
def __init__(self, test_id, error, short_description=None, details=None):
"""
Create an error holder for a failed test.
Args:
test_id (str): Test identifier that failed
error: Exception that prevented test loading
short_description (str): Brief error description
details (dict): Error details
"""Decorators for skipping tests conditionally or unconditionally.
def skip(reason):
"""
Skip test unconditionally.
Args:
reason (str): Reason for skipping
Returns:
Test decorator function
"""
def skipIf(condition, reason):
"""
Skip test if condition is true.
Args:
condition: Boolean condition to evaluate
reason (str): Reason for skipping
Returns:
Test decorator function
"""
def skipUnless(condition, reason):
"""
Skip test unless condition is true.
Args:
condition: Boolean condition to evaluate
reason (str): Reason for skipping
Returns:
Test decorator function
"""Context manager for asserting that specific exceptions are raised.
class ExpectedException:
"""
Context manager for expected exceptions.
More flexible than unittest's assertRaises with support
for matcher-based exception validation.
"""
def __init__(self, matcher_or_exception, msg=None):
"""
Create expected exception context.
Args:
matcher_or_exception: Exception class or matcher
msg (str): Optional failure message
"""
def __enter__(self):
"""Enter context manager."""
return self
def __exit__(self, exc_type, exc_value, traceback):
"""
Exit context manager and validate exception.
Returns:
bool: True if exception was expected and handled
"""Utility functions for working with test cases and test organization.
def clone_test_with_new_id(test, new_id):
"""
Clone a test with a new test ID.
Args:
test: Original test case instance
new_id (str): New test identifier
Returns:
TestCase: Cloned test with new ID
"""
def run_test_with(test_runner):
"""
Decorator to specify custom test runner.
Args:
test_runner: RunTest class or instance
Returns:
Test method decorator
"""
def unique_text_generator():
"""
Generate unique text strings.
Yields:
str: Unique text strings for test isolation
"""import testtools
from testtools.matchers import Equals, Contains, GreaterThan
class MyEnhancedTest(testtools.TestCase):
def test_matcher_assertions(self):
# Use matchers for sophisticated assertions
self.assertThat("Hello World", Contains("World"))
self.assertThat(42, GreaterThan(40))
self.assertThat([1, 2, 3], MatchesListwise([
Equals(1), Equals(2), Equals(3)
]))
def test_with_debug_content(self):
# Attach debugging information
debug_data = {"state": "processing", "count": 42}
self.addDetail('debug_state',
testtools.content.json_content(debug_data))
# Test continues normally
result = process_data()
self.assertThat(result, Contains("success"))
def test_expected_exception(self):
# Test expected exceptions with matchers
with testtools.ExpectedException(
MatchesException(ValueError, "Invalid.*input")
):
process_invalid_input()
@testtools.skip("Feature not implemented")
def test_future_feature(self):
pass
@testtools.skipIf(os.name == 'nt', "Unix-only test")
def test_unix_feature(self):
# Test Unix-specific functionality
passimport testtools
from fixtures import TempDir
class MyFixtureTest(testtools.TestCase):
def test_with_temp_directory(self):
# Use fixture for temporary directory
temp_dir = self.useFixture(TempDir())
# Write test file
test_file = os.path.join(temp_dir.path, 'test.txt')
with open(test_file, 'w') as f:
f.write('test content')
# Test file operations
self.assertTrue(os.path.exists(test_file))
# Fixture automatically cleaned upclass MyExpectationTest(testtools.TestCase):
def test_multiple_expectations(self):
# Check multiple expectations without immediate failure
data = get_complex_data()
self.expectThat(data['status'], Equals('success'))
self.expectThat(data['count'], GreaterThan(0))
self.expectThat(data['items'], HasLength(5))
# All expectations checked, failures reported togetherInstall with Tessl CLI
npx tessl i tessl/pypi-testtools