Python:对包含基类的项目进行 Nose 测试

标签 python inheritance transition nose

我创建了一个包,其中包含一个基类, future 的项目将从该基类继承。我正在尝试自动化测试,并转向 Nose 测试。

我是 Python 新手,所以如果我的问题是微不足道的/初级的,我深表歉意。

该项目利用流行的 Python 有限状态机包 transitions ,我的基类继承 State (如我的 states.py 中所示)。

base_tester/ 中运行 $nosetests 时,我收到 3 个重复错误(为简洁起见,仅粘贴了 1 个):

E.EE.
======================================================================
ERROR: Failure: TypeError (__init__() missing 1 required positional argument: 'name')
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/user/.pyenv/versions/3.7.1/lib/python3.7/site-packages/nose/failure.py", line 39, in runTest
    raise self.exc_val.with_traceback(self.tb)
  File "/home/user/.pyenv/versions/3.7.1/lib/python3.7/site-packages/nose/loader.py", line 523, in makeTest
    return self._makeTest(obj, parent)
  File "/home/user/.pyenv/versions/3.7.1/lib/python3.7/site-packages/nose/loader.py", line 582, in _makeTest
    return MethodTestCase(obj)
  File "/home/user/.pyenv/versions/3.7.1/lib/python3.7/site-packages/nose/case.py", line 346, in __init__
    self.inst = self.cls()
  File "/home/user/repos/openrov/production/testers/base_tester/base_tester/states.py", line 6, in __init__
    super().__init__(*args, **kwargs)
TypeError: __init__() missing 1 required positional argument: 'name'

但是,当我创建一个小型测试项目并实现一个继承类时,它会按预期工作。我相信我在 test.py 中所做的事情有问题,但无法弄清楚是什么。

谢谢!

项目结构:

base_tester/
├── base_tester/
│   ├── __init__.py
│   └── states.py
├── setup.py
└── test/
    ├── __init__.py
    └── test.py

状态.py:

from transitions import State

# Parent class
class TestParent(State):    
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

    # To be implemented by inheriting classes
    def run_test(self):
        raise NotImplementedError()

base_tester/init.py:

from base_tester.states import *

测试/test.py:

import unittest
from base_tester import TestParent

class Test1(TestParent):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

    def run_test(self):
        pass

class Tester(unittest.TestCase):
    test1 = Test1(name='test1')

    def test_1(self):
        self.assertTrue(True)

    def main(self):
        pass

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

最佳答案

问题在于 TestParentTest1 中方法的命名。更具体地说,是 Test1/TestParent.run_test 导致了问题。我假设 Nose 认为这些方法是孤立的测试。结果,它尝试创建相关类的实例,但由于 TestParentTest1State 没有默认的 名称而失败.

请参阅docs about finding tests 。其中提到:

If it looks like a test, it’s a test. Names of directories, modules, classes and functions are compared against the testMatch regular expression, and those that match are considered tests. Any class that is a unittest.TestCase subclass is also collected, so long as it is inside of a module that looks like a test.

这也是您多次收到错误消息的原因。您的输出表明您(尝试)运行五个测试,其中三个失败。 我只通过了 4 次测试,但还有 3 次失败。为了更好地说明这一发现,我向 TestParent 添加了默认的 name 并让 TestParent.run_test 通过。如果我现在执行nosetests -v,我会得到以下输出:

base_tester.TestParent.run_test ... ok
test.test.Test1.run_test ... ok
test.test.TestParent.run_test ... ok
test_1 (test.test.Tester) ... ok

TestParent.run_test 由于导入而执行了两次。一个简单的解决方案是避免方法名称与测试模式正则表达式(提到 in the docs )匹配,默认情况下为 (?:\b|_)[Tt]est。然而,有时由于语义原因,方法名称中包含 test 是不可避免的。

测试发现提到以下内容:

If an object defines a __test__ attribute that does not evaluate to True, that object will not be collected, nor will any objects it contains.

在您的情况下,将 __test__ = False 添加到 TestParent 也应该可以解决问题:

# Parent class
class TestParent(State):
    __test__ = False  # avoid nosetests test discover

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

    # To be implemented by inheriting classes
    def run_test(self):
        raise NotImplementedError()

关于Python:对包含基类的项目进行 Nose 测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53636877/

相关文章:

html - 背景图像悬停 CSS 问题

python - 通过 Slack API 将文件发布到聊天

python - 如何有效地掩盖pygame中的表面

c++ - 死亡钻石和作用域解析运算符 (c++)

html - 背景图像过渡不适用于表单按钮

javascript - 添加 css 过渡时间以使用 javascript 切换类

c# - IronPython 在线程中使用 numpy 时抛出 InsufficientMemoryException

python - Python 是否需要深入了解继承链中的所有类?

go - 如何在golang中结合接口(interface)和结构?

c++ - 为什么基类指针指向基类中的纯虚方法而不是派生类中的重写方法?