繁体   English   中英

测试用户输入-Python

[英]Testing User Input - Python

我在用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()

不幸的是,尽管它通过了测试,但我发现当它与预期的输出进行比较时,它始终接受输入的第一个字母/数字作为结果。 因此,我认为这与我需要输入的多个值有关。 我尝试将它们分离在不同的输入(input1 + input2 + input3)上,但是仍然无法正常工作。

如果有人可以给我一些操作技巧,我将不胜感激! 先感谢您!

我建议重构代码,以便您可以测试功能:

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,字符串...)测试main函数。

最后, 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))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM