Browse Source

Replaced use of TestCase.fail() with assertRaises().

Also removed try/except/fail antipattern that hides exceptions.
Tim Graham 8 years ago
parent
commit
c9ae09addf

+ 2 - 10
tests/admin_views/tests.py

@@ -1243,10 +1243,7 @@ class CustomModelAdminTest(AdminViewBasicTestCase):
         self.assertContains(response, 'Hello from a custom logout template')
 
     def test_custom_admin_site_index_view_and_template(self):
-        try:
-            response = self.client.get(reverse('admin2:index'))
-        except TypeError:
-            self.fail('AdminSite.index_template should accept a list of template paths')
+        response = self.client.get(reverse('admin2:index'))
         self.assertIsInstance(response, TemplateResponse)
         self.assertTemplateUsed(response, 'custom_admin/index.html')
         self.assertContains(response, 'Hello from a custom index template *bar*')
@@ -1283,12 +1280,7 @@ class CustomModelAdminTest(AdminViewBasicTestCase):
     def test_pwd_change_custom_template(self):
         self.client.force_login(self.superuser)
         su = User.objects.get(username='super')
-        try:
-            response = self.client.get(
-                reverse('admin4:auth_user_password_change', args=(su.pk,))
-            )
-        except TypeError:
-            self.fail('ModelAdmin.change_user_password_template should accept a list of template paths')
+        response = self.client.get(reverse('admin4:auth_user_password_change', args=(su.pk,)))
         self.assertEqual(response.status_code, 200)
 
 

+ 2 - 9
tests/check_framework/tests.py

@@ -224,10 +224,7 @@ class SilencingCheckTests(SimpleTestCase):
     def test_silenced_error(self):
         out = StringIO()
         err = StringIO()
-        try:
-            call_command('check', stdout=out, stderr=err)
-        except CommandError:
-            self.fail("The mycheck.E001 check should be silenced.")
+        call_command('check', stdout=out, stderr=err)
         self.assertEqual(out.getvalue(), 'System check identified no issues (1 silenced).\n')
         self.assertEqual(err.getvalue(), '')
 
@@ -236,11 +233,7 @@ class SilencingCheckTests(SimpleTestCase):
     def test_silenced_warning(self):
         out = StringIO()
         err = StringIO()
-        try:
-            call_command('check', stdout=out, stderr=err)
-        except CommandError:
-            self.fail("The mycheck.E001 check should be silenced.")
-
+        call_command('check', stdout=out, stderr=err)
         self.assertEqual(out.getvalue(), 'System check identified no issues (1 silenced).\n')
         self.assertEqual(err.getvalue(), '')
 

+ 4 - 5
tests/file_uploads/tests.py

@@ -7,6 +7,7 @@ import hashlib
 import json
 import os
 import shutil
+import sys
 import tempfile as sys_tempfile
 import unittest
 from io import BytesIO
@@ -564,16 +565,14 @@ class DirectoryCreationTests(SimpleTestCase):
     def setUp(self):
         self.obj = FileModel()
 
+    @unittest.skipIf(sys.platform == 'win32', "Python on Windows doesn't have working os.chmod().")
     def test_readonly_root(self):
         """Permission errors are not swallowed"""
         os.chmod(MEDIA_ROOT, 0o500)
         self.addCleanup(os.chmod, MEDIA_ROOT, 0o700)
-        try:
+        with self.assertRaises(OSError) as cm:
             self.obj.testfile.save('foo.txt', SimpleUploadedFile('foo.txt', b'x'), save=False)
-        except OSError as err:
-            self.assertEqual(err.errno, errno.EACCES)
-        except Exception:
-            self.fail("OSError [Errno %s] not raised." % errno.EACCES)
+        self.assertEqual(cm.exception.errno, errno.EACCES)
 
     def test_not_a_directory(self):
         """The correct IOError is raised when the upload directory name exists but isn't a directory"""

+ 6 - 21
tests/fixtures_regress/tests.py

@@ -11,7 +11,6 @@ import warnings
 import django
 from django.core import management, serializers
 from django.core.exceptions import ImproperlyConfigured
-from django.core.management.base import CommandError
 from django.core.serializers.base import DeserializationError
 from django.db import IntegrityError, transaction
 from django.db.models import signals
@@ -838,15 +837,9 @@ class M2MNaturalKeyFixtureTests(TestCase):
         A, B, C, AtoB, BtoC, CtoA = (M2MComplexCircular1A, M2MComplexCircular1B,
                                      M2MComplexCircular1C, M2MCircular1ThroughAB,
                                      M2MCircular1ThroughBC, M2MCircular1ThroughCA)
-        try:
-            sorted_deps = serializers.sort_dependencies(
-                [('fixtures_regress', [A, B, C, AtoB, BtoC, CtoA])]
-            )
-        except CommandError:
-            self.fail("Serialization dependency solving algorithm isn't "
-                      "capable of handling circular M2M setups with "
-                      "intermediate models.")
-
+        sorted_deps = serializers.sort_dependencies(
+            [('fixtures_regress', [A, B, C, AtoB, BtoC, CtoA])]
+        )
         # The dependency sorting should not result in an error, and the
         # through model should have dependencies to the other models and as
         # such come last in the list.
@@ -858,17 +851,9 @@ class M2MNaturalKeyFixtureTests(TestCase):
         Circular M2M relations with explicit through models should be serializable
         This test tests the circularity with explicit natural_key.dependencies
         """
-        try:
-            sorted_deps = serializers.sort_dependencies([
-                ('fixtures_regress', [
-                    M2MComplexCircular2A,
-                    M2MComplexCircular2B,
-                    M2MCircular2ThroughAB])
-            ])
-        except CommandError:
-            self.fail("Serialization dependency solving algorithm isn't "
-                      "capable of handling circular M2M setups with "
-                      "intermediate models plus natural key dependency hints.")
+        sorted_deps = serializers.sort_dependencies([
+            ('fixtures_regress', [M2MComplexCircular2A, M2MComplexCircular2B, M2MCircular2ThroughAB])
+        ])
         self.assertEqual(sorted_deps[:2], [M2MComplexCircular2A, M2MComplexCircular2B])
         self.assertEqual(sorted_deps[2:], [M2MCircular2ThroughAB])
 

+ 2 - 4
tests/forms_tests/tests/test_error_messages.py

@@ -16,11 +16,9 @@ from django.utils.safestring import mark_safe
 
 class AssertFormErrorsMixin(object):
     def assertFormErrors(self, expected, the_callable, *args, **kwargs):
-        try:
+        with self.assertRaises(ValidationError) as cm:
             the_callable(*args, **kwargs)
-            self.fail("Testing the 'clean' method on %s failed to raise a ValidationError.")
-        except ValidationError as e:
-            self.assertEqual(e.messages, expected)
+        self.assertEqual(cm.exception.messages, expected)
 
 
 class FormsErrorMessagesTestCase(SimpleTestCase, AssertFormErrorsMixin):

+ 4 - 8
tests/forms_tests/tests/test_forms.py

@@ -173,11 +173,9 @@ class FormsTestCase(SimpleTestCase):
         self.assertFalse(p.is_bound)
         self.assertEqual(p.errors, {})
         self.assertFalse(p.is_valid())
-        try:
+        with self.assertRaises(AttributeError):
             p.cleaned_data
-            self.fail('Attempts to access cleaned_data when validation fails should fail.')
-        except AttributeError:
-            pass
+
         self.assertHTMLEqual(
             str(p),
             """<tr><th><label for="id_first_name">First name:</label></th><td>
