Package: django-instant-coverage
Instant CoverageYour new Django site need tests. Nothing super fancy, just enough that you know
you’ve not forgotten to close some <div> somewhere and it’s not going to start
500ing next time you deploy. Youcouldwrite unit tests, but those are boring
and your client sure as hell isn’t going to pay for the time.You’ve got five minutes, though.FeaturesSimpleIterates through a list of URLs and complains if any of them 500.MagicWill loudly complain when there are views missing from the list of URLs to
test.Has what you needComes withoptional mixinsfor checking links and validating HTML, JSON,
your spelling, or WCAG compliance.ExtensibleEasily add tests that will run against every view on your website. If you
want tests for things like consistent capitalisation of a particular phrase
or the universal inclusion of a particular meta tag, you can have them in
minutes.PortableCompatible with (andtestedagainst) Django versions 1.5 to 4.2, and
Python versions from 2.7 to 3.11.ChangesChanges made in each release are listed intagsin this repository.UsageInstallpip installdjango-instant-coverage‘Write’ your testsYou’ll want a tests module somewhere. I keep mine in myPROJECT_DIR,
because it’s testing the whole site and not just one app. Wherever you put it,
it should be named such that your test runner will find it (tests.pyusually works well) and should contain at least the following:fromdjango.testimportTestCasefrominstant_coverageimportInstantCoverageMixinclassEverythingTest(InstantCoverageMixin,TestCase):passWith that in place, you should be able to run your tests withpython manage.py test. They’ll fail, though. You’ll get a list of URLs you’ve not
told it to test, looking something like this:AssertionError: The following views are untested:

('^',) ^$ (index)
('^admin/',) ^$ (index)
('^admin/',) ^logout/$ (logout)
('^admin/',) ^password_change/$ (password_change)
[...]It’ll probably contain a bunch of URLs you don’t want to test, though, like
those from the Django admin app. To quickly exclude entire URL includes, add
tuples like the ones shown in the failure you just got to your test’suncovered_includesattribute:classEverythingTest(InstantCoverageMixin,TestCase):uncovered_includes=[('^admin/',),]Add paths matching the URLs that youdoactually want to test tocovered_urls, and add paths that match those youdon’ttouncovered_urls. If you forget what’s still missing, run the tests again to
get an audit of what’s left.classEverythingTest(InstantCoverageMixin,TestCase):covered_urls=['/','/api/','/0007C3F2760E0541/',]uncovered_urls=[# requires stuff to be in the session'/upload/confirm/','/shortlist-selection/',# only accepts POST'/shortlist-order/',# probably tested pretty thoroughly by the django project'/media/woof.jpg',]If you want to usereverse()rather than hard-code URLs or if you want to
test more than one path for a given URL, that is fully supported.Encouraged,
even. It doesn’t matter how you build it, as long ascovered_urlsis a
list.If you have views that you can’t test without data present in the database,make a fixtures fileandadd it to your test class, or create them
programmatically insetUp()orsetUpTestData()on the test class.Use the provided optional test mixinsBy default, Instant Coverage will make sure none of your views raise unhandled
exceptions and all of them return status codes between 200 and 399. There’s a
good chance at least some of the providedoptional mixinswill be
appropriate for your website, so be sure to have a look through them and see
what strikes your fancy. Use them like this:frominstant_coverageimportInstantCoverageMixin,optionalclassEverythingTest(optional.Spelling,optional.ExternalLinks,optional.ValidHTML5,InstantCoverageMixin,TestCase):# covered_urls, etc...Write your own testsInstantCoverageMixinprovides aninstant_responsesmethod that returns
a dictionary ofDjango test clientResponseobjectskeyed by URL. Test methods you write should
iterate across that. Have a look at theoptional mixinsfor some examples.If you make any that you think might be useful to any other websites, even if a
minority, a pull request would be very much appreciated.Test under different circumstancesIf you want to test all the URLs you’ve listed under different circumstances
(for instance, when a user is logged in or when a different language has been
selected), create a subclass of your tests and overridesetUp(). For
instance, you might put the following below yourEverythingTest:fromdjango.contrib.authimportget_user_modelclassLoggedInEverythingTest(EverythingTest):defsetUp(self):super(LoggedInEverythingTest,self).setUp()user=get_user_model()(username='user',is_staff=True,is_superuser=True,)user.set_password('pass')user.save()self.assertTrue(self.client.login(username='user',password='pass'))Be aware that, by default, the test client will follow redirects. If you do not
want this, set thefollow_redirectsattribute of your tests toFalse.
If you have more specific requirements, you may have to override theget_client_kwargsorattempt_to_get_internal_urlmethods of your test.If you have a bunch of test classes that test the same collection of URLs, you
may want to consider inheriting fromInstantCoverageAPIinstead ofInstantCoverageMixin; the former will not run any tests that you don’t
explicitly add yourself.