2017-09-04 124 views
0

我正在編寫一些測試,依靠用戶輸入來決定它們是否已通過。使pytest等待用戶輸入

我有這樣的功能:

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它運行良好,並且在每次試驗後停下來獲取用戶輸入。但是,我想用它設置了各種變量和標頭日誌文件(稱爲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() 

當我這樣運行它,它不會停止或運行任何測試。

如果我可以寫入日誌文件,同時也寫入相同的東西到終端(包括用戶輸入),這將是偉大的。否則,正確調用這個函數的方法也會起作用。

+3

單元測試的要點是它們不需要用戶交互... –

+0

此功能可以被測試的唯一方法就是這樣,因爲它可能是不正確的 –

+1

您真的需要找到一種方法來模擬用戶輸入用於測試目的。如果您在測試過程中依賴用戶輸入,那麼運行測試的其他人可能不會測試與您相同的內容。測試應該是確定性的。 – larsks

回答

2

你的測試應該儘可能的簡單,讓它可以隨意執行。如果他們將依賴於外部(例如用戶)輸入和其他一些技巧來正常運行,那麼從長遠來看,沒有人會執行它們。

如果你在你也許可以忍受它的項目的唯一開發商,但我要說,這種做法是不正確,不認爲是最佳實踐

應用:

的一切,如果你只是在控制檯(這似乎是從你的代碼段),等待用戶的輸入,那麼就嘲笑input內置並將其設置爲返回值,例如第一的.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是鬆耦合的代碼 - 這樣你就可以測試你的邏輯,無論在圖形用戶界面(無論是Web,桌面或移動應用) 。