ycseattle
ycseattle

Reputation: 3975

Python unittest: how to reuse the TestCase.assert functions

I am writing a subclass of unittest.TestCase to abstract some details of our code, and I want to use my own assert functions, but I need this assert result will be reported to the test result. I am trying to reuse the unittest assert functions like this:

class MyTestCase(unittest.TestCase):
    def assertState(state, value):
        if state_dict[state] == value:
            self.assertTrue(True)
        else:
            self.assertTrue(False)

The problem is that the call of the asserrState in my MyTestCase instance will report assertError instead of reporting the error the the test result object.

Please suggest how I can write my own assert functions in the subclass of unittest.TestCase.

EDIT: What I want to accomplish is to provide our own MyTestCase class as base class that include more assert functions with business logic in it. This way, the real tests can just subclass MyTestCase and use these asserts without repeating the same code. This means that I want to be able to call MyTestCase.assertState in a subclass of MyTestCase and still report the test failure to that concrete test result. Something like the following.

class ConcreteTestCase(MyTestCase):
    def test_1(self):
        #do something here
        self.assertState("state", "on")

Please let me know if there is a way to do it.

Upvotes: 1

Views: 1591

Answers (3)

ouk
ouk

Reputation: 405

Very late reply, but finally a solution as I ran into the same issue when defining my own TestCase subclass. It may be helpful for other people looking for the same thing.

You simply need to add __unittest = True in the module where the class is defined.

import unittest

__unittest = True

class MyTestCase(unittest.TestCase):
    def assertState(state, value):
        if state_dict[state] != value:
            standardMsg = 'the state %s does not match %s' % (state, value)
            self.fail(self._formatMessage(msg, standardMsg))

Now your user-defined assert method will behave exactly like the unittest.TestCase ones, and won't show the unwanted stack trace upon failure.

Works on Python 2.7

Source: http://www.gossamer-threads.com/lists/python/python/1014779

Upvotes: 2

Fred Nurk
Fred Nurk

Reputation: 14212

class MyTestCase(unittest.TestCase):
  def assertState(self, state, value):
    self.assertEqual(value, self.state_dict[state])

  def test_whatever(self):
    self.assertState(1, 1)
    self.assertState(2, 2)

Upvotes: 2

thule
thule

Reputation: 4232

First of all, you forgot the self parameter. Secondly, how are you running it? If you really want the test result object, that is how you do it:

In [1]: import unittest

In [2]: state_dict = {1:2}

In [3]: class MyTestCase(unittest.TestCase):
   ...:         def assertState(self, state, value):
   ...:             if state_dict[state] == value:
   ...:                 self.assertTrue(True)
   ...:         else:
   ...:                 self.assertTrue(False)
   ...:     def runTest(self):
   ...:         self.assertState(1,2)
   ...:         self.assertState(1,1)
   ...: 

In [4]: r = unittest.TestResult()

In [5]: MyTestCase().run(r)

In [6]: r
Out[6]: <unittest.TestResult run=1 errors=0 failures=1>

In [7]: r.errors
Out[7]: []

In [8]: r.failures
Out[8]: 
[(<__main__.MyTestCase testMethod=runTest>,
  'Traceback (most recent call last):\n  File "<ipython console>", line 9, in runTest\n  File "<ipython console>", line 6, in assertState\nAssertionError\n')]

Upvotes: 1

Related Questions