对一组自动化测试只运行一次 setUp
Posted
技术标签:
【中文标题】对一组自动化测试只运行一次 setUp【英文标题】:Run setUp only once for a set of automated tests 【发布时间】:2012-12-27 16:11:47 【问题描述】:我的 Python 版本是 2.6。
我只想执行一次测试 setUp 方法,因为我在那里做了所有测试都需要的事情。
我的想法是创建一个布尔变量,在第一次执行后将其设置为“true”,然后禁用对 setup 方法的多次调用。
class mySelTest(unittest.TestCase):
setup_done = False
def setUp(self):
print str(self.setup_done)
if self.setup_done:
return
self.setup_done = True
print str(self.setup_done)
输出:
False
True
--- Test 1 ---
False
True
--- Test 2 ---
为什么这不起作用?我错过了什么吗?
【问题讨论】:
Unittest 为每个测试创建单独的实例 不要这样做。实施一些其他机制。但不要试图改变setUp
的含义。
Unittest setUp/tearDown for several tests的可能重复
【参考方案1】:
我正在使用 Python 3,发现 cls
引用也可用于 setup
方法,因此以下工作:
class TestThing(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.thing = Thing() # the `thing` is only instantiated once
def setup(self):
self.thing = TestThing.thing # ...but set on each test case instance
def test_the_thing(self):
self.assertTrue(self.thing is not None)
【讨论】:
不能在setUp中访问cls,它是一个实例方法(小写的setup()不会被调用,因为它不是unittest的setUp方法,也不是'test'开头的方法,这可能是您没有收到错误的原因)但是,一旦您在 setUpClass 中定义了类变量,您就可以在所有实例方法中简单地调用 self.thing 谢谢@khuang834。你说得对。这是我的疏忽。【参考方案2】:对于 python >3,您可以通过定义 startTestRun
,stopTestRun
的 unittest.TestResult class
来实现。回复https://***.com/a/64892396/2679740
【讨论】:
【参考方案3】:您可以使用setUpClass
定义每个测试套件只运行一次的方法。
【讨论】:
感谢您的回复。由于我使用的是 Python 2.6.6,所以 setUpClass 不可用。 @JohnM.:你可以下载 unittest2 backport 包并在旧的 python-dist 上获取所有新的东西。 该问题涉及 Python 2,但由于该答案对 Python 3 也有效,因此我更改了 URL,因为不推荐使用 Python 2。【参考方案4】:如果您因为需要加载一些数据进行测试而最终来到这里... 那么就您使用 Django 1.9+ 而言,请转到 setUpTestData:
class MyTests(TestCase):
@classmethod
def setUpTestData(cls):
# Set up data for the whole TestCase
cls.foo = Foo.objects.create(bar="Test")
def test1(self):
self.assertEqual(self.foo.bar, 'Test')
【讨论】:
【参考方案5】:Daniel's answer 是正确的,但这里有一个例子可以避免我发现的一些常见错误,例如当TestCase
是unittest.TestCase
的子类时,在setUpClass()
中不调用super()
(如django.test
或falcon.testing
)。
setUpClass()
的文档没有提到在这种情况下您需要调用 super()
。如果不这样做,您将收到错误消息,如 this related question 所示。
class SomeTest(TestCase):
def setUp(self):
self.user1 = UserProfile.objects.create_user(resource=SomeTest.the_resource)
@classmethod
def setUpClass(cls):
""" get_some_resource() is slow, to avoid calling it for each test use setUpClass()
and store the result as class variable
"""
super(SomeTest, cls).setUpClass()
cls.the_resource = get_some_resource()
【讨论】:
请注意,这仅在TestCase
是 unittest.TestCase
的子类时才相关。【参考方案6】:
setup_done 是一个类变量,而不是一个实例变量。
您将其作为实例变量引用:
self.setup_done
但是你需要将它作为类变量来引用:
mySelTest.setup_done
这是更正后的代码:
class mySelTest(unittest.TestCase):
setup_done = False
def setUp(self):
print str(mySelTest.setup_done)
if mySelTest.setup_done:
return
mySelTest.setup_done = True
print str(mySelTest.setup_done)
【讨论】:
【参考方案7】:将您想要设置的所有代码放在 mySelTest 之外。
setup_done = False
class mySelTest(unittest.TestCase):
def setUp(self):
print str(setup_done)
if setup_done:
return
setup_done = True
print str(setup_done)
另一种可能性是在setUp()
中实例化一个Singleton 类,它只会运行一次__new__
代码并为其余调用返回对象实例。
见:Is there a simple, elegant way to define singletons?
class Singleton(object):
_instance = None
def __new__(cls, *args, **kwargs):
if not cls._instance:
cls._instance = super(Singleton, cls).__new__(
cls, *args, **kwargs)
# PUT YOUR SETUP ONCE CODE HERE!
cls.setUpBool = True
return cls._instance
class mySelTest(unittest.TestCase):
def setUp(self):
# The first call initializes singleton, ever additional call returns the instantiated reference.
print(Singleton().setUpBool)
不过你的方法也行。
【讨论】:
【参考方案8】:不要尝试对 setUp 的调用进行重复数据删除,只需调用一次即可。
例如:
class MyClass(object):
...
def _set_up():
code to do one-time setup
_set_up()
这将在模块第一次加载时调用 _set_up()。我已将其定义为模块级函数,但您同样可以将其设为 MyClass 的类方法。
【讨论】:
以上是关于对一组自动化测试只运行一次 setUp的主要内容,如果未能解决你的问题,请参考以下文章