@@ -2168,11 +2166,9 @@ Password: <input type="password" name="password" required />
         self.assertEqual(p.errors['last_name'], ['This field is required.'])
         self.assertEqual(p.errors['birthday'], ['This field is required.'])
         self.assertEqual(p['first_name'].errors, ['This field is required.'])
-        try:
+        # Accessing a nonexistent field.
+        with self.assertRaises(KeyError):
             p['person1-first_name'].errors
-            self.fail('Attempts to access non-existent fields should fail.')
-        except KeyError:
-            pass
 
         # In this example, the data doesn't have a prefix, but the form requires it, so
         # the form doesn't "see" the fields.

+ 1 - 4
tests/forms_tests/tests/test_formsets.py

@@ -1012,11 +1012,8 @@ class FormsFormsetTestCase(SimpleTestCase):
 
         # confirm indexing of formset
         self.assertEqual(formset[0], forms[0])
-        try:
+        with self.assertRaises(IndexError):
             formset[3]
-            self.fail('Requesting an invalid formset index should raise an exception')
-        except IndexError:
-            pass
 
         # Formsets can override the default iteration order
         class BaseReverseFormSet(BaseFormSet):

+ 5 - 9
tests/generic_relations_regress/tests.py

@@ -115,16 +115,12 @@ class GenericRelationTests(TestCase):
             note.save()
 
     def test_target_model_len_zero(self):
-        """Test for #13085 -- __len__() returns 0"""
+        """
+        Saving a model with a GenericForeignKey to a model instance whose
+        __len__ method returns 0 (Team.__len__() here) shouldn't fail (#13085).
+        """
         team1 = Team.objects.create(name='Backend devs')
-        try:
-            note = Note(note='Deserve a bonus', content_object=team1)
-        except Exception as e:
-            if (issubclass(type(e), Exception) and
-                    str(e) == 'Impossible arguments to GFK.get_content_type!'):
-                self.fail("Saving model with GenericForeignKey to model instance whose "
-                          "__len__ method returns 0 shouldn't fail.")
-            raise e
+        note = Note(note='Deserve a bonus', content_object=team1)
         note.save()
 
     def test_target_model_nonzero_false(self):

+ 2 - 8
tests/generic_views/test_base.py

@@ -78,21 +78,15 @@ class ViewTest(unittest.TestCase):
         """
         Test that a view can't be accidentally instantiated before deployment
         """
-        try:
+        with self.assertRaises(AttributeError):
             SimpleView(key='value').as_view()
-            self.fail('Should not be able to instantiate a view')
-        except AttributeError:
-            pass
 
     def test_no_init_args(self):
         """
         Test that a view can't be accidentally instantiated before deployment
         """
-        try:
+        with self.assertRaises(TypeError):
             SimpleView.as_view('value')
-            self.fail('Should not be able to use non-keyword arguments instantiating a view')
-        except TypeError:
-            pass
 
     def test_pathological_http_method(self):
         """

+ 3 - 6
tests/get_or_create/tests.py

@@ -212,13 +212,10 @@ class GetOrCreateTestsWithManualPKs(TestCase):
 
     def test_get_or_create_empty(self):
         """
