如何在使用unittest时自由组合多个setUp()/ tearDown()基类?

时间:2018-02-14 14:50:55

标签: python python-unittest

有各种设置:创建应用驱动程序,创建虚拟设备,进行登录。

有些测试用例只需要应用程序驱动程序,有些需要应用程序驱动程序和登录,有些需要应用程序驱动程序和设备,有些则使用全部三种。

如何制作类似#include <iostream> // The unittest.TestCase. struct TestCase { virtual void setUp() {} virtual void tearDown() {} }; template <typename ...Ts> struct Combine: public TestCase, public Ts... { virtual void setUp() override { int t[] = { 0, (Ts::setUp(), 1)... }; } // TODO: invert the order virtual void tearDown() override { int t[] = { 0, (Ts::tearDown(), 1)... }; } }; // Setups for 'login' only. struct Login { void setUp() { std::cout << "Login setup" << std::endl; } void tearDown() { std::cout << "Login teardown" << std::endl; } }; // Setups for 'device' only. struct Device { void setUp() { std::cout << "Device setup" << std::endl; } void tearDown() { std::cout << "Device teardown" << std::endl; } }; // A concrete test case. struct MyTest: public Combine<Login, Device> { void test() { std::cout << "test" << std::endl; } }; int main() { MyTest cd; cd.setUp(); cd.test(); cd.tearDown(); Combine<Device> d; d.setUp(); d.tearDown(); return 0; } 模板的内容:

Login setup
Device setup
test
Login teardown
Device teardown
Device setup
Device teardown

输出:

- segment_times times 
  Specify a list of split points. times contains
  a list of comma separated duration specifications,
  in increasing order. See also the segment_time option.

1 个答案:

答案 0 :(得分:2)

使用mixins,多重继承和super()调用:

import unittest

class MixinBase(object):
    def setUp(self):
        pass

    def tearDown(self):
        pass


class LoginMixin(MixinBase):
    def setUp(self):
        print("LoginMixin.setUp()")
        self.login = "login"
        super(LoginMixin, self).setUp()

    def tearDown(self):
        super(LoginMixin, self).tearDown()
        print("LoginMixin.tearDown()")
        del self.login


class DeviceMixin(MixinBase):
    def setUp(self):
        print("DeviceMixin.setUp()")
        self.device = "device"
        super(DeviceMixin, self).setUp()

    def tearDown(self):
        super(DeviceMixin, self).tearDown()
        print("DeviceMixin.tearDown()")
        del self.device



class TestThatOnlyNeedsLogin(LoginMixin, unittest.TestCase):
    def test_something(self):
        self.assertEqual(self.login, "login")


class TestThatNeedsLoginAndDevice(LoginMixin, DeviceMixin, unittest.TestCase):
    def test_something(self):
        self.assertEqual(self.login, "login")
        self.assertEqual(self.device, "device")

# XXX actually useless (multiple inheritance works fine)
# but since you asked for it
def combinemixins(cls, *otherbases):
    bases = (cls,)  + otherbases
    Combined = type.__new__(type, "Combined", bases, {})
    return Combined

LoginAndDevice = combinemixins(LoginMixin, DeviceMixin)

class TestWithCombined(LoginAndDevice, unittest.TestCase):
    def test_something(self):
        self.assertEqual(self.login, "login")
        self.assertEqual(self.device, "device")


if __name__ == "__main__":
    unittest.main()