我有一个使用Python unittest模块进行单元测试的大型项目。
我有一个控制系统行为的大方面的小方法。我需要这种方法在UT下运行时返回一个固定的结果,以便给出一致的测试运行,但是对于每个单独的UT模拟它都会很昂贵。
有没有办法可以让这个单一方法知道单元测试,以便在单元测试下运行时可以修改它的行为?
答案 0 :(得分:3)
您可以检查unittest
模块是否已加载。如果运行测试,则应仅加载该文件。
>>> 'unittest' in sys.modules.keys()
False
>>> from unittest import TestCase
>>> 'unittest' in sys.modules.keys()
True
答案 1 :(得分:2)
我对unittest
模块了解不多,但是如果您直接运行文件进行单元测试,则可以使用以下内容包含测试代码:
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
模块有很多有用的内省函数。
答案 2 :(得分:2)
我的解决方案是在运行TEST_FLAG=true
之前设置unittest
环境变量。例如:
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')
答案 3 :(得分:1)
您可以在运行时为测试修改函数。例如:
def func():
return random.randint()
import module
def replacement_func():
return 4 # chosen by fair dice roll
module.func = replacement_func
# run unit tests here
现在,只要module
中的代码调用func()
,它就会实际回拨给replacement_func()
。
答案 4 :(得分:0)
我确信还有其他更好的方法,但你总是可以从主要设置全局标志而不是单元测试,然后在你的方法中访问它。
另一种方法当然是覆盖方法作为单元测试设置的一部分 - 如果您的方法被调用brian
并且您有一个test_brian
,那么只需在您预先设置测试设置brian = test_brian
将完成工作,您可能需要将模块名称放入前面的语句。
答案 5 :(得分:0)
使用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.