-        Regression test for #16137: get_or_create does not require kwargs.
+        If all the attributes on a model have defaults, get_or_create() doesn't
+        require any arguments.
         """
-        try:
-            DefaultPerson.objects.get_or_create()
-        except AssertionError:
-            self.fail("If all the attributes on a model have defaults, we "
-                      "shouldn't need to pass any arguments.")
+        DefaultPerson.objects.get_or_create()
 
 
 class GetOrCreateTransactionTests(TransactionTestCase):

+ 1 - 5
tests/gis_tests/gdal_tests/test_ds.py

@@ -80,12 +80,8 @@ class DataSourceTest(unittest.TestCase):
             self.assertEqual(source.driver, str(ds.driver))
 
             # Making sure indexing works
-            try:
+            with self.assertRaises(OGRIndexError):
                 ds[len(ds)]
-            except OGRIndexError:
-                pass
-            else:
-                self.fail('Expected an IndexError!')
 
     def test02_invalid_shp(self):
         "Testing invalid SHP files for the Data Source."

+ 2 - 4
tests/gis_tests/gdal_tests/test_envelope.py

@@ -39,10 +39,8 @@ class EnvelopeTest(unittest.TestCase):
             Envelope('foo')
         with self.assertRaises(GDALException):
             Envelope((1, 1, 0, 0))
-        try:
-            Envelope(0, 0, 0, 0)
-        except GDALException:
-            self.fail("shouldn't raise an exception for min_x == max_x or min_y == max_y")
+        # Shouldn't raise an exception for min_x == max_x or min_y == max_y
+        Envelope(0, 0, 0, 0)
 
     def test02_properties(self):
         "Testing Envelope properties."

+ 1 - 4
tests/gis_tests/geoapp/test_serializers.py

@@ -25,10 +25,7 @@ class GeoJSONSerializerTests(TestCase):
 
     def test_serialization_base(self):
         geojson = serializers.serialize('geojson', City.objects.all().order_by('name'))
-        try:
-            geodata = json.loads(geojson)
-        except Exception:
-            self.fail("Serialized output is not valid JSON")
+        geodata = json.loads(geojson)
         self.assertEqual(len(geodata['features']), len(City.objects.all()))
         self.assertEqual(geodata['features'][0]['geometry']['type'], 'Point')
         self.assertEqual(geodata['features'][0]['properties']['name'], 'Chicago')

+ 1 - 5
tests/gis_tests/geoapp/tests.py

@@ -43,12 +43,8 @@ class GeoModelTest(TestCase):
         # Making sure TypeError is thrown when trying to set with an
         #  incompatible type.
         for bad in [5, 2.0, LineString((0, 0), (1, 1))]:
-            try:
+            with self.assertRaisesMessage(TypeError, 'Cannot set'):
                 nullcity.point = bad
-            except TypeError:
-                pass
-            else:
-                self.fail('Should throw a TypeError')
 
         # Now setting with a compatible GEOS Geometry, saving, and ensuring
         #  the save took, notice no SRID is explicitly set.

+ 2 - 5
tests/i18n/tests.py

@@ -526,11 +526,8 @@ class TranslationThreadSafetyTests(SimpleTestCase):
 
     def test_bug14894_translation_activate_thread_safety(self):
         translation_count = len(trans_real._translations)
-        try:
-            translation.activate('pl')
-        except RuntimeError:
-            self.fail('translation.activate() is not thread-safe')
-
+        # May raise RuntimeError if translation.activate() isn't thread-safe.
+        translation.activate('pl')
         # make sure sideeffect_str actually added a new translation
         self.assertLess(translation_count, len(trans_real._translations))
 

+ 7 - 16
tests/model_forms/tests.py

@@ -305,7 +305,7 @@ class ModelFormBaseTest(TestCase):
                          ['name', 'slug', 'url', 'some_extra_field'])
 
     def test_extra_field_model_form(self):
-        try:
+        with self.assertRaisesMessage(FieldError, 'no-field'):
             class ExtraPersonForm(forms.ModelForm):
                 """ ModelForm with an extra field """
                 age = forms.IntegerField()
@@ -313,24 +313,15 @@ class ModelFormBaseTest(TestCase):
                 class Meta:
                     model = Person
                     fields = ('name', 'no-field')
-        except FieldError as e:
-            # Make sure the exception contains some reference to the
-            # field responsible for the problem.
-            self.assertIn('no-field', e.args[0])
-        else:
-            self.fail('Invalid "no-field" field not caught')
 
     def test_extra_declared_field_model_form(self):
-        try:
-            class ExtraPersonForm(forms.ModelForm):
-                """ ModelForm with an extra field """
-                age = forms.IntegerField()
+        class ExtraPersonForm(forms.ModelForm):
+            """ ModelForm with an extra field """
+            age = forms.IntegerField()
 
-                class Meta:
-                    model = Person
-                    fields = ('name', 'age')
-        except FieldError:
-            self.fail('Declarative field raised FieldError incorrectly')
+            class Meta:
+                model = Person
+                fields = ('name', 'age')
 
     def test_extra_field_modelform_factory(self):
         with self.assertRaises(FieldError):

+ 101 - 171
tests/multiple_database/tests.py

@@ -1115,10 +1115,7 @@ class RouterTestCase(TestCase):
         mark = Person.objects.using('other').create(name="Mark Pilgrim")
 
         # Set a foreign key with an object from a different database
-        try:
-            dive.editor = marty
-        except ValueError:
-            self.fail("Assignment across primary/replica databases with a common source should be ok")
+        dive.editor = marty
 
         # Database assignments of original objects haven't changed...
         self.assertEqual(marty._state.db, 'default')
@@ -1131,20 +1128,14 @@ class RouterTestCase(TestCase):
         self.assertEqual(dive._state.db, 'default')
 
         # ...and the source database now has a copy of any object saved
-        try:
-            Book.objects.using('default').get(title='Dive into Python').delete()
-        except Book.DoesNotExist:
-            self.fail('Source database should have a copy of saved object')
+        Book.objects.using('default').get(title='Dive into Python').delete()
 
         # This isn't a real primary/replica database, so restore the original from other
         dive = Book.objects.using('other').get(title='Dive into Python')
         self.assertEqual(dive._state.db, 'other')
 
         # Set a foreign key set with an object from a different database
-        try:
-            marty.edited.set([pro, dive], bulk=False)
-        except ValueError:
-            self.fail("Assignment across primary/replica databases with a common source should be ok")
+        marty.edited.set([pro, dive], bulk=False)
 
         # Assignment implies a save, so database assignments of original objects have changed...
         self.assertEqual(marty._state.db, 'default')
@@ -1153,20 +1144,14 @@ class RouterTestCase(TestCase):
         self.assertEqual(mark._state.db, 'other')
 
         # ...and the source database now has a copy of any object saved
-        try:
-            Book.objects.using('default').get(title='Dive into Python').delete()
-        except Book.DoesNotExist:
-            self.fail('Source database should have a copy of saved object')
+        Book.objects.using('default').get(title='Dive into Python').delete()
 
         # This isn't a real primary/replica database, so restore the original from other
         dive = Book.objects.using('other').get(title='Dive into Python')
         self.assertEqual(dive._state.db, 'other')
 
         # Add to a foreign key set with an object from a different database
-        try:
-            marty.edited.add(dive, bulk=False)
-        except ValueError:
-            self.fail("Assignment across primary/replica databases with a common source should be ok")
+        marty.edited.add(dive, bulk=False)
 
         # Add implies a save, so database assignments of original objects have changed...
         self.assertEqual(marty._state.db, 'default')
@@ -1175,10 +1160,7 @@ class RouterTestCase(TestCase):
         self.assertEqual(mark._state.db, 'other')
 
         # ...and the source database now has a copy of any object saved
-        try:
-            Book.objects.using('default').get(title='Dive into Python').delete()
-        except Book.DoesNotExist:
-            self.fail('Source database should have a copy of saved object')
+        Book.objects.using('default').get(title='Dive into Python').delete()
 
         # This isn't a real primary/replica database, so restore the original from other
         dive = Book.objects.using('other').get(title='Dive into Python')
@@ -1261,10 +1243,7 @@ class RouterTestCase(TestCase):
         self.assertEqual(Person.objects.using('other').count(), 2)
 
         # Set a m2m set with an object from a different database
-        try:
-            marty.book_set.set([pro, dive])
-        except ValueError:
-            self.fail("Assignment across primary/replica databases with a common source should be ok")
+        marty.book_set.set([pro, dive])
 
         # Database assignments don't change
         self.assertEqual(marty._state.db, 'default')
@@ -1280,10 +1259,7 @@ class RouterTestCase(TestCase):
         Book.authors.through.objects.using('default').delete()
 
         # Add to an m2m with an object from a different database
-        try:
-            marty.book_set.add(dive)
-        except ValueError:
-            self.fail("Assignment across primary/replica databases with a common source should be ok")
+        marty.book_set.add(dive)
 
         # Database assignments don't change
         self.assertEqual(marty._state.db, 'default')
@@ -1299,10 +1275,7 @@ class RouterTestCase(TestCase):
         Book.authors.through.objects.using('default').delete()
 
         # Set a reverse m2m with an object from a different database
-        try:
-            dive.authors.set([mark, marty])
-        except ValueError:
-            self.fail("Assignment across primary/replica databases with a common source should be ok")
+        dive.authors.set([mark, marty])
 
         # Database assignments don't change
         self.assertEqual(marty._state.db, 'default')
@@ -1321,10 +1294,7 @@ class RouterTestCase(TestCase):
         self.assertEqual(Book.authors.through.objects.using('other').count(), 0)
 
         # Add to a reverse m2m with an object from a different database
-        try:
-            dive.authors.add(marty)
-        except ValueError:
-            self.fail("Assignment across primary/replica databases with a common source should be ok")
+        dive.authors.add(marty)
 
         # Database assignments don't change
         self.assertEqual(marty._state.db, 'default')
@@ -1359,10 +1329,7 @@ class RouterTestCase(TestCase):
 
         # Set a one-to-one relation with an object from a different database
         alice_profile = UserProfile.objects.create(user=alice, flavor='chocolate')
-        try:
-            bob.userprofile = alice_profile
-        except ValueError:
-            self.fail("Assignment across primary/replica databases with a common source should be ok")
+        bob.userprofile = alice_profile
 
         # Database assignments of original objects haven't changed...
         self.assertEqual(alice._state.db, 'default')
@@ -1390,10 +1357,7 @@ class RouterTestCase(TestCase):
             'other').create(source="Python Weekly", content_object=dive)
 
         # Set a generic foreign key with an object from a different database
-        try:
-            review1.content_object = dive
-        except ValueError:
-            self.fail("Assignment across primary/replica databases with a common source should be ok")
+        review1.content_object = dive
 
         # Database assignments of original objects haven't changed...
         self.assertEqual(pro._state.db, 'default')
@@ -1407,20 +1371,14 @@ class RouterTestCase(TestCase):
         self.assertEqual(dive._state.db, 'default')
 
         # ...and the source database now has a copy of any object saved
-        try:
-            Book.objects.using('default').get(title='Dive into Python').delete()
-        except Book.DoesNotExist:
-            self.fail('Source database should have a copy of saved object')
+        Book.objects.using('default').get(title='Dive into Python').delete()
 
         # This isn't a real primary/replica database, so restore the original from other
         dive = Book.objects.using('other').get(title='Dive into Python')
         self.assertEqual(dive._state.db, 'other')
 
         # Add to a generic foreign key set with an object from a different database
-        try:
-            dive.reviews.add(review1)
-        except ValueError:
-            self.fail("Assignment across primary/replica databases with a common source should be ok")
+        dive.reviews.add(review1)
 
         # Database assignments of original objects haven't changed...
         self.assertEqual(pro._state.db, 'default')
@@ -1433,10 +1391,7 @@ class RouterTestCase(TestCase):
         self.assertEqual(dive._state.db, 'default')
 
         # ...and the source database now has a copy of any object saved
-        try:
-            Book.objects.using('default').get(title='Dive into Python').delete()
-        except Book.DoesNotExist:
-            self.fail('Source database should have a copy of saved object')
+        Book.objects.using('default').get(title='Dive into Python').delete()
 
         # BUT! if you assign a FK object when the base object hasn't
         # been saved yet, you implicitly assign the database for the
@@ -1601,20 +1556,14 @@ class FixtureTestCase(TestCase):
     def test_fixture_loading(self):
         "Multi-db fixtures are loaded correctly"
         # Check that "Pro Django" exists on the default database, but not on other database
-        try:
-            Book.objects.get(title="Pro Django")
-            Book.objects.using('default').get(title="Pro Django")
-        except Book.DoesNotExist:
-            self.fail('"Pro Django" should exist on default database')
+        Book.objects.get(title="Pro Django")
+        Book.objects.using('default').get(title="Pro Django")
 
         with self.assertRaises(Book.DoesNotExist):
             Book.objects.using('other').get(title="Pro Django")
 
         # Check that "Dive into Python" exists on the default database, but not on other database
-        try:
-            Book.objects.using('other').get(title="Dive into Python")
-        except Book.DoesNotExist:
-            self.fail('"Dive into Python" should exist on other database')
+        Book.objects.using('other').get(title="Dive into Python")
 
         with self.assertRaises(Book.DoesNotExist):
             Book.objects.get(title="Dive into Python")
@@ -1622,12 +1571,9 @@ class FixtureTestCase(TestCase):
             Book.objects.using('default').get(title="Dive into Python")
 
         # Check that "Definitive Guide" exists on the both databases
-        try:
-            Book.objects.get(title="The Definitive Guide to Django")
-            Book.objects.using('default').get(title="The Definitive Guide to Django")
-            Book.objects.using('other').get(title="The Definitive Guide to Django")
-        except Book.DoesNotExist:
-            self.fail('"The Definitive Guide to Django" should exist on both databases')
+        Book.objects.get(title="The Definitive Guide to Django")
+        Book.objects.using('default').get(title="The Definitive Guide to Django")
+        Book.objects.using('other').get(title="The Definitive Guide to Django")
 
     @override_settings(DATABASE_ROUTERS=[AntiPetRouter()])
     def test_pseudo_empty_fixtures(self):
@@ -1906,210 +1852,194 @@ class RouteForWriteTestCase(TestCase):
     def test_fk_delete(self):
         owner = Person.objects.create(name='Someone')
         pet = Pet.objects.create(name='fido', owner=owner)
-        try:
+        with self.assertRaises(RouterUsed) as cm:
             with self.override_router():
                 pet.owner.delete()
-            self.fail('db_for_write() not invoked on router')
-        except RouterUsed as e:
-            self.assertEqual(e.mode, RouterUsed.WRITE)
-            self.assertEqual(e.model, Person)
-            self.assertEqual(e.hints, {'instance': owner})
+        e = cm.exception
+        self.assertEqual(e.mode, RouterUsed.WRITE)
+        self.assertEqual(e.model, Person)
+        self.assertEqual(e.hints, {'instance': owner})
 
     def test_reverse_fk_delete(self):
         owner = Person.objects.create(name='Someone')
         to_del_qs = owner.pet_set.all()
-        try:
+        with self.assertRaises(RouterUsed) as cm:
             with self.override_router():
                 to_del_qs.delete()
-            self.fail('db_for_write() not invoked on router')
-        except RouterUsed as e:
-            self.assertEqual(e.mode, RouterUsed.WRITE)
-            self.assertEqual(e.model, Pet)
-            self.assertEqual(e.hints, {'instance': owner})
+        e = cm.exception
+        self.assertEqual(e.mode, RouterUsed.WRITE)
+        self.assertEqual(e.model, Pet)
+        self.assertEqual(e.hints, {'instance': owner})
 
     def test_reverse_fk_get_or_create(self):
         owner = Person.objects.create(name='Someone')
-        try:
+        with self.assertRaises(RouterUsed) as cm:
             with self.override_router():
                 owner.pet_set.get_or_create(name='fido')
-            self.fail('db_for_write() not invoked on router')
-        except RouterUsed as e:
-            self.assertEqual(e.mode, RouterUsed.WRITE)
-            self.assertEqual(e.model, Pet)
-            self.assertEqual(e.hints, {'instance': owner})
+        e = cm.exception
+        self.assertEqual(e.mode, RouterUsed.WRITE)
+        self.assertEqual(e.model, Pet)
+        self.assertEqual(e.hints, {'instance': owner})
 
     def test_reverse_fk_update(self):
         owner = Person.objects.create(name='Someone')
         Pet.objects.create(name='fido', owner=owner)
-        try:
+        with self.assertRaises(RouterUsed) as cm:
             with self.override_router():
                 owner.pet_set.update(name='max')
-            self.fail('db_for_write() not invoked on router')
-        except RouterUsed as e:
-            self.assertEqual(e.mode, RouterUsed.WRITE)
-            self.assertEqual(e.model, Pet)
-            self.assertEqual(e.hints, {'instance': owner})
+        e = cm.exception
+        self.assertEqual(e.mode, RouterUsed.WRITE)
+        self.assertEqual(e.model, Pet)
+        self.assertEqual(e.hints, {'instance': owner})
 
     def test_m2m_add(self):
         auth = Person.objects.create(name='Someone')
         book = Book.objects.create(title="Pro Django",
                                    published=datetime.date(2008, 12, 16))
-        try:
+        with self.assertRaises(RouterUsed) as cm:
             with self.override_router():
                 book.authors.add(auth)
-            self.fail('db_for_write() not invoked on router')
-        except RouterUsed as e:
-            self.assertEqual(e.mode, RouterUsed.WRITE)
-            self.assertEqual(e.model, Book.authors.through)
-            self.assertEqual(e.hints, {'instance': book})
+        e = cm.exception
+        self.assertEqual(e.mode, RouterUsed.WRITE)
+        self.assertEqual(e.model, Book.authors.through)
+        self.assertEqual(e.hints, {'instance': book})
 
     def test_m2m_clear(self):
         auth = Person.objects.create(name='Someone')
         book = Book.objects.create(title="Pro Django",
                                    published=datetime.date(2008, 12, 16))
         book.authors.add(auth)
-        try:
+        with self.assertRaises(RouterUsed) as cm:
             with self.override_router():
                 book.authors.clear()
-            self.fail('db_for_write() not invoked on router')
-        except RouterUsed as e:
-            self.assertEqual(e.mode, RouterUsed.WRITE)
-            self.assertEqual(e.model, Book.authors.through)
-            self.assertEqual(e.hints, {'instance': book})
+        e = cm.exception
+        self.assertEqual(e.mode, RouterUsed.WRITE)
+        self.assertEqual(e.model, Book.authors.through)
+        self.assertEqual(e.hints, {'instance': book})
 
     def test_m2m_delete(self):
         auth = Person.objects.create(name='Someone')
         book = Book.objects.create(title="Pro Django",
                                    published=datetime.date(2008, 12, 16))
         book.authors.add(auth)
-        try:
+        with self.assertRaises(RouterUsed) as cm:
             with self.override_router():
                 book.authors.all().delete()
-            self.fail('db_for_write() not invoked on router')
-        except RouterUsed as e:
-            self.assertEqual(e.mode, RouterUsed.WRITE)
-            self.assertEqual(e.model, Person)
-            self.assertEqual(e.hints, {'instance': book})
+        e = cm.exception
+        self.assertEqual(e.mode, RouterUsed.WRITE)
+        self.assertEqual(e.model, Person)
+        self.assertEqual(e.hints, {'instance': book})
 
     def test_m2m_get_or_create(self):
         Person.objects.create(name='Someone')
         book = Book.objects.create(title="Pro Django",
                                    published=datetime.date(2008, 12, 16))
-        try:
+        with self.assertRaises(RouterUsed) as cm:
             with self.override_router():
                 book.authors.get_or_create(name='Someone else')
-            self.fail('db_for_write() not invoked on router')
-        except RouterUsed as e:
-            self.assertEqual(e.mode, RouterUsed.WRITE)
-            self.assertEqual(e.model, Book)
-            self.assertEqual(e.hints, {'instance': book})
+        e = cm.exception
+        self.assertEqual(e.mode, RouterUsed.WRITE)
+        self.assertEqual(e.model, Book)
+        self.assertEqual(e.hints, {'instance': book})
 
     def test_m2m_remove(self):
         auth = Person.objects.create(name='Someone')
         book = Book.objects.create(title="Pro Django",
                                    published=datetime.date(2008, 12, 16))
         book.authors.add(auth)
-        try:
+        with self.assertRaises(RouterUsed) as cm:
             with self.override_router():
                 book.authors.remove(auth)
-            self.fail('db_for_write() not invoked on router')
-        except RouterUsed as e:
-            self.assertEqual(e.mode, RouterUsed.WRITE)
-            self.assertEqual(e.model, Book.authors.through)
-            self.assertEqual(e.hints, {'instance': book})
+        e = cm.exception
+        self.assertEqual(e.mode, RouterUsed.WRITE)
+        self.assertEqual(e.model, Book.authors.through)
+        self.assertEqual(e.hints, {'instance': book})
 
     def test_m2m_update(self):
         auth = Person.objects.create(name='Someone')
         book = Book.objects.create(title="Pro Django",
                                    published=datetime.date(2008, 12, 16))
         book.authors.add(auth)
-        try:
+        with self.assertRaises(RouterUsed) as cm:
             with self.override_router():
                 book.authors.all().update(name='Different')
-            self.fail('db_for_write() not invoked on router')
-        except RouterUsed as e:
-            self.assertEqual(e.mode, RouterUsed.WRITE)
-            self.assertEqual(e.model, Person)
-            self.assertEqual(e.hints, {'instance': book})
+        e = cm.exception
+        self.assertEqual(e.mode, RouterUsed.WRITE)
+        self.assertEqual(e.model, Person)
+        self.assertEqual(e.hints, {'instance': book})
 
     def test_reverse_m2m_add(self):
         auth = Person.objects.create(name='Someone')
         book = Book.objects.create(title="Pro Django",
                                    published=datetime.date(2008, 12, 16))
-        try:
+        with self.assertRaises(RouterUsed) as cm:
             with self.override_router():
                 auth.book_set.add(book)
-            self.fail('db_for_write() not invoked on router')
-        except RouterUsed as e:
-            self.assertEqual(e.mode, RouterUsed.WRITE)
-            self.assertEqual(e.model, Book.authors.through)
-            self.assertEqual(e.hints, {'instance': auth})
+        e = cm.exception
+        self.assertEqual(e.mode, RouterUsed.WRITE)
+        self.assertEqual(e.model, Book.authors.through)
+        self.assertEqual(e.hints, {'instance': auth})
 
     def test_reverse_m2m_clear(self):
         auth = Person.objects.create(name='Someone')
         book = Book.objects.create(title="Pro Django",
                                    published=datetime.date(2008, 12, 16))
         book.authors.add(auth)
-        try:
+        with self.assertRaises(RouterUsed) as cm:
             with self.override_router():
                 auth.book_set.clear()
-            self.fail('db_for_write() not invoked on router')
-        except RouterUsed as e:
-            self.assertEqual(e.mode, RouterUsed.WRITE)
-            self.assertEqual(e.model, Book.authors.through)
-            self.assertEqual(e.hints, {'instance': auth})
+        e = cm.exception
+        self.assertEqual(e.mode, RouterUsed.WRITE)
+        self.assertEqual(e.model, Book.authors.through)
+        self.assertEqual(e.hints, {'instance': auth})
 
     def test_reverse_m2m_delete(self):
         auth = Person.objects.create(name='Someone')
         book = Book.objects.create(title="Pro Django",
                                    published=datetime.date(2008, 12, 16))
         book.authors.add(auth)
-        try:
+        with self.assertRaises(RouterUsed) as cm:
             with self.override_router():
                 auth.book_set.all().delete()
-            self.fail('db_for_write() not invoked on router')
-        except RouterUsed as e:
-            self.assertEqual(e.mode, RouterUsed.WRITE)
-            self.assertEqual(e.model, Book)
-            self.assertEqual(e.hints, {'instance': auth})
+        e = cm.exception
+        self.assertEqual(e.mode, RouterUsed.WRITE)
+        self.assertEqual(e.model, Book)
+        self.assertEqual(e.hints, {'instance': auth})
 
     def test_reverse_m2m_get_or_create(self):
         auth = Person.objects.create(name='Someone')
         Book.objects.create(title="Pro Django",
                             published=datetime.date(2008, 12, 16))
-        try:
+        with self.assertRaises(RouterUsed) as cm:
             with self.override_router():
                 auth.book_set.get_or_create(title="New Book", published=datetime.datetime.now())
-            self.fail('db_for_write() not invoked on router')
-        except RouterUsed as e:
-            self.assertEqual(e.mode, RouterUsed.WRITE)
-            self.assertEqual(e.model, Person)
-            self.assertEqual(e.hints, {'instance': auth})
+        e = cm.exception
+        self.assertEqual(e.mode, RouterUsed.WRITE)
+        self.assertEqual(e.model, Person)
+        self.assertEqual(e.hints, {'instance': auth})
 
     def test_reverse_m2m_remove(self):
         auth = Person.objects.create(name='Someone')
         book = Book.objects.create(title="Pro Django",
                                    published=datetime.date(2008, 12, 16))
         book.authors.add(auth)
-        try:
+        with self.assertRaises(RouterUsed) as cm:
             with self.override_router():
                 auth.book_set.remove(book)
-            self.fail('db_for_write() not invoked on router')
-        except RouterUsed as e:
-            self.assertEqual(e.mode, RouterUsed.WRITE)
-            self.assertEqual(e.model, Book.authors.through)
-            self.assertEqual(e.hints, {'instance': auth})
+        e = cm.exception
+        self.assertEqual(e.mode, RouterUsed.WRITE)
+        self.assertEqual(e.model, Book.authors.through)
+        self.assertEqual(e.hints, {'instance': auth})
 
     def test_reverse_m2m_update(self):
         auth = Person.objects.create(name='Someone')
         book = Book.objects.create(title="Pro Django",
                                    published=datetime.date(2008, 12, 16))
         book.authors.add(auth)
-        try:
+        with self.assertRaises(RouterUsed) as cm:
             with self.override_router():
                 auth.book_set.all().update(title='Different')
-            self.fail('db_for_write() not invoked on router')
-        except RouterUsed as e:
-            self.assertEqual(e.mode, RouterUsed.WRITE)
-            self.assertEqual(e.model, Book)
-            self.assertEqual(e.hints, {'instance': auth})
+        e = cm.exception
+        self.assertEqual(e.mode, RouterUsed.WRITE)
+        self.assertEqual(e.model, Book)
+        self.assertEqual(e.hints, {'instance': auth})

+ 1 - 4
tests/proxy_models/tests.py

@@ -188,10 +188,7 @@ class ProxyModelTests(TestCase):
 
     def test_permissions_created(self):
         from django.contrib.auth.models import Permission
-        try:
-            Permission.objects.get(name="May display users information")
-        except Permission.DoesNotExist:
-            self.fail("The permission 'May display users information' has not been created")
+        Permission.objects.get(name="May display users information")
 
     def test_proxy_model_signals(self):
         """

