How to supply stdin, files and environment variable inputs to Python unit tests?

后端 未结 4 408
囚心锁ツ
囚心锁ツ 2020-11-29 03:51

How to write tests where conditions like the following arise:

  1. Test user Input.
  2. Test input read from a file.
  3. Test input read from an environme
4条回答
  •  有刺的猬
    2020-11-29 04:38

    If you can get away without using an external process, do so.

    However, there are situations where this is complicated, and you really want to use process, e.g., you want to test the command line interface of a C executable.

    User input

    Use subprocess.Popen as in:

    process = subprocess.Popen(
        command,
        shell  = False,
        stdin  = subprocess.PIPE,
        stdout = subprocess.PIPE,
        stderr = subprocess.PIPE,
        universal_newlines = True
    )
    stdout, stderr = process.communicate("the user input\nline 2")
    exit_status = process.wait()
    

    There is no difference between taking input from a user and taking it from a pipe for input done with methods like raw_input or sys.stdin.read().

    Files

    • Create a temporary directory and create the files you want to read from in there on your test setUp methods:

      tdir = tempfile.mkdtemp(
          prefix = 'filetest_', 
      )
      fpath = os.path.join(tdir,'filename')
      fp = open(fpath, 'w')
      fp.write("contents")
      fp.close()
      
    • Do the file reading in the tests.

    • Remove the temp dir afterwards.

      shutil.rmtree(tdir)
      
    • It is quite complicated reading from files, and most programs can read either from files or from STDIN (e.g. with fileinput). So, if what you want to test is what happens when a certain content is input, and your program accepts STDIN, just use Popen to test the program.

    Environment variables

    • Set the environment variables with os.environ["THE_VAR"] = "the_val"
    • Unset them with del os.environ["THE_VAR"]
    • os.environ = {'a':'b'} does not work
    • Then call subprocess.Popen. The environment is inherited from the calling process.

    Template Code

    I have a module on my github that tests STDOUT, STDERR and the exit status given STDIN, command line arguments and enviroment. Also, check the tests for that module under the "tests" dir. There must be much better modules out there for this, so take mine just for learning purposes.

提交回复
热议问题