

Unit testing in Django? - chrisallen

I've been attempting to discipline myself into making more extensive use of testing in general, but of late, in Django.<p>There are parts of the project I'm working on that need refactored and writing tests that have good coverage of the various function points is going to put me in a better position to be able to refactor confidently. For reasons that should be obvious, I've begun implementing unit tests in the "account" app within the project.<p>I've managed to break the account registration and transaction process into three unit tests so far, but one of the tests seems a bit too big/fat, and it's a little bit repetitious. The reason for this is that the transaction is stateful and I cannot rely on globals for unit tests. (Test order not guaranteed, cannot use that.)<p>So that would be my first question, how do I cope with a stateful transaction in terms of breaking it down more? Just deal with the fact that I'm repeatedly retrieving and validating the same data cross more than one test, or is there a better way?<p>More importantly, are there any books/materials/tutorials that take a pragmatic viewpoint on unit testing in development (ie, not rigidly 'test first') that you  would recommend?<p>Test-first methodology isn't really an option aesthetically and practically because I'm coming into an ongoing project and the culture/practice wasn't there for it. I'm the first one to start making use of tests.<p>Thanks.
======
jgeewax
You could also break each test into a separate TestCase where each case uses
the setUp() and tearDown() methods to do the repetitive stuff.

On a slightly different note, perhaps the layout of the test looks off because
you're testing too much. It's difficult to comment too much without code, but
you might want to consider assuming that certain things "just work" when using
them in more complex tests.

That is, if a User depends on an Account being created, create the account and
just assume that everything went fine. If that happens to fail, another test
elsewhere should fail also which will be more helpful when debugging.

PG's most recent essay said it nicely: every line of code is a liability, even
tests. The more you repeat yourself (testing things were created correctly
that are tested elsewhere) the more code you then need to maintain and update
should the requirements ever change.

~~~
chrisallen
The technical debt is ever-present to my mind, but this is a registration page
that involves a credit card transaction and represents direct revenue to my
company.

 _It_ at least has to be tested thoroughly. The rest of the apps in the
project are less important that in that respect (used internally, primarily).

------
dnsauve
One way I've always dealt with the repetitive bits in my tests is to break out
the offending code into separate utility type methods that can then be called
by the test itself (or even multiple tests) as needed.

These methods could themselves also contain assertThis, assertThat, as needed
to ensure they're functioning as expected as well.

Another way I've done it is to have tests calling other test methods
themselves. i.e., something like:

    
    
        testFoo(self):
           # Do some test here.
           self.assertTrue(....)
    
        testBar(self):
           # Test that Foo works for logged in user as well
           self.client.login(username='joe', password='abc')
           self.testFoo()
           self.assertTrue(...)

~~~
chrisallen
I think at least one or a combination of these methods will resolve my qualms
with how it's arranged right now. Thank you very much.

Edit: It is worth noting that I'm trying to keep the unit tests independent,
however.