+ 4 - 8
tests/queries/tests.py

@@ -2621,14 +2621,10 @@ class UnionTests(unittest.TestCase):
 
 class DefaultValuesInsertTest(TestCase):
     def test_no_extra_params(self):
-        # Ticket #17056 -- affects Oracle
-        try:
-            DumbCategory.objects.create()
-        except TypeError:
-            self.fail(
-                "Creation of an instance of a model with only the PK field "
-                "shouldn't error out after bulk insert refactoring (#17056)"
-            )
+        """
+        Can create an instance of a model with only the PK field (#17056)."
+        """
+        DumbCategory.objects.create()
 
 
 class ExcludeTests(TestCase):

+ 2 - 8
tests/raw_query/tests.py

@@ -221,11 +221,8 @@ class RawQueryTests(TestCase):
 
     def test_missing_fields_without_PK(self):
         query = "SELECT first_name, dob FROM raw_query_author"
-        try:
+        with self.assertRaisesMessage(InvalidQuery, 'Raw query must include the primary key'):
             list(Author.objects.raw(query))
-            self.fail('Query without primary key should fail')
-        except InvalidQuery:
-            pass
 
     def test_annotations(self):
         query = (
@@ -290,10 +287,7 @@ class RawQueryTests(TestCase):
         self.assertNumQueries(1, list, Author.objects.raw("SELECT * FROM raw_query_author"))
 
     def test_subquery_in_raw_sql(self):
-        try:
-            list(Book.objects.raw('SELECT id FROM (SELECT * FROM raw_query_book WHERE paperback IS NOT NULL) sq'))
-        except InvalidQuery:
-            self.fail("Using a subquery in a RawQuerySet raised InvalidQuery")
+        list(Book.objects.raw('SELECT id FROM (SELECT * FROM raw_query_book WHERE paperback IS NOT NULL) sq'))
 
     def test_db_column_name_is_used_in_raw_query(self):
         """

+ 1 - 7
tests/sessions_tests/tests.py

@@ -198,13 +198,7 @@ class SessionTestsMixin(object):
         # removed the key) results in a new key being generated.
         try:
             session = self.backend('1')
-            try:
-                session.save()
-            except AttributeError:
-                self.fail(
-                    "The session object did not save properly. "
-                    "Middleware may be saving cache items without namespaces."
-                )
+            session.save()
             self.assertNotEqual(session.session_key, '1')
             self.assertIsNone(session.get('cat'))
             session.delete()

+ 1 - 4
tests/settings_tests/tests.py

@@ -127,10 +127,7 @@ class ClassDecoratedTestCase(ClassDecoratedTestCaseSuper):
         Overriding a method on a super class and then calling that method on
         the super class should not trigger infinite recursion. See #17011.
         """
-        try:
-            super(ClassDecoratedTestCase, self).test_max_recursion_error()
-        except RuntimeError:
-            self.fail()
+        super(ClassDecoratedTestCase, self).test_max_recursion_error()
 
 
 @modify_settings(ITEMS={'append': 'mother'})

+ 1 - 5
tests/swappable_models/tests.py

@@ -44,9 +44,5 @@ class SwappableModelTests(TestCase):
     @override_settings(TEST_ARTICLE_MODEL='swappable_models.article')
     def test_case_insensitive(self):
         "Model names are case insensitive. Check that model swapping honors this."
-        try:
-            Article.objects.all()
-        except AttributeError:
-            self.fail('Swappable model names should be case insensitive.')
-
+        Article.objects.all()
         self.assertIsNone(Article._meta.swapped)

+ 1 - 12
tests/test_client/tests.py

@@ -613,14 +613,10 @@ class ClientTest(TestCase):
     def test_session_modifying_view(self):
         "Request a page that modifies the session"
         # Session value isn't set initially
-        try:
+        with self.assertRaises(KeyError):
             self.client.session['tobacconist']
-            self.fail("Shouldn't have a session value")
-        except KeyError:
-            pass
 
         self.client.post('/session_view/')
-
         # Check that the session was modified
         self.assertEqual(self.client.session['tobacconist'], 'hovercraft')
 
@@ -644,13 +640,6 @@ class ClientTest(TestCase):
         with self.assertRaises(KeyError):
             self.client.get("/broken_view/")
 
-        # Try the same assertion, a different way
-        try:
-            self.client.get('/broken_view/')
-            self.fail('Should raise an error')
-        except KeyError:
-            pass
-
     def test_mail_sending(self):
         "Test that mail is redirected to a dummy outbox during test setup"
 

+ 4 - 17
tests/test_client_regress/tests.py

@@ -875,21 +875,15 @@ class ExceptionTests(TestDataMixin, TestCase):
 
         login = self.client.login(username='testclient', password='password')
         self.assertTrue(login, 'Could not log in')
-        try:
+        with self.assertRaises(CustomTestException):
             self.client.get("/staff_only/")
-            self.fail("General users should not be able to visit this page")
-        except CustomTestException:
-            pass
 
         # At this point, an exception has been raised, and should be cleared.
 
         # This next operation should be successful; if it isn't we have a problem.
         login = self.client.login(username='staff', password='password')
         self.assertTrue(login, 'Could not log in')
-        try:
-            self.client.get("/staff_only/")
-        except CustomTestException:
-            self.fail("Staff should be able to visit this page")
+        self.client.get("/staff_only/")
 
 
 @override_settings(ROOT_URLCONF='test_client_regress.urls')
@@ -901,12 +895,8 @@ class TemplateExceptionTests(SimpleTestCase):
     }])
     def test_bad_404_template(self):
         "Errors found when rendering 404 error templates are re-raised"
