【问题标题】:Skipping code in python if in a unittest如果在单元测试中跳过python中的代码
【发布时间】:2018-07-11 07:40:54
【问题描述】:

我当前的脚本调用外部脚本来执行某些任务。我想在单元测试中检查代码,但实际上并没有运行外部脚本。如果代码作为单元测试的一部分运行,有什么方法可以告诉脚本有效地跳过以下块?

【问题讨论】:

  • 意味着您正在导入您在单元测试中运行的 .py 文件?
  • 模拟出外部任务并将其作为参数传递
  • 嗯。还没有看过 Mock - 如果我要做一些适当的单元测试,可能应该。
  • 您不应该将条件测试代码与生产代码混合。

标签: python unit-testing python-unittest


【解决方案1】:

unittest 包广泛支持“模拟”功能和方法。将对外部程序的调用封装在一个简单的函数中,您的单元测试可以覆盖(“模拟”)而不修改程序的结构。示例:

这是你程序的一部分,在模块realcode.py

def internal_function_calling_exec(arg1):
    """The real thing"""
    print("I am executing an external program")


def bigger_function_being_tested(arg1, arg2):
    """
    A complex function with one or more calls to `internal_function_calling_exec`
    """
    print("I will now call `internal_function_calling_exec()`")
    internal_function_calling_exec(42)

您的单元测试可能如下所示:

import unittest
from unittest.mock import patch
import realcode

class MyTest(unittest.TestCase):

    @patch("realcode.internal_function_calling_exec")
    def test_something(self, mocked_func):
        realcode.bigger_function_being_tested(1, 2)
        mocked_func.assert_called_with(42)

这永远不会调用原始的internal_function_calling_exec()。相反,这将触发对模拟对象的调用;然后您的测试可以查询该对象以确认它被正确调用。

有一些方法可以模拟类方法等,例如,您可以模拟 subprocess.call。但我认为以上是更好的模式。

【讨论】:

    【解决方案2】:

    一种可能的方法是在单元测试中设置一个环境变量,并在被测试的脚本中检查该环境变量。

    例如在unittest.py:

    os.environ["testing"] = "1"
    

    script-to-be-tested.py:

    testing = os.environ["testing"]
    ... do stuff based on the testing variable
    

    由于script-to-be-tested.py会从unittest.py调用,它应该继承环境变量。

    可能不是最干净的解决方案,但它应该可以工作。

    【讨论】:

    • 这与我的想法一致。 DI 想知道 unittest 是否设置了我可以查询的任何自身?
    • @Chris:据我所知 pyunit 本身不会改变任何环境变量。查看this answer 是否有其他有用的解决方案?
    猜你喜欢
    • 2012-09-25
    • 1970-01-01
    • 2013-07-05
    • 1970-01-01
    • 2018-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多