subprocess.call() 中的 Pytest 模拟全局变量
Pytest mock global variable in subprocess.call()
在 these answers 之后可以轻松模拟全局变量。伟大的。但是,当您在 Pytest 的测试中尝试模拟您使用 subprocess.call()
调用的脚本中的变量时,这不起作用。
这是我在名为 so_script.py
:
的文件中的简化脚本
import argparse
INCREMENTOR = 4
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('input_nr', type=int, help='An int to increment')
args = parser.parse_args()
with open('test.txt', 'w+') as f:
f.write(str(args.input_nr + INCREMENTOR))
现在,假设我想在我的测试中将 INCREMENTOR
的值模拟为 1
。如果我这样做:
from subprocess import call
from unittest import mock
def test_increments_with_1():
with mock.patch('so_script.INCREMENTOR', 1):
call(['python', 'so_script.py', '3'])
with open('test.txt', 'r+') as f:
assert f.read() == '4'
测试将失败,因为 INCREMENTOR
的值仍然是 4,即使我试图将其修补为 1。所以写入文件的是 7 而不是 4。
所以我的问题是:如何在我的 so_script.py
文件中模拟 INCREMENTOR
全局变量,以便在对其调用 subprocess.call()
时,它仍然被模拟?
因为 so_script.py
脚本和 pytest 在不同的进程中执行,所以不能在 so_script.py
中模拟对象,而后者在测试中被称为不同的进程。
我找到的最佳解决方案是将 if __name__ == '__main__:
块中的所有内容放入一个函数中,然后使用 Pytest 测试该函数,模拟我需要模拟的任何内容。而且,为了获得 100% 的测试覆盖率(这是我将脚本作为子进程调用的最初意图),我应用了 this solution.
所以我在测试中放弃使用 subprocess.call()
并编写了一个 init()
函数来检查 if __name__ == '__main__:
,然后在测试中模拟 __name__
来测试函数,只是正如文章建议的那样。这让我获得了 100% 的测试覆盖率和完整的模拟功能。
在 these answers 之后可以轻松模拟全局变量。伟大的。但是,当您在 Pytest 的测试中尝试模拟您使用 subprocess.call()
调用的脚本中的变量时,这不起作用。
这是我在名为 so_script.py
:
import argparse
INCREMENTOR = 4
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('input_nr', type=int, help='An int to increment')
args = parser.parse_args()
with open('test.txt', 'w+') as f:
f.write(str(args.input_nr + INCREMENTOR))
现在,假设我想在我的测试中将 INCREMENTOR
的值模拟为 1
。如果我这样做:
from subprocess import call
from unittest import mock
def test_increments_with_1():
with mock.patch('so_script.INCREMENTOR', 1):
call(['python', 'so_script.py', '3'])
with open('test.txt', 'r+') as f:
assert f.read() == '4'
测试将失败,因为 INCREMENTOR
的值仍然是 4,即使我试图将其修补为 1。所以写入文件的是 7 而不是 4。
所以我的问题是:如何在我的 so_script.py
文件中模拟 INCREMENTOR
全局变量,以便在对其调用 subprocess.call()
时,它仍然被模拟?
因为 so_script.py
脚本和 pytest 在不同的进程中执行,所以不能在 so_script.py
中模拟对象,而后者在测试中被称为不同的进程。
我找到的最佳解决方案是将 if __name__ == '__main__:
块中的所有内容放入一个函数中,然后使用 Pytest 测试该函数,模拟我需要模拟的任何内容。而且,为了获得 100% 的测试覆盖率(这是我将脚本作为子进程调用的最初意图),我应用了 this solution.
所以我在测试中放弃使用 subprocess.call()
并编写了一个 init()
函数来检查 if __name__ == '__main__:
,然后在测试中模拟 __name__
来测试函数,只是正如文章建议的那样。这让我获得了 100% 的测试覆盖率和完整的模拟功能。