views:

103

answers:

2

Hi:

I am doing some unit testing stuff in Django. What is the relationship between TestCase class and the actual method in this class? What is the best practice for organizing these stuff?

For example, I have

class Test(TestCase):
    def __init__(self):
        ...
    def testTestA(self):
        #test code

    def testTestB(self):
        #test code

If I organize in this way:

class Test1(TestCase):
    def __init__(self):
        ...
    def testTestA(self):
        #test code

class Test2(TestCase):
    def __init__(self):
        ...
    def testTestB(self):
        ...

Which is better and what is the difference?

Thanks!

+1  A: 
  1. You rarely write __init__ for a TestCase. So strike that from your mental model of unit testing.

  2. You sometimes write a setUp and tearDown. Django automates much of this, however, and you often merely provide a static fixtures= variable that's used to populate the test database.

More fundamentally, what's a test case?

A test case is a "fixture" -- a configuration of a unit under test -- that you can then exercise. Ideally each TestCase has a setUp method that creates one fixture. Each method will perform a manipulation on that fixture and assert that the manipulation worked.

However. There's nothing dogmatic about that.

In many cases -- particularly when exercising Django models -- where there just aren't that many interesting manipulations.

If you don't override save in a model, you don't really need to do CRUD testing. You can (and should) trust the ORM. [If you don't trust it, then get a new framework that you do trust.]

If you have a few properties in a models class, you might not want to create a distinct method to test each property. You might want to simply test them sequentially in a single method of a single TestCase.

If, OTOH, you have really complex class with lots of state changes, you will need a distinct TestCase to configure an object is one state, manipulate it into another state and assert that the changes all behaved correctly.

View Functions, since they aren't -- technically -- stateful, don't match the Unit Test philosophy perfectly. When doing setUp to create a unit in a known state, you're using the client interface to step through some interactions to create a session in a known state. Once the session has reached as desired state, then your various test methods will exercise that session, and assert that things worked.

Summary

Think of TestCase as a "Setup" or "Context" in which tests will be run.

Think of each method as "when_X_should_Y" statement. Some folks suggest that kind of name ("test_when_x_should_y") So the method will perform "X" and assert that "Y" was the response.

S.Lott
+1  A: 

It's kind of hard to answer this question regarding the proper organization of cases A and B and test methods 1, 2 and 3...

However splitting the tests to test cases serves two major purposes: 1) Organizing the tests around some logical groups, such as CustomerViewTests, OrdersAggregationTests, etc.

2) Sharing the same setUp() and tearDown() methods, for tests which require the same, well, setup and tear down.

More information and examples can be found at unitTest documentation.

Amitay Dobo
So, technically, either way is Okey but only differs in philosophy?
sza
Either way are ok, depending on what and how you make your tests but there is an behavioral difference: the shared set up and tear down for test methods under the same TestCase class.Also, the TestCase is a class as any class, meaning you can use inheritence and shared (private) methods for test, but usually you don't want any of these complications, especially the way django test runner runs the test by default.
Amitay Dobo