def runner(test_command, work_dir=None):
    """
    Internal test job runner context manager.

    Run the test_command in a subprocess and instantiates 2
    FlushStreamThread, one for each standard stream (output/stdout
    and error/stderr).

    It yields the subprocess.Popen instance that was spawned to
    run the given test command in the given working directory.

    Leaving the context manager kills the process and joins the
    flushing threads. Use the ``process.wait`` method to avoid that.
    """
    process = subprocess.Popen(test_command, bufsize=0, shell=True,
                               cwd=work_dir,
                               stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    with flush_stream_threads(process):
        try:
            yield process
        finally:
            if process.poll() is None:
                process.terminate()
Internal test job runner context manager.

    Run the test_command in a subprocess and instantiates 2
    FlushStreamThread, one for each standard stream (output/stdout
    and error/stderr).

    It yields the subprocess.Popen instance that was spawned to
    run the given test command in the given working directory.

    Leaving the context manager kills the process and joins the
    flushing threads. Use the ``process.wait`` method to avoid that.