-        try:
+        with self.assertRaises(TemplateSyntaxError):
             self.client.get("/no_such_view/")
-        except TemplateSyntaxError:
-            pass
-        else:
-            self.fail("Should get error about syntax error in template")
 
 
 # We need two different tests to check URLconf substitution -  one to check
@@ -945,11 +935,8 @@ class ContextTests(TestDataMixin, TestCase):
         self.assertEqual(response.context['get-foo'], 'whiz')
         self.assertEqual(response.context['data'], 'sausage')
 
-        try:
+        with self.assertRaisesMessage(KeyError, 'does-not-exist'):
             response.context['does-not-exist']
-            self.fail('Should not be able to retrieve non-existent key')
-        except KeyError as e:
-            self.assertEqual(e.args[0], 'does-not-exist')
 
     def test_inherited_context(self):
         "Context variables can be retrieved from a list of contexts"

+ 5 - 16
tests/test_runner/tests.py

@@ -240,12 +240,8 @@ class DummyBackendTest(unittest.TestCase):
         tested_connections = db.ConnectionHandler({})
         with mock.patch('django.test.runner.connections', new=tested_connections):
             runner_instance = DiscoverRunner(verbosity=0)
-            try:
-                old_config = runner_instance.setup_databases()
-                runner_instance.teardown_databases(old_config)
-            except Exception as e:
-                self.fail("setup_databases/teardown_databases unexpectedly raised "
-                          "an error: %s" % e)
+            old_config = runner_instance.setup_databases()
+            runner_instance.teardown_databases(old_config)
 
 
 class AliasedDefaultTestSetupTest(unittest.TestCase):
