让pytest等待用户输入
Making pytest wait for user input
我正在编写一些依赖于用户输入来决定它们是否通过的测试。
我有这个功能:
def viewable(actual_proj):
print("\nCan you see %s projects named:\n"%len(actual_proj))
for i in actual_proj:
print (i+"\n")
return input("(y/n)? : ")
内:
def is_present(pytestconfig, project_not_present = 0):
actual_projects = all_projects.copy()
if (project_not_present!=0):
del_file = all_ini_files[project_not_present-1]
os.rename(del_file, del_file +'_tst')
del actual_projects[project_not_present-1]
capmanager = pytestconfig.pluginmanager.getplugin('capturemanager')
subprocess.Popen('./MultiPRM.exe')
capmanager.suspendcapture(in_=True)
decision = viewable(actual_projects)
capmanager.resumecapture()
if (project_not_present!=0):
os.rename(del_file+'_tst', del_file)
if (decision =='y'):
return True
else:
return False
当我 运行 命令 pytest name_of_test_file.py
它 运行 没问题,并在每次测试后停止以获取用户输入。但是,我想使用一个文件来设置各种变量和 headers 作为日志文件(称为 run_tests.py
)
# start the report
print("Creating test report: " + os.path.abspath(report_filepath))
rep = open(report_filepath, "w")
rep.write(report_header)
rep.write("Test environment: \n");
rep.write(" Username: " + os.environ['USERNAME'] + "\n")
rep.write("Testing started at: " + get_time() + "\n\n")
rep.close()
# get application version
cmd = exe_under_test + " --help >> " + report_filepath
os.system(cmd)
# start the tests
cmd = "pytest >> " + report_filepath
os.system(cmd)
# finalise the report
rep = open(report_filepath, "a+")
rep.write("\nTesting completed at: " + get_time() + "\n\n")
rep.close()
当我 运行 这样做时,它不会停止或 运行 任何测试。
如果我可以写入日志文件,同时也可以将相同的内容写入终端(包括用户输入),那就太好了。否则,正确调用此函数的方法也可以。
您的测试应该尽可能 运行 简单,以便轻松执行它们。如果它们将依赖于外部(例如用户的)输入和其他一些技巧来正确 运行,那么没有人会在很长一段时间内执行它们 运行。
如果您是项目中唯一的开发人员,您可能可以接受它,但我要说这种方法是不正确的,不被认为是最佳实践。
首先,如果您只是在等待用户在控制台中的输入(从您的代码片段看来),那么只需模拟 input
内置并将其设置为 return 值, 例如:
app.py
def my_input(prompt=''):
try:
return raw_input(prompt)
except NameError:
return input(prompt)
def my_great_func():
choice = my_input('y/n?: ')
return choice
test.py
import unittest.mock as mock
import pytest
from app import my_great_func
@pytest.yield_fixture
def fake_input():
with mock.patch('app.my_input') as m:
yield m
def test_my_great_func(fake_input):
fake_input.return_value = 'y'
assert my_great_func() == 'y'
测试执行:
$ pytest test.py -v
============================= test session starts ==============================
platform linux -- Python 3.5.2, pytest-3.2.1
cachedir: .cache
rootdir: /home/kris/projects/tmp, inifile:
collected 1 item
test.py::test_my_great_func PASSED
=========================== 1 passed in 0.01 seconds ===========================
其次,努力在应用程序逻辑和 GUI 松散耦合的地方编写代码 - 这样您就可以测试您的逻辑,而不管 GUI(无论是 Web、桌面还是移动应用程序)。
单元测试不需要输入,但如果您临时需要,这是一种方法。如果您使用标志 -s
,它将按原样输出,而不是 capturing and only displaying on failures。因此,如果您使用 pytest -s
,您可以调用 input()
,它会在继续之前暂停并等待输入。
我正在编写一些依赖于用户输入来决定它们是否通过的测试。
我有这个功能:
def viewable(actual_proj):
print("\nCan you see %s projects named:\n"%len(actual_proj))
for i in actual_proj:
print (i+"\n")
return input("(y/n)? : ")
内:
def is_present(pytestconfig, project_not_present = 0):
actual_projects = all_projects.copy()
if (project_not_present!=0):
del_file = all_ini_files[project_not_present-1]
os.rename(del_file, del_file +'_tst')
del actual_projects[project_not_present-1]
capmanager = pytestconfig.pluginmanager.getplugin('capturemanager')
subprocess.Popen('./MultiPRM.exe')
capmanager.suspendcapture(in_=True)
decision = viewable(actual_projects)
capmanager.resumecapture()
if (project_not_present!=0):
os.rename(del_file+'_tst', del_file)
if (decision =='y'):
return True
else:
return False
当我 运行 命令 pytest name_of_test_file.py
它 运行 没问题,并在每次测试后停止以获取用户输入。但是,我想使用一个文件来设置各种变量和 headers 作为日志文件(称为 run_tests.py
)
# start the report
print("Creating test report: " + os.path.abspath(report_filepath))
rep = open(report_filepath, "w")
rep.write(report_header)
rep.write("Test environment: \n");
rep.write(" Username: " + os.environ['USERNAME'] + "\n")
rep.write("Testing started at: " + get_time() + "\n\n")
rep.close()
# get application version
cmd = exe_under_test + " --help >> " + report_filepath
os.system(cmd)
# start the tests
cmd = "pytest >> " + report_filepath
os.system(cmd)
# finalise the report
rep = open(report_filepath, "a+")
rep.write("\nTesting completed at: " + get_time() + "\n\n")
rep.close()
当我 运行 这样做时,它不会停止或 运行 任何测试。
如果我可以写入日志文件,同时也可以将相同的内容写入终端(包括用户输入),那就太好了。否则,正确调用此函数的方法也可以。
您的测试应该尽可能 运行 简单,以便轻松执行它们。如果它们将依赖于外部(例如用户的)输入和其他一些技巧来正确 运行,那么没有人会在很长一段时间内执行它们 运行。
如果您是项目中唯一的开发人员,您可能可以接受它,但我要说这种方法是不正确的,不被认为是最佳实践。
首先,如果您只是在等待用户在控制台中的输入(从您的代码片段看来),那么只需模拟 input
内置并将其设置为 return 值, 例如:
app.py
def my_input(prompt=''):
try:
return raw_input(prompt)
except NameError:
return input(prompt)
def my_great_func():
choice = my_input('y/n?: ')
return choice
test.py
import unittest.mock as mock
import pytest
from app import my_great_func
@pytest.yield_fixture
def fake_input():
with mock.patch('app.my_input') as m:
yield m
def test_my_great_func(fake_input):
fake_input.return_value = 'y'
assert my_great_func() == 'y'
测试执行:
$ pytest test.py -v
============================= test session starts ==============================
platform linux -- Python 3.5.2, pytest-3.2.1
cachedir: .cache
rootdir: /home/kris/projects/tmp, inifile:
collected 1 item
test.py::test_my_great_func PASSED
=========================== 1 passed in 0.01 seconds ===========================
其次,努力在应用程序逻辑和 GUI 松散耦合的地方编写代码 - 这样您就可以测试您的逻辑,而不管 GUI(无论是 Web、桌面还是移动应用程序)。
单元测试不需要输入,但如果您临时需要,这是一种方法。如果您使用标志 -s
,它将按原样输出,而不是 capturing and only displaying on failures。因此,如果您使用 pytest -s
,您可以调用 input()
,它会在继续之前暂停并等待输入。