Python Unittest:打开并等待程序关闭

时间:2011-07-28 13:02:11

标签: python unit-testing

目前我尝试创建一个打开文件的单元测试(使用相应的应用程序),然后测试运行应该等到程序关闭。

def test_HFG(self):
#....
print "please edit this file"
os.chdir(r'C:\test\a')
os.startfile("myfile.vdx")
# here I need a "stop until the program is closed"-function
#....

有没有人知道如何实现(尽可能简单)我的计划?

5 个答案:

答案 0 :(得分:4)

os.startfile当然是完全无阻塞的,没有等待的选项。

我建议使用subprocess模块,调用Windows“start”命令打开带有关联对象的文件,这与os.startfile完全相同,但允许你等待完成的过程。

e.g:

subprocess.call(["start", my_file])

答案 1 :(得分:3)

来自文档:

  一旦关联的应用程序出现,

startfile()就会返回   推出。没有选项等待应用程序关闭,并且   无法检索应用程序的退出状态。

如果你知道打开文件的应用程序的路径,你可以使用subprocess.Popen()来让你等待。

请参阅: http://docs.python.org/library/os.html#os.startfile

http://docs.python.org/library/subprocess.html#subprocess.Popen

答案 2 :(得分:1)

os.startfile的文档明确说明:

  一旦启动关联的应用程序,

startfile()就会返回。   没有选择等待应用程序关闭,也没办法   检索应用程序的退出状态

因此,我建议使用替代方法,例如通过subprocess.Popen启动它,这样可以让您等到子流程完成。

答案 3 :(得分:0)

answer = raw_input("Please Edit this file (done): ")
if answer == done:
    blablabla
else:
    stop programm or whatever

让他告诉你他什么时候完成,我能想象的最简单的方式

答案 4 :(得分:0)

您可以按照this C++ answer的建议,通过pywin32调用基础Windows API:

def start_file_wait(fname):
    import win32con
    import win32api
    import win32event
    from win32com.shell import shellcon
    from win32com.shell.shell import ShellExecuteEx
    rc = ShellExecuteEx(
        fMask=shellcon.SEE_MASK_NOCLOSEPROCESS,
        nShow=win32con.SW_SHOW,
        lpFile=fname)
    hproc = rc['hProcess']
    win32event.WaitForSingleObject(hproc, win32event.INFINITE)
    win32api.CloseHandle(hproc)

或直接来自ctypes

def startfile_wait(fname):
    import ctypes
    from ctypes.wintypes import ULONG, DWORD, HANDLE, HKEY, HINSTANCE, HWND, LPCWSTR


    class SHELLEXECUTEINFOW(ctypes.Structure):
        _fields_ = [
            ("cbSize", DWORD),
            ("fMask", ULONG),
            ("hwnd", HWND),
            ("lpVerb", LPCWSTR),
            ("lpFile", LPCWSTR),
            ("lpParameters", LPCWSTR),
            ("lpDirectory", LPCWSTR),
            ("nShow", ctypes.c_int),
            ("hInstApp", HINSTANCE),
            ("lpIDList", ctypes.c_void_p),
            ("lpClass", LPCWSTR),
            ("hkeyClass", HKEY),
            ("dwHotKey", DWORD),
            ("DUMMYUNIONNAME", ctypes.c_void_p),
            ("hProcess", HANDLE)
        ]

    shell_execute_ex = ctypes.windll.shell32.ShellExecuteExW
    shell_execute_ex.argtypes = [ctypes.POINTER(SHELLEXECUTEINFOW)]
    shell_execute_ex.res_type = ctypes.c_bool

    wait_for_single_object = ctypes.windll.kernel32.WaitForSingleObject
    wait_for_single_object.argtypes = [HANDLE, DWORD]
    wait_for_single_object.res_type = DWORD

    close_handle = ctypes.windll.kernel32.CloseHandle
    close_handle.argtypes = [HANDLE]
    close_handle.res_type = bool

    # https://stackoverflow.com/a/17638969/102441
    arg = SHELLEXECUTEINFOW()
    arg.cbSize = ctypes.sizeof(arg)
    arg.fMask = 0x00000040  # SEE_MASK_NOCLOSEPROCESS
    arg.hwnd = None
    arg.lpVerb = None
    arg.lpFile = fname
    arg.lpParameters = ""
    arg.lpDirectory = None
    arg.nShow = 10  # SW_SHOWDEFAULT
    arg.hInstApp = None
    ok = shell_execute_ex(arg)
    if not ok:
        raise ctypes.WinError()
    try:
        wait_for_single_object(arg.hProcess, -1)
    finally:
        close_handle(arg.hProcess)