@@ -263,12 +259,8 @@ class AliasedDefaultTestSetupTest(unittest.TestCase):
         })
         with mock.patch('django.test.runner.connections', new=tested_connections):
             runner_instance = DiscoverRunner(verbosity=0)
-            try:
-                old_config = runner_instance.setup_databases()
-                runner_instance.teardown_databases(old_config)
-            except Exception as e:
-                self.fail("setup_databases/teardown_databases unexpectedly raised "
-                          "an error: %s" % e)
+            old_config = runner_instance.setup_databases()
+            runner_instance.teardown_databases(old_config)
 
 
 class SetupDatabasesTests(unittest.TestCase):
@@ -366,7 +358,4 @@ class EmptyDefaultDatabaseTest(unittest.TestCase):
         testcases.connections = db.ConnectionHandler({'default': {}})
         connection = testcases.connections[db.utils.DEFAULT_DB_ALIAS]
         self.assertEqual(connection.settings_dict['ENGINE'], 'django.db.backends.dummy')
-        try:
-            connections_support_transactions()
-        except Exception as e:
-            self.fail("connections_support_transactions() unexpectedly raised an error: %s" % e)
+        connections_support_transactions()

+ 31 - 49
tests/urlpatterns_reverse/tests.py

@@ -5,7 +5,6 @@ Unit tests for reverse URL lookups.
 from __future__ import unicode_literals
 
 import sys
