【问题标题】:Can I have an abstract base class for my tornado.testing.AsyncTestCase tests?我可以为我的 tornado.testing.AsyncTestCase 测试提供一个抽象基类吗?
【发布时间】:2020-01-22 15:09:23
【问题描述】:

是否有可能在 tornado 中定义测试的基类本身不作为测试运行?

假设我有以下最小示例作为基类:

from tornado.testing import AsyncTestCase, gen_test
from tornado.httpclient import HTTPRequest

class AbstractTestCase(AsyncTestCase):
    def set_parameters(self):
        #Set some parameter value here: self.uri = ...
        raise NotImplementedError

    @gen_test
    def test_common_functionality(self):
        req = HTTPRequest(self.uri, method = "GET")
        response = yield self.client.fetch(req, raise_error=False)
        self.assertEqual(200, response.code)

现在,我想创建几个继承自 this 的测试用例,为 self.uri 定义它们自己的值...并有一些自己的特定测试。像这样:

class ConcreteTestCase(AbstractTestCase):
    def set_parameters(self):
        self.uri = "www.stackoverflow.com"

    @gen_test
    def test_some_other_thing(self):
        self.assertEqual(2, 1+1)

但是,当我尝试运行它时,AbstractTestCase 也会自行运行,并给出错误(NotImplementedError)。即使我只尝试运行继承测试也会发生这种情况。

有什么办法可以解决这个问题,还是我必须在每个测试用例中复制功能?

【问题讨论】:

    标签: python unit-testing testing tornado


    【解决方案1】:

    一种方法是使用多重继承。只要该类在运行时处于继承层次结构中,抽象类就不需要扩展 AsyncTestCase。

    class AbstractTestCase(object):
        def set_parameters(self):
            #Set some parameter value here: self.uri = ...
            raise NotImplementedError
    
        @gen_test
        def test_common_functionality(self):
            req = HTTPRequest(self.uri, method = "GET")
            response = yield self.client.fetch(req, raise_error=False)
            self.assertEqual(200, response.code)
    
    class ConcreteTestCase(AbstractTestCase, AsyncTestCase):
        def set_parameters(self):
            self.uri = "www.stackoverflow.com"
    
        @gen_test
        def test_some_other_thing(self):
            self.assertEqual(2, 1+1)
    

    这确实有点奇怪,mypy 类型检查不喜欢它。但它很简单而且很有效,而且我还没有找到我喜欢的mypy-friendly 替代方案。

    【讨论】:

    • 谢谢,这似乎最有效。我不得不用常规断言替换 self.assertEqual(...) ,但它完成了工作。
    • 虽然进一步说明,不能使用 assertEqual 之类的东西有点烦人......
    • self.assertEqual 在这里工作,这要归功于动态类型。看起来 AbstractTestCase 没有这个方法,但是当最终类被实例化时,方法就在那里。
    • 你当然是对的。我只是看着我的编辑抱怨,并没有进一步思考。
    【解决方案2】:

    命令行

    python3 -m tornado.testing ConcreteTestCase.ConcreteTestCase
    

    testmain.py

    #!/usr/bin/env python3
    import unittest
    from tornado.testing import main
    
    
    def all():
        cases = ['ConcreteTestCase.ConcreteTestCase']
        return unittest.defaultTestLoader.loadTestsFromNames(cases)
    
    main()
    
    

    test/runtests.py 就是一个很好的例子。

    【讨论】:

    • 这对我不起作用,它仍然尝试运行抽象测试用例并获得 NotImplementedError
    • @andresti 你只需要运行你想要的测试?如果是这样,在类名之后附加方法名,就像这样python3 -m tornado.testing ConcreteTestCase.ConcreteTestCase.test_some_other_thing
    • 这确实有效。但我真正想要的是运行我拥有的所有测试,而不是一个接一个地运行。
    猜你喜欢
    • 1970-01-01
    • 2012-04-03
    • 2020-11-21
    • 1970-01-01
    • 1970-01-01
    • 2018-12-06
    • 1970-01-01
    • 2020-10-28
    相关资源
    最近更新 更多