Better-than-nothing testing for Django
Project description
![A roll of duct tape; the Instant Coverage logo][logo]
[logo]: http://colons.co/instant-coverage-small.png
[![Build Status][travis-status]][travis]
[travis-status]: https://travis-ci.org/colons/instant-coverage.png
# Instant Coverage
Your 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. You *could* write 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.
## Features
- **Simple**
- Iterates through a list of URLs and complains if any of them 500.
- **Magic**
- Will loudly complain when there are views missing from the list of URLs
to test.
- **Has what you need**
- Comes with [optional test mixins][optional] for checking links and
validating HTML, JSON or your spelling.
- **Extensible**
- Easily 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.
- **Portable**
- [Tested][travis] on Python 2.7 and 3.3 and Django 1.4, 1.5 and 1.6.
# Usage
## Install
`pip install django-instant-coverage`
## ‘Write’ your tests
You'll want a tests module somewhere. I keep mine in my `PROJECT_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.py` usually
works well) and should contain at least the following:
```python
from django.test import TestCase
from instant_coverage import InstantCoverageMixin
class EverythingTest(InstantCoverageMixin, TestCase):
pass
```
With that in place, you should be able to run your tests with `python 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's
`uncovered_includes` attribute:
```python
class EverythingTest(InstantCoverageMixin, TestCase):
uncovered_includes = [
('^admin/',),
]
```
Add URLs that you *do* actually want to test to `covered_urls`, and add those
you *don't* to `uncovered_urls`. If you forget what's still missing, run the
tests again to get an audit of what's left.
```python
class EverythingTest(InstantCoverageMixin, TestCase):
covered_urls = [
'/',
'/api/',
'/0007C3F2760E0541/',
]
uncovered_urls = [
# requires stuff to be in the session
'/upload/confirm/',
'/shortlist-selection/',
# only accepts POST
'/shortlist-order/',
]
```
If you have views that you can't test without data present in the database,
[make a fixtures file][dumpdata] and [add it to your test class][fixtures].
[dumpdata]: https://docs.djangoproject.com/en/dev/ref/django-admin/#dumpdata-app-label-app-label-app-label-model
[fixtures]: https://docs.djangoproject.com/en/dev/topics/testing/tools/#django.test.TransactionTestCase.fixtures
## Use the provided optional test mixins
By 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 provided [optional mixins][optional] will be
appropriate for your website, so be sure to have a look through them and see
what strikes your fancy. Use them like this:
```python
from instant_coverage import InstantCoverageMixin, optional
class EverythingTest(
optional.Spelling, optional.ExternalLinks, optional.ValidHTML5,
InstantCoverageMixin, TestCase
):
# covered_urls, etc...
```
## Write your own tests
`InstantCoverageMixin` provides an `instant_responses` method that returns a
dictionary of responses keyed by URL. Test methods you write should iterate
across that. Have a look at [the optional mixins][optional] for 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 circumstances
If 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 override `setUp()`. For
instance, you might put the following below your `EverythingTest`:
```python
from django.contrib.auth import get_user_model
class LoggedInEverythingTest(EverythingTest):
def setUp(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'))
```
[travis]: https://travis-ci.org/colons/instant-coverage
[optional]: https://github.com/colons/instant-coverage/blob/master/instant_coverage/optional.py
[logo]: http://colons.co/instant-coverage-small.png
[![Build Status][travis-status]][travis]
[travis-status]: https://travis-ci.org/colons/instant-coverage.png
# Instant Coverage
Your 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. You *could* write 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.
## Features
- **Simple**
- Iterates through a list of URLs and complains if any of them 500.
- **Magic**
- Will loudly complain when there are views missing from the list of URLs
to test.
- **Has what you need**
- Comes with [optional test mixins][optional] for checking links and
validating HTML, JSON or your spelling.
- **Extensible**
- Easily 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.
- **Portable**
- [Tested][travis] on Python 2.7 and 3.3 and Django 1.4, 1.5 and 1.6.
# Usage
## Install
`pip install django-instant-coverage`
## ‘Write’ your tests
You'll want a tests module somewhere. I keep mine in my `PROJECT_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.py` usually
works well) and should contain at least the following:
```python
from django.test import TestCase
from instant_coverage import InstantCoverageMixin
class EverythingTest(InstantCoverageMixin, TestCase):
pass
```
With that in place, you should be able to run your tests with `python 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's
`uncovered_includes` attribute:
```python
class EverythingTest(InstantCoverageMixin, TestCase):
uncovered_includes = [
('^admin/',),
]
```
Add URLs that you *do* actually want to test to `covered_urls`, and add those
you *don't* to `uncovered_urls`. If you forget what's still missing, run the
tests again to get an audit of what's left.
```python
class EverythingTest(InstantCoverageMixin, TestCase):
covered_urls = [
'/',
'/api/',
'/0007C3F2760E0541/',
]
uncovered_urls = [
# requires stuff to be in the session
'/upload/confirm/',
'/shortlist-selection/',
# only accepts POST
'/shortlist-order/',
]
```
If you have views that you can't test without data present in the database,
[make a fixtures file][dumpdata] and [add it to your test class][fixtures].
[dumpdata]: https://docs.djangoproject.com/en/dev/ref/django-admin/#dumpdata-app-label-app-label-app-label-model
[fixtures]: https://docs.djangoproject.com/en/dev/topics/testing/tools/#django.test.TransactionTestCase.fixtures
## Use the provided optional test mixins
By 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 provided [optional mixins][optional] will be
appropriate for your website, so be sure to have a look through them and see
what strikes your fancy. Use them like this:
```python
from instant_coverage import InstantCoverageMixin, optional
class EverythingTest(
optional.Spelling, optional.ExternalLinks, optional.ValidHTML5,
InstantCoverageMixin, TestCase
):
# covered_urls, etc...
```
## Write your own tests
`InstantCoverageMixin` provides an `instant_responses` method that returns a
dictionary of responses keyed by URL. Test methods you write should iterate
across that. Have a look at [the optional mixins][optional] for 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 circumstances
If 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 override `setUp()`. For
instance, you might put the following below your `EverythingTest`:
```python
from django.contrib.auth import get_user_model
class LoggedInEverythingTest(EverythingTest):
def setUp(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'))
```
[travis]: https://travis-ci.org/colons/instant-coverage
[optional]: https://github.com/colons/instant-coverage/blob/master/instant_coverage/optional.py
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Close
Hashes for django-instant-coverage-0.0.8.tar.gz
Algorithm | Hash digest | |
---|---|---|
SHA256 | 2354b6fec9bccdee5599df3eb4d778d4fc6e09bf5c177b232da5bc2411e23211 |
|
MD5 | 8feafb01690d575b1c5a601ab41f30d8 |
|
BLAKE2b-256 | 0af64cde65b7f7508bad8d6b34b268741beaffe8379e2abf54d24bd231da1133 |