質問

I'm rather new to unit-testing and am trying to feel out the best practices for the thing. I've seen several questions on here relating to unit-test inheriting a base class that itself contains several tests, for example:

class TestBase(unittest.TestCase):
    # some standard tests

class AnotherTest(TestBase):
    # run some more tests in addition to the standard tests

I think what I've gathered from the community is that it's a better idea to write separate tests for each implementation and use multiple inheritance. But what if that base class actually doesn't contain any tests - just helpers for all your other tests. For example, let's say I've got some base test class which I've used to store some common methods that most if not all of my other tests will use. Let's also assume that I've got a database model in models.py called ContentModel

test_base.py

import webtest
from google.appengine.ext import testbed
from models import ContentModel

class TestBase(unittest.TestCase):

    def setUp(self):
        self.ContentModel = ContentModel
        self.testbed = testbed.Testbed()
        self.testbed.activate()
        # other useful stuff

    def tearDown(self):
        self.testbed.deactivate()

    def createUser(self, admin=False):
        # create a user that may or may not be an admin

    # possibly other useful things

It seems this would save me tons of time on all other tests:

another_test.py

from test_base import TestBase

class AnotherTest(TestBase):
    def test_something_authorized(self):
        self.createUser(admin=True)
        # run a test

    def test_something_unauthorized(self):
        self.createUser(admin=False)
        # run a test

    def test_some_interaction_with_the_content_model(self):
        new_instance = self.ContentModel('foo' = 'bar').put()
        # run a test

Note: this is based on some of my work in webapp2 on google app engine, but I expect that an analogous situation arises for pretty much any python web application

My Question

Is it good practice to use a base/helper class that contains useful methods/variables which all your other tests inherit, or should each test class be "self contained"?

Thanks!

役に立ちましたか?

解決

Superb question. I think that almost anything you do that automates testing is excellent. That said, the tests really serve as the only reliable source of documentation. So the tests should be very easy to read and comprehend. The tests are reliable, unlike comments, because they show what the software really does and how to use it.

I like this approach. But you might also try out nose. Nose is a bit "lighter weight" to set up, and is well supported if you go the continuous integration route with something like Jenkins for automated build/test/deployment. Nose does not format its messages quite as nicely as the xUnit style (IMO, of course). But for many things, you might be willing to give that up.

BTW. Python is not Java. So it is perfectly acceptable to reuse just a plain old python function for re-use.

他のヒント

A base class is a good option for some uses - as long as you don't test anything in the base class. I use base classes all the time.

Also, think of the value of seeing the code in your test class. A good example is a base class I use all the time (in c#.NET): I use a SDK - ArcObjects from Esri - that requires a license. In normal execution this is handled elsewhere, but in testing, I have to check out (or activate) a license before I can use the objects in the library. This has absolutely nothing to do with the functionality of the code I am testing in the test class, but is required to make the tests run. Thus, I decided to tuck this functionality away in a base class that check s out a license before a test and checks it back in after. Tests that requires a licence are simply inherriting from this base class.

Finally, be very careful about where you setup and tear down the prerequisites for the test. It can get messy if some is done in the base class and others are done in the child class.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top