【问题标题】:How can a piece of python code tell if it's running under unittest一段python代码如何判断它是否在unittest下运行
【发布时间】:2014-09-21 10:50:41
【问题描述】:

我有一个使用 Python unittest 模块进行单元测试的大型项目。

我有一种小方法可以控制系统行为的大部分方面。在 UT 下运行时,我需要这种方法返回一个固定的结果,以提供一致的测试运行,但对我来说,为每个 UT 模拟它会很昂贵。

有没有办法让这个单一方法,单元测试感知,以便它可以在单元测试下运行时修改其行为?

【问题讨论】:

标签: python unit-testing


【解决方案1】:

我确信还有其他更好的方法,但是您始终可以从 main 设置一个全局标志,而不是在单元测试中,然后在您的方法中访问它。

当然,另一种方法是在单元测试设置中覆盖该方法 - 如果您的方法被称为 brian 并且您有一个 test_brian,那么只需在您的预测试设置期间进行 @987654323 @ 将完成这项工作,您可能需要将模块名称放入前面的语句中

【讨论】:

    【解决方案2】:

    您可以在运行时为测试修改函数。例如:

    模块.py

    ​​>
    def func():
        return random.randint()
    

    test.py

    ​​>
    import module
    
    def replacement_func():
        return 4 # chosen by fair dice roll
    
    module.func = replacement_func
    
    # run unit tests here
    

    现在,每当module 中的代码调用func() 时,它实际上会回调到您的replacement_func()

    【讨论】:

      【解决方案3】:

      我对@9​​87654323@ 模块了解不多,但是如果您是直接运行该文件进行单元测试,则可以在测试代码中附上以下 if:

      if __name__ == "__main__":
      

      if 语句中的任何代码只有在您的特定模块被直接调用时才会被执行,而不是导入到其他东西中。根据文档,这就是您应该首先调用unittest.main() 的方式。

      https://docs.python.org/2/library/unittest.html

      这假设您没有从命令行运行。

      编辑:您可以查看函数堆栈以尝试找到 unittest.main() 函数。

      import inspect
      
      def in_unit_test():
        current_stack = inspect.stack()
        for stack_frame in current_stack:
          for program_line in stack_frame[4]:    # This element of the stack frame contains 
            if "unittest" in program_line:       # some contextual program lines
              return True
        return False
      

      https://docs.python.org/2/library/inspect.html

      这是一种 hacky 解决方案,但 inspect 模块有很多有用的自省功能。

      【讨论】:

      • 我的解决方案是在上面的“if name ...”行之后创建一个标志“sys.unittesting = None”。 sys 在很多文件中被导入......当然任何通常导入的模块都可以。我发现您有时确实需要确定您是否在进行单元测试,例如抑制等待用户输入的内容。
      • 警告:此函数将始终返回 True,因为函数名称为 in_unittest,并将由 if "unittest" in program_line: 断言
      • 糟糕,已修复。谢谢。
      【解决方案4】:

      我的解决方案是在运行unittest 之前设置一个TEST_FLAG=true 环境变量。例如:

      TEST_FLAG=true python -m unittest discover -s tests -b
      

      那么只需要检查变量是否被设置。例如:

      MONGODB_URI =
          os.environ.get('MONGODB_URI') if not os.environ.get('TEST_FLAG') 
              else os.environ.get('MONGODB_TEST_URI')
      

      【讨论】:

        【解决方案5】:

        使用tox 我设置了一个这样的环境变量:

        [testenv]
        setenv = TOX_TESTENV = true
        

        然后在代码中检查是否设置了变量:

        import os
        
        
        if os.env.get('TOX_TESTENV'):
            # Code is running under test.
            # This is useful to configure log levels for example.
        

        【讨论】:

          【解决方案6】:

          您可以检查unittest 模块是否已加载。只有在测试运行时才应该加载它。

          >>> 'unittest' in sys.modules.keys()
          False
          >>> from unittest import TestCase
          >>> 'unittest' in sys.modules.keys()
          True
          

          【讨论】:

          • 跳过.keys()而直接使用'unittest' in sys.modules应该会更高效。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-09-13
          • 2016-01-11
          • 2016-10-04
          • 1970-01-01
          • 1970-01-01
          • 2011-11-14
          • 2021-04-16
          相关资源
          最近更新 更多