Using Python unittest, how do I create and use a “callable that returns a test case”?

I am learning Python and trying to understand more about the Python module unittest. The documentation includes the following:

For the convenience of testing, as we will see later, it is a good idea to provide a callable object in each test module that returns a pre-built test suite:

def suite():
    suite = unittest.TestSuite()
    suite.addTest(WidgetTestCase('testDefaultSize'))
    suite.addTest(WidgetTestCase('testResize'))
    return suite

As far as I can tell, the purpose of this is not explained. In addition, I could not understand how to use such a method. I tried several things without success (other than examining the error messages I received):

import unittest

def average(values):
    return sum(values) / len(values)

class MyTestCase(unittest.TestCase):
    def testFoo(self):
        self.assertEqual(average([10,100]),55)

    def testBar(self):
        self.assertEqual(average([11]),11)

    def testBaz(self):
        self.assertEqual(average([20,20]),20)

    def suite():
        suite = unittest.TestSuite()
        suite.addTest(MyTestCase('testFoo'))
        suite.addTest(MyTestCase('testBar'))
        suite.addTest(MyTestCase('testBaz'))
        return suite

if __name__ == '__main__':
    # s = MyTestCase.suite()
    # TypeError: unbound method suite() must be called 
    # with MyTestCase instance as first argument

    # s = MyTestCase.suite(MyTestCase())
    # ValueError: no such test method in <class '__main__.MyTestCase'>: runTest

    # s = MyTestCase.suite(MyTestCase('testFoo'))
    # TypeError: suite() takes no arguments (1 given)

The following "worked", but seems uncomfortable, and it was necessary to change the method signature suite()to " def suite(self):".

s = MyTestCase('testFoo').suite()
unittest.TextTestRunner().run(s)
+5
5

, , .

print MyTestCase.suite # <unbound method MyTestCase.suite>

. , , . MyTestCase.run:

print MyTestCase.run # <unbound method MyTestCase.run>

, , suite, , , . run , ? - :

MyTestCase.run() # ?

, , ? , , run - self . , Python "" suite , run, .

, :

suite , :

import unittest

def average(values):
    return sum(values) / len(values)

class MyTestCase(unittest.TestCase):
    def testFoo(self):
        self.assertEqual(average([10,100]),55)

    def testBar(self):
        self.assertEqual(average([11]),11)

    def testBaz(self):
        self.assertEqual(average([20,20]),20)

def suite():
    suite = unittest.TestSuite()
    suite.addTest(MyTestCase('testFoo'))
    suite.addTest(MyTestCase('testBar'))
    suite.addTest(MyTestCase('testBaz'))
    return suite

print suite() # <unittest.TestSuite tests=[<__main__.MyTestCase testMethod=testFoo>, <__main__.MyTestCase testMethod=testBar>, <__main__.MyTestCase testMethod=testBaz>]>

, , MyTestCase.suite()

, , , suite "" , self, ? .

Python, Python , self . self static . "" , staticmethod:

@staticmethod
def suite():
    suite = unittest.TestSuite()
    suite.addTest(MyTestCase('testFoo'))
    suite.addTest(MyTestCase('testBar'))
    suite.addTest(MyTestCase('testBaz'))
    return suite

, Python MyTestCase , :

print MyTestCase.suite # <function suite at 0x...>

, , MyTestCase.suite(), .

if __name__ == '__main__':
    s = MyTestCase.suite()
    unittest.TextTestRunner().run(s) # Ran 3 tests in 0.000s, OK
+6

, suite() , . , , :

alltests = unittest.TestSuite([
  my_module_1.suite(),
  my_module_2.suite(),
])

, , . self " " , , . (, a.b(1, 2) b(a, 1, 2).) , classmethod. , , staticmethod. unittest, , , .

+1

, nose - , . , , .

+1

, suite() , unittest ( ), , , . , " testoob, suite() ( defaultTest =" suite " ()) unittest. XML , stdout stderr ( ), HTML- ( ). , , , , .

+1

. , .

def suite():
    suite = unittest.TestLoader().loadTestsFromTestCase(Your_Test_Case_Class)
    return suite

, :

if __name__ == "__main__":
     suite()

And if you want to bundle your packages in another module, i.e. test_suite.py (for example), then this can be done as follows:

import test_module name import unittest

if __name__=="__main__":
    suite1=test_module_name.suite()
    ...
    ...
    alltests = unittest.TestSuite([suite1,suite2])

Now how to run the tests. I usually use a simpler execution method by running this command at the package level, and unittest will automatically detect the tests:

python -m unittest discover

or

nosetests 

Caution: Unittest is X times faster than nosetest, so its developer preferences, especially if they use third-party nosetest plugins and want to continue to use it.

0
source

All Articles