我在用Python测试代码输入时遇到麻烦。我尝试了几种解决方案,但是我缺少一些东西,因此,如果您能给我一些提示,我将不胜感激。
首先,这是我要测试的主代码文件中的摘录:
if __name__ == '__main__':
n = int(input())
m = int(input())
grid = []
for _ in range(n):
grid.append(list(map(str, input().rstrip().split())))
calculate(grid)
运行代码时,我输入“ n”,然后输入“ m”,然后根据用户输入(在新行中的每一行..)创建一个网格,并执行一个计算内容的函数。网格,函数返回结果。一切都很好,但是现在我需要为其创建几个测试用例(针对预期的输出测试不同的输入)。
首先,我尝试过此操作:(在单独的.py文件中)
from unittest import mock
from unittest import TestCase
import main_file
class DictCreateTests(TestCase):
@mock.patch('main_file.input', create=True)
def testdictCreateSimple(self, mocked_input):
mocked_input.side_effect = ['2', '2', 'R G B\nR G B'] #this is the input I need for my color grid
self.assertEqual(calculate(grid), 2)
if __name__ == '__main__':
unittest.main()
然后我研究了更多选项,并尝试了该选项,这使我最接近:
import unittest
import os
class Test1(unittest.TestCase):
def test_case1(self):
input = "2\n2\nR G B\nR G B"
expected_output = '2'
with os.popen("echo " + input + "' | python main_file.py") as o:
output = o.read()
output = output.strip() # Remove leading spaces and LFs
self.assertEqual(output, expected_output)
if __name__ == '__main__':
unittest.main()
不幸的是,尽管它通过了测试,但我发现当它与预期的输出进行比较时,它始终接受输入的第一个字母/数字作为结果。因此,我认为这与我需要输入的多个值有关。我尝试将它们分别放在不同的输入(输入1 +输入2 +输入3)上,但仍然无法正常工作。
如果有人可以给我一些操作方法的提示,我将非常感激!预先谢谢你!
答案 0 :(得分:3)
我建议重构代码,以便您可以测试功能:
def create_grid_and_calculate(n, m):
grid = []
for _ in range(n):
grid.append(list(map(str, input().rstrip().split())))
return calculate(grid)
if __name__ == '__main__':
n = int(input())
m = int(input())
create_grid_and_calculate(n, m)
然后
import unittest
import os
from main_file import create_grid_and_calculate
class Test1(unittest.TestCase):
def test_case1(self):
expected_output = '2'
self.assertEqual(create_grid_and_calculate(2, 2), expected_output)
self.assertEqual(create_grid_and_calculate(int("R G B"), int("R G B")), expected_output)
if __name__ == '__main__':
unittest.main()
您还可以使用在命令行上传递的参数替换输入,并使用专用模块(例如,argparse
进行解析)来更好地控制输入。
import argparse
def create_grid_and_calculate(n, m):
...
def main(argv: list = None):
parser = argparse.ArgumentParser(description="My script...")
parser.add_argument(
"-m",
dest="m",
action="store",
type=int,
help="parameter m",
)
parser.add_argument(
"-n",
dest="n",
action="store",
type=int,
help="parameter n",
)
args = parser.parse_args(argv or [])
create_grid_and_calculate(args.n, args.m)
if __name__ == '__main__':
import sys
sys.exit(main(sys.argv[1:]))
因此,您还可以使用不同的输入(int,字符串...)测试主函数。
最后,pytest是建立在unittest
之上的出色的单一测试框架,也许您可以看看。
编辑: 要定义网格,不需要输入大小(n和m),也不需要分别输入每一行。为行选择1个分隔符(此处为逗号),为列选择另一种分隔符(此处为空格),您将得到:
import argparse
def main(argv: list = None):
parser = argparse.ArgumentParser(description="My script...")
parser.add_argument(
"-g",
"--grid",
dest="grid",
action="store",
type=str,
help="The grid, defined as 'x11 x12 ... x1n, x21 x22 ... x2n, ...'",
)
args = parser.parse_args(argv or [])
# first we split on comma, then on space
grid = [x.split() for x in args.grid.split(',')]
print(grid)
calculate(grid)
if __name__ == '__main__':
import sys
sys.exit(main(sys.argv[1:]))
您将像这样运行它:main_file.py -g '1 2 3, 4 5 6, 7 8 9'
[['1', '2', '3'], ['4', '5', '6'], ['7', '8', '9']]
要获取int列表,请使用:
grid = [[int(val) for val in row.split()] for row in args.grid.split(',')]
或者也许更清楚:
grid = []
for row in args.grid.split(','):
grid.append([])
for val in row.split():
grid[-1].append(int(val))