Skip to content

Commit c79aeba

Browse files
committed
Python unittest.expectedFailure improvements
Raises an _UnexpectedSuccess exception Takes a boolean parameter with a condition under which the test is expected to fail
1 parent d8ad5a3 commit c79aeba

File tree

2 files changed

+66
-4
lines changed

2 files changed

+66
-4
lines changed

python/testing/__init__.py

+64
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import os
2929
import sys
3030
import difflib
31+
import functools
3132

3233
from PyQt4.QtCore import QVariant
3334
from qgis.core import QgsApplication, QgsFeatureRequest, QgsVectorLayer
@@ -154,8 +155,71 @@ def assertFilesEqual(self, filepath_expected, filepath_result):
154155
self.assertEqual(0, len(diff), ''.join(diff))
155156

156157

158+
class _UnexpectedSuccess(Exception):
159+
"""
160+
The test was supposed to fail, but it didn't!
161+
"""
162+
pass
163+
164+
165+
def expectedFailure(*args):
166+
"""
167+
Will decorate a unittest function as an expectedFailure. A function
168+
flagged as expectedFailure will be succeed if it raises an exception.
169+
If it does not raise an exception, this will throw an
170+
`_UnexpectedSuccess` exception.
171+
172+
@expectedFailure
173+
def my_test(self):
174+
self.assertTrue(False)
175+
176+
The decorator also accepts a parameter to only expect a failure under
177+
certain conditions.
178+
179+
@expectedFailure(time.localtime().tm_year < 2002)
180+
def my_test(self):
181+
self.assertTrue(qgisIsInvented())
182+
"""
183+
if hasattr(args[0], '__call__'):
184+
# We got a function as parameter: assume usage like
185+
# @expectedFailure
186+
# def testfunction():
187+
func = args[0]
188+
189+
@functools.wraps(func)
190+
def wrapper(*args, **kwargs):
191+
try:
192+
func(*args, **kwargs)
193+
except Exception:
194+
pass
195+
else:
196+
raise _UnexpectedSuccess
197+
return wrapper
198+
else:
199+
# We got a function as parameter: assume usage like
200+
# @expectedFailure(failsOnThisPlatform)
201+
# def testfunction():
202+
condition = args[0]
203+
204+
def realExpectedFailure(func):
205+
@functools.wraps(func)
206+
def wrapper(*args, **kwargs):
207+
if condition:
208+
try:
209+
func(*args, **kwargs)
210+
except Exception:
211+
pass
212+
else:
213+
raise _UnexpectedSuccess
214+
else:
215+
func(*args, **kwargs)
216+
return wrapper
217+
218+
return realExpectedFailure
219+
157220
# Patch unittest
158221
unittest.TestCase = TestCase
222+
unittest.expectedFailure = expectedFailure
159223

160224

161225
def start_app():

tests/src/python/test_qgsvectorfilewriter.py

+2-4
Original file line numberDiff line numberDiff line change
@@ -172,13 +172,11 @@ def testDateTimeWriteTabfile(self):
172172
assert isinstance(f.attributes()[datetime_idx], QDateTime)
173173
self.assertEqual(f.attributes()[datetime_idx], QDateTime(QDate(2014, 3, 5), QTime(13, 45, 22)))
174174

175+
# This test fails on Travis Linux build for unknown reason (probably GDAL version related)
176+
@unittest.expectedFailure(os.environ.get('TRAVIS') and 'linux' in platform.system().lower())
175177
def testWriteShapefileWithZ(self):
176178
"""Check writing geometries with Z dimension to an ESRI shapefile."""
177179

178-
if os.environ.get('TRAVIS') and 'linux' in platform.system().lower():
179-
# This test fails on Travis Linux build for unknown reason (probably GDAL version related)
180-
return
181-
182180
#start by saving a memory layer and forcing z
183181
ml = QgsVectorLayer(
184182
('Point?crs=epsg:4326&field=id:int'),

0 commit comments

Comments
 (0)