I am writing some tests that rely on user input to decide whether they have passed.
I have this function:
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)? : ")
Within :
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
When i run the command pytest name_of_test_file.py
it runs fine, and stops after each test to get user input. However, i want to use a file which sets up various variables and headers for a log file (called 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()
When i run it this way, it does not stop or run any of the tests.
If i could write to a log file while also writing the same thing to the terminal(including user input) that would be great. Otherwise, a way of calling this function correctly would work too.
Your tests should be as easy to run as possible to make it hassle free to execute them. If they will be dependent on external (e.g. user's) input and some other tricks to properly run, then nobody is going to execute them in the long run.
If you are the sole developer in the project you can probably live with it, but I would say that this approach is incorrect and not considered to be the best-practices.
First of all if you are just waiting for user's input in the console (which seems like from your code snippets), then just mock the
input
built-in and set it return value, e.g.:app.py
test.py
Test execution:
And secondly strive to write code where your application logic and GUI are loosely coupled - this way you can test your logic regardless of the GUI (be it web, desktop or mobile app).