Giving parameters into TestCase from Suite in python

匿名 (未验证) 提交于 2019-12-03 01:29:01

问题:

From python documentation(http://docs.python.org/library/unittest.html):

import unittest  class WidgetTestCase(unittest.TestCase):     def setUp(self):         self.widget = Widget('The widget')      def tearDown(self):         self.widget.dispose()         self.widget = None      def test_default_size(self):         self.assertEqual(self.widget.size(), (50,50),                          'incorrect default size')      def test_resize(self):         self.widget.resize(100,150)         self.assertEqual(self.widget.size(), (100,150),                          'wrong size after resize')

Here is, how invoke those testcase:

def suite():     suite = unittest.TestSuite()     suite.addTest(WidgetTestCase('test_default_size'))     suite.addTest(WidgetTestCase('test_resize'))     return suite

Is it possible to insert parameter custom_parameter into WidgetTestCase like:

class WidgetTestCase(unittest.TestCase):     def setUp(self,custom_parameter):         self.widget = Widget('The widget')         self.custom_parameter=custom_parameter

?

回答1:

What I've done is in test_suite module just added

WidgetTestCase.CustomParameter="some_address"

The simplest solutions are the best :)



回答2:

I've found a way to do this, but it's a bit of a cludge.

Basically, what I do is add, to the TestCase, an __init__ method which defines a 'default' parameter and a __str__ so that we can distinguish cases:

class WidgetTestCase(unittest.TestCase):      def __init__(self, methodName='runTest'):         self.parameter = default_parameter         unittest.TestCase.__init__(self, methodName)      def __str__(self):         ''' Override this so that we know which instance it is '''         return "%s(%s) (%s)" % (self._testMethodName, self.currentTest, unittest._strclass(self.__class__))

Then in suite(), I iterate over my test parameters, replacing the default parameter with one specific to each test:

def suite():     suite = unittest.TestSuite()      for test_parameter in test_parameters:         loadedtests = unittest.TestLoader().loadTestsFromTestCase(WidgetTestCase)         for t in loadedtests:             t.parameter = test_parameter         suite.addTests(loadedtests)      suite.addTests(unittest.TestLoader().loadTestsFromTestCase(OtherWidgetTestCases))     return suite

where OtherWidgetTestCases are tests which don't need to be parameterised.

For instance I have a bunch of tests on real data for which a suite of tests need to be applied to each, but I also have some synthetic data sets, designed to test certain edge cases not normally present in the data, and I only need to apply certain tests to those, so they get their own tests in OtherWidgetTestCases.



回答3:

This is something that has been on my mind recently. Yes it is very possible to do. I called it scenario testing, but I think parameterized may be more accurate. I put a proof of concept up as a gist here. In short it is a meta class that allows you to define a scenario and run the tests against it a bunch. With it your example can be something like this:

class WidgetTestCase(unittest.TestCase):     __metaclass__ = ScenarioMeta     class widget_width(ScenerioTest):         scenarios = [             dict(widget_in=Widget("One Way"), expected_tuple=(50, 50)),             dict(widget_in=Widget("Another Way"), expected_tuple=(100, 150))         ]         def __test__(self, widget_in, expected_tuple):             self.assertEqual(widget_in.size, expected_tuple)

When run, the meta class writes 2 seperate tests out so the output would be something like:

$ python mysc  
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!