Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are unittest base classes good practice? (python/webapp2)

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!

like image 360
Quentin Donnellan Avatar asked Feb 13 '14 00:02

Quentin Donnellan


People also ask

Is Pytest better than unittest?

Which is better – pytest or unittest? Although both the frameworks are great for performing testing in python, pytest is easier to work with. The code in pytest is simple, compact, and efficient. For unittest, we will have to import modules, create a class and define the testing functions within that class.

Is PyUnit and unittest same?

PyUnit is an easy way to create unit testing programs and UnitTests with Python. (Note that docs.python.org uses the name "unittest", which is also the module name.)

What are some of the benefits of using a unit testing framework such as Python's unittest module?

Key advantages of Python unit testing are:Detecting problems early - Unit tests discloses problems early into the development. Mitigating change - Allows the developer to refactor the source code during the testing stage and later on, while still making sure the module works as expected.


2 Answers

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.

like image 107
Fred Mitchell Avatar answered Sep 26 '22 01:09

Fred Mitchell


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.

like image 30
Morten Avatar answered Sep 25 '22 01:09

Morten