-import unittest
 
 from admin_scripts.tests import AdminScriptTestCase
 
@@ -313,16 +312,9 @@ class URLPatternReverse(SimpleTestCase):
 
     def test_patterns_reported(self):
         # Regression for #17076
-        try:
+        with self.assertRaisesMessage(NoReverseMatch, r"1 pattern(s) tried: ['people/(?P<name>\\w+)/$']"):
             # this url exists, but requires an argument
             reverse("people", args=[])
-        except NoReverseMatch as e:
-            pattern_description = r"1 pattern(s) tried: ['people/(?P<name>\\w+)/$']"
-            self.assertIn(pattern_description, str(e))
-        else:
-            # we can't use .assertRaises, since we want to inspect the
-            # exception
-            self.fail("Expected a NoReverseMatch, but none occurred.")
 
     @override_script_prefix('/script:name/')
     def test_script_name_escaping(self):
@@ -339,7 +331,7 @@ class URLPatternReverse(SimpleTestCase):
         )
 
 
-class ResolverTests(unittest.TestCase):
+class ResolverTests(SimpleTestCase):
     @ignore_warnings(category=RemovedInDjango20Warning)
     def test_resolver_repr(self):
         """
@@ -359,10 +351,7 @@ class ResolverTests(unittest.TestCase):
         urls = 'urlpatterns_reverse.named_urls'
         proxy_url = reverse_lazy('named-url1', urlconf=urls)
         resolver = get_resolver(urls)
-        try:
-            resolver.resolve(proxy_url)
-        except TypeError:
-            self.fail('Failed to coerce lazy object to text')
+        resolver.resolve(proxy_url)
 
     def test_resolver_reverse(self):
         resolver = get_resolver('urlpatterns_reverse.named_urls')
@@ -407,32 +396,31 @@ class ResolverTests(unittest.TestCase):
             [{'type': RegexURLResolver}, {'type': RegexURLPattern, 'name': None}],
             [{'type': RegexURLResolver}, {'type': RegexURLResolver}],
         ]
-        try:
+        with self.assertRaisesMessage(Resolver404, "tried") as cm:
             resolve('/included/non-existent-url', urlconf=urls)
-            self.fail('resolve did not raise a 404')
-        except Resolver404 as e:
-            # make sure we at least matched the root ('/') url resolver:
-            self.assertIn('tried', e.args[0])
-            tried = e.args[0]['tried']
-            self.assertEqual(
-                len(e.args[0]['tried']),
-                len(url_types_names),
-                'Wrong number of tried URLs returned.  Expected %s, got %s.' % (
-                    len(url_types_names), len(e.args[0]['tried'])
-                )
+        e = cm.exception
+        # make sure we at least matched the root ('/') url resolver:
+        self.assertIn('tried', e.args[0])
+        tried = e.args[0]['tried']
+        self.assertEqual(
+            len(e.args[0]['tried']),
+            len(url_types_names),
+            'Wrong number of tried URLs returned.  Expected %s, got %s.' % (
+                len(url_types_names), len(e.args[0]['tried'])
             )
-            for tried, expected in zip(e.args[0]['tried'], url_types_names):
-                for t, e in zip(tried, expected):
-                    self.assertIsInstance(t, e['type']), str('%s is not an instance of %s') % (t, e['type'])
-                    if 'name' in e:
-                        if not e['name']:
-                            self.assertIsNone(t.name, 'Expected no URL name but found %s.' % t.name)
-                        else:
-                            self.assertEqual(
-                                t.name,
-                                e['name'],
-                                'Wrong URL name.  Expected "%s", got "%s".' % (e['name'], t.name)
-                            )
+        )
+        for tried, expected in zip(e.args[0]['tried'], url_types_names):
+            for t, e in zip(tried, expected):
+                self.assertIsInstance(t, e['type']), str('%s is not an instance of %s') % (t, e['type'])
+                if 'name' in e:
+                    if not e['name']:
+                        self.assertIsNone(t.name, 'Expected no URL name but found %s.' % t.name)
+                    else:
+                        self.assertEqual(
+                            t.name,
+                            e['name'],
+                            'Wrong URL name.  Expected "%s", got "%s".' % (e['name'], t.name)
+                        )
 
     def test_namespaced_view_detail(self):
         resolver = get_resolver('urlpatterns_reverse.nested_urls')
@@ -918,17 +906,11 @@ class DefaultErrorHandlerTests(SimpleTestCase):
 
     def test_default_handler(self):
         "If the urls.py doesn't specify handlers, the defaults are used"
-        try:
-            response = self.client.get('/test/')
-            self.assertEqual(response.status_code, 404)
-        except AttributeError:
-            self.fail("Shouldn't get an AttributeError due to undefined 404 handler")
-
-        try:
-            with self.assertRaises(ValueError):
-                self.client.get('/bad_view/')
-        except AttributeError:
-            self.fail("Shouldn't get an AttributeError due to undefined 500 handler")
+        response = self.client.get('/test/')
+        self.assertEqual(response.status_code, 404)
+
+        with self.assertRaisesMessage(ValueError, "I don't think I'm getting good"):
+            self.client.get('/bad_view/')
 
 
 @override_settings(ROOT_URLCONF=None)

+ 7 - 12
tests/validation/test_unique.py

@@ -144,27 +144,22 @@ class PerformUniqueChecksTest(TestCase):
         self.assertEqual(cm.exception.message_dict, {'posted': ['This field cannot be null.']})
 
     def test_unique_for_date_with_nullable_date(self):
+        """
+        unique_for_date/year/month checks shouldn't trigger when the
+        associated DateField is None.
+        """
         FlexibleDatePost.objects.create(
             title="Django 1.0 is released", slug="Django 1.0",
             subtitle="Finally", posted=datetime.date(2008, 9, 3),
         )
         p = FlexibleDatePost(title="Django 1.0 is released")
-        try:
-            p.full_clean()
-        except ValidationError:
-            self.fail("unique_for_date checks shouldn't trigger when the associated DateField is None.")
+        p.full_clean()
 
         p = FlexibleDatePost(slug="Django 1.0")
-        try:
-            p.full_clean()
-        except ValidationError:
-            self.fail("unique_for_year checks shouldn't trigger when the associated DateField is None.")
+        p.full_clean()
 
         p = FlexibleDatePost(subtitle="Finally")
-        try:
-            p.full_clean()
-        except ValidationError:
-            self.fail("unique_for_month checks shouldn't trigger when the associated DateField is None.")
+        p.full_clean()
 
     def test_unique_errors(self):
         UniqueErrorsModel.objects.create(name='Some Name', no=10)

+ 1 - 5
tests/validators/tests.py

@@ -308,12 +308,8 @@ class TestSimpleValidators(SimpleTestCase):
         self.assertEqual(repr(v), str_prefix("ValidationError({%(_)s'first': [%(_)s'First Problem']})"))
 
     def test_regex_validator_flags(self):
-        try:
+        with self.assertRaises(TypeError):
             RegexValidator(re.compile('a'), flags=re.IGNORECASE)
-        except TypeError:
-            pass
-        else:
-            self.fail("TypeError not raised when flags and pre-compiled regex in RegexValidator")
 
     def test_max_length_validator_message(self):
         v = MaxLengthValidator(16, message='"%(value)s" has more than %(limit_value)d characters.')

+ 1 - 7
tests/view_tests/tests/test_debug.py

@@ -442,15 +442,9 @@ class ExceptionReporterTests(SimpleTestCase):
         except BrokenEvaluation:
             exc_type, exc_value, tb = sys.exc_info()
 
-        reporter = ExceptionReporter(request, exc_type, exc_value, tb)
-        try:
-            html = reporter.get_traceback_html()
-        except BrokenEvaluation:
-            self.fail("Broken evaluation in traceback is not caught.")
-
         self.assertIn(
             "BrokenEvaluation",
-            html,
+            ExceptionReporter(request, exc_type, exc_value, tb).get_traceback_html(),
             "Evaluation exception reason not mentioned in traceback"
         )