0
# Enhanced Test Cases
1
2
Enhanced TestCase class that extends unittest.TestCase with additional assertion methods, content attachments, fixture support, and improved error reporting capabilities.
3
4
## Capabilities
5
6
### Core TestCase Class
7
8
Extended test case with matcher-based assertions, content attachment support, and enhanced error reporting.
9
10
```python { .api }
11
class TestCase(unittest.TestCase):
12
"""
13
Enhanced test case extending unittest.TestCase.
14
15
Provides additional assertion methods, content attachments,
16
and improved error reporting for comprehensive testing.
17
"""
18
19
def assertThat(self, matchee, matcher, message='', verbose=False):
20
"""
21
Assert that matchee matches the given matcher.
22
23
Args:
24
matchee: Object to be matched
25
matcher: Matcher instance to apply
26
message (str): Optional failure message
27
verbose (bool): Include detailed mismatch info
28
29
Raises:
30
MismatchError: If matcher does not match matchee
31
"""
32
33
def expectThat(self, matchee, matcher):
34
"""
35
Check expectation without failing immediately.
36
37
Allows multiple expectations to be checked, with failures
38
reported at test completion.
39
40
Args:
41
matchee: Object to be matched
42
matcher: Matcher instance to apply
43
"""
44
45
def addDetail(self, name, content_object):
46
"""
47
Add debugging detail to test result.
48
49
Args:
50
name (str): Detail identifier
51
content_object (Content): Content to attach
52
"""
53
54
def getDetails(self):
55
"""
56
Get all attached details.
57
58
Returns:
59
dict: Mapping of detail names to Content objects
60
"""
61
62
def patch(self, obj, attribute, new_value):
63
"""
64
Apply a patch for the duration of the test.
65
66
Args:
67
obj: Object to patch
68
attribute (str): Attribute name to patch
69
new_value: New value for attribute
70
"""
71
72
def useFixture(self, fixture):
73
"""
74
Use a fixture for the test's duration.
75
76
Args:
77
fixture: Fixture instance with setUp/cleanUp methods
78
79
Returns:
80
The fixture instance
81
"""
82
```
83
84
### Test Placeholders and Error Holders
85
86
Placeholder classes for tests that failed to load or haven't been implemented yet.
87
88
```python { .api }
89
class PlaceHolder(TestCase):
90
"""
91
Placeholder for tests not yet implemented.
92
93
Useful for creating test structure before implementation.
94
"""
95
96
def __init__(self, test_id, short_description=None, details=None, outcome='addSuccess'):
97
"""
98
Create a placeholder test.
99
100
Args:
101
test_id (str): Unique test identifier
102
short_description (str): Brief test description
103
details (dict): Additional test details
104
outcome (str): Expected test outcome
105
"""
106
107
class ErrorHolder(PlaceHolder):
108
"""
109
Placeholder for tests that failed to load.
110
111
Represents tests that couldn't be imported or constructed
112
due to errors in the test definition.
113
"""
114
115
def __init__(self, test_id, error, short_description=None, details=None):
116
"""
117
Create an error holder for a failed test.
118
119
Args:
120
test_id (str): Test identifier that failed
121
error: Exception that prevented test loading
122
short_description (str): Brief error description
123
details (dict): Error details
124
"""
125
```
126
127
### Test Skipping Decorators
128
129
Decorators for skipping tests conditionally or unconditionally.
130
131
```python { .api }
132
def skip(reason):
133
"""
134
Skip test unconditionally.
135
136
Args:
137
reason (str): Reason for skipping
138
139
Returns:
140
Test decorator function
141
"""
142
143
def skipIf(condition, reason):
144
"""
145
Skip test if condition is true.
146
147
Args:
148
condition: Boolean condition to evaluate
149
reason (str): Reason for skipping
150
151
Returns:
152
Test decorator function
153
"""
154
155
def skipUnless(condition, reason):
156
"""
157
Skip test unless condition is true.
158
159
Args:
160
condition: Boolean condition to evaluate
161
reason (str): Reason for skipping
162
163
Returns:
164
Test decorator function
165
"""
166
```
167
168
### Expected Exception Context Manager
169
170
Context manager for asserting that specific exceptions are raised.
171
172
```python { .api }
173
class ExpectedException:
174
"""
175
Context manager for expected exceptions.
176
177
More flexible than unittest's assertRaises with support
178
for matcher-based exception validation.
179
"""
180
181
def __init__(self, matcher_or_exception, msg=None):
182
"""
183
Create expected exception context.
184
185
Args:
186
matcher_or_exception: Exception class or matcher
187
msg (str): Optional failure message
188
"""
189
190
def __enter__(self):
191
"""Enter context manager."""
192
return self
193
194
def __exit__(self, exc_type, exc_value, traceback):
195
"""
196
Exit context manager and validate exception.
197
198
Returns:
199
bool: True if exception was expected and handled
200
"""
201
```
202
203
### Test Utilities
204
205
Utility functions for working with test cases and test organization.
206
207
```python { .api }
208
def clone_test_with_new_id(test, new_id):
209
"""
210
Clone a test with a new test ID.
211
212
Args:
213
test: Original test case instance
214
new_id (str): New test identifier
215
216
Returns:
217
TestCase: Cloned test with new ID
218
"""
219
220
def run_test_with(test_runner):
221
"""
222
Decorator to specify custom test runner.
223
224
Args:
225
test_runner: RunTest class or instance
226
227
Returns:
228
Test method decorator
229
"""
230
231
def unique_text_generator():
232
"""
233
Generate unique text strings.
234
235
Yields:
236
str: Unique text strings for test isolation
237
"""
238
```
239
240
## Usage Examples
241
242
### Basic Enhanced Test Case
243
244
```python
245
import testtools
246
from testtools.matchers import Equals, Contains, GreaterThan
247
248
class MyEnhancedTest(testtools.TestCase):
249
250
def test_matcher_assertions(self):
251
# Use matchers for sophisticated assertions
252
self.assertThat("Hello World", Contains("World"))
253
self.assertThat(42, GreaterThan(40))
254
self.assertThat([1, 2, 3], MatchesListwise([
255
Equals(1), Equals(2), Equals(3)
256
]))
257
258
def test_with_debug_content(self):
259
# Attach debugging information
260
debug_data = {"state": "processing", "count": 42}
261
self.addDetail('debug_state',
262
testtools.content.json_content(debug_data))
263
264
# Test continues normally
265
result = process_data()
266
self.assertThat(result, Contains("success"))
267
268
def test_expected_exception(self):
269
# Test expected exceptions with matchers
270
with testtools.ExpectedException(
271
MatchesException(ValueError, "Invalid.*input")
272
):
273
process_invalid_input()
274
275
@testtools.skip("Feature not implemented")
276
def test_future_feature(self):
277
pass
278
279
@testtools.skipIf(os.name == 'nt', "Unix-only test")
280
def test_unix_feature(self):
281
# Test Unix-specific functionality
282
pass
283
```
284
285
### Using Fixtures
286
287
```python
288
import testtools
289
from fixtures import TempDir
290
291
class MyFixtureTest(testtools.TestCase):
292
293
def test_with_temp_directory(self):
294
# Use fixture for temporary directory
295
temp_dir = self.useFixture(TempDir())
296
297
# Write test file
298
test_file = os.path.join(temp_dir.path, 'test.txt')
299
with open(test_file, 'w') as f:
300
f.write('test content')
301
302
# Test file operations
303
self.assertTrue(os.path.exists(test_file))
304
# Fixture automatically cleaned up
305
```
306
307
### Expectation-Based Testing
308
309
```python
310
class MyExpectationTest(testtools.TestCase):
311
312
def test_multiple_expectations(self):
313
# Check multiple expectations without immediate failure
314
data = get_complex_data()
315
316
self.expectThat(data['status'], Equals('success'))
317
self.expectThat(data['count'], GreaterThan(0))
318
self.expectThat(data['items'], HasLength(5))
319
320
# All expectations checked, failures reported together
321
```