Clarify dangerous use of exceptions in unit tests

Also, update unit tests to use more specific exception where possible
to make auditing easier in the future.

Change-Id: I4906e2f8e3ebacf0587f1471ca8dd46c73edc17a
This commit is contained in:
Johannes Erdfelt 2012-09-20 17:19:05 +00:00
parent 2dd5cb8fb0
commit a86e362ddd
2 changed files with 26 additions and 7 deletions

View File

@ -54,13 +54,33 @@ Writing Integration Tests
TBD TBD
Tests and assertRaises Tests and Exceptions
---------------------- --------------------
When asserting that a test should raise an exception, test against the A properly written test asserts that particular behavior occurs. This can
most specific exception possible. An overly broad exception type (like be a success condition or a failure condition, including an exception.
Exception) can mask errors in the unit test itself. When asserting that a particular exception is raised, the most specific
exception possible should be used.
In particular, testing for Exception being raised is almost always a
mistake since it will match (almost) every exception, even those
unrelated to the exception intended to be tested.
This applies to catching exceptions manually with a try/except block,
or using assertRaises().
Example:: Example::
self.assertRaises(exception.InstanceNotFound, db.instance_get_by_uuid, self.assertRaises(exception.InstanceNotFound, db.instance_get_by_uuid,
elevated, instance_uuid) elevated, instance_uuid)
If a stubbed function/method needs a generic exception for testing
purposes, test.TestingException is available.
Example::
def stubbed_method(self):
raise test.TestingException()
self.stubs.Set(cls, 'inner_method', stubbed_method)
obj = cls()
self.assertRaises(test.TestingException, obj.outer_method)

View File

@ -46,11 +46,10 @@ class DbApiTestCase(test.TestCase):
return db.instance_create(self.context, args) return db.instance_create(self.context, args)
def test_ec2_ids_not_found_are_printable(self): def test_ec2_ids_not_found_are_printable(self):
def check_exc_format(method): def check_exc_format(method):
try: try:
method(self.context, 'fake') method(self.context, 'fake')
except Exception as exc: except exception.NotFound as exc:
self.assertTrue('fake' in unicode(exc)) self.assertTrue('fake' in unicode(exc))
check_exc_format(db.get_ec2_volume_id_by_uuid) check_exc_format(db.get_ec2_volume_id_by_uuid)