【问题标题】:Is it possible to run a single test method from a python unittest.TestCase with a reference to the method?是否可以从 python unittest.TestCase 运行单个测试方法并引用该方法?
【发布时间】:2018-03-13 20:39:49
【问题描述】:

假设我有以下TestCase

class TestSomething(unittest.TestCase):
    def test_a(self):
        # Do some testing

    def test_b(self):
        # Do some other testing

如果我参考了那个测试,我可以运行TestSomething.test_a 吗?我想做的是:

def run_test(test):
    # Somehow runs the test
    # HERE IS THE PART I AM REALLY STUCK ON

run_test(TestSomething.test_a)

我知道对于正常的单元测试来说这是一件很尴尬的事情。我想要做的是提供一个测试作为函数装饰器的参数运行。本质上:

@corresponding_test(TestSomething.test_a)
def my_function_a():
    # Something here

然后在装饰器中基本上检查该函数的测试是否通过,然后再运行该函数。

【问题讨论】:

  • 这不是单元测试。在每个方法中运行你的逻辑,这是最合理的。
  • 我正在做的事情比这里写的更复杂,需要我问的内容,你知道问题的答案吗?

标签: python unit-testing automated-tests decorator python-unittest


【解决方案1】:

OP 明确指出现实世界的用例涉及更多,但这仍然需要说明:

免责声明:不是运行单元测试的良好标准方式。如果您使用此代码运行单元测试,那么您 [可能] 做错了。

也就是说,你的问题引起了我的兴趣,所以我继续为你写了一个工作演示:

"""
The `only_if_test_passes` decorator can be used to run a function if and
only if the argument test (unbound `TestCase` method) passes.
"""

import inspect
from unittest import TestCase, TestResult


class TestError(Exception):
    pass


class MyTests(TestCase):

    def test_pass(self):
        # This passes because nothing went wrong
        pass

    def test_fail(self):
        self.fail('This test will always fail')


def only_if_test_passes(test_method):
    # Comments are computed values when passed MyTests.test_pass
    test_case_class = inspect._findclass(test_method)  # MyTests
    test_case_name = test_case_class.__name__  # 'MyTests'
    test_name = test_method.__name__  # 'test_pass'
    # Introspection for Python 2:
    # test_case_class = test_method.im_class
    # test_case_name = test_case_class.__name__  # Same as for Python 3
    # test_name = test_method.if_func.func_name

    def decorator(fn):
        def decorated(*args, **kwargs):
            test_result = TestResult()
            case = test_case_class(test_name)  # MyTests('test_pass')
            case(test_result)
            if test_result.wasSuccessful():
                return fn(*args, **kwargs)
            else:
                raise TestError('Unit test failed: {}.{}'.format(
                    test_case_name, test_name))
        return decorated
    return decorator


@only_if_test_passes(MyTests.test_pass)
def this_will_run():
    print('This should output')


@only_if_test_passes(MyTests.test_fail)
def this_wont_ever_run():
    print("Don't bother; you'll never see this.")


if __name__ == "__main__":
    this_will_run()
    this_wont_ever_run()

gist

自省在 Python 2 中会有所不同。

另见:unittest.TestCase docs

【讨论】:

  • 似乎找不到inspect._findclass
  • 我用 Python 3.5.2 对其进行了测试。如果您正在尝试 Python 2 内省,则还需要进行其他更改。我认为来源仍然证明了答案。
  • 你能把源代码放在这里而不是放在一个要点里,这样它就保存在这里而不是另一个网站上吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多