0

I am running integration tests with Nose. In one of my tests, I need to get the output and parse it to find a specific string.

def test_diagnostic_tool():
    with Capturing() as output:
        failures = run_integration_testing_exe('*', test_exe='DiagnosticTool.exe', use_default_composed_filter=False)

    eq_(failures, 0)


class Capturing(list):
    def __enter__(self):
        self._stdout = sys.stdout
        sys.stdout = self._stringio = StringIO()
        return self

    def __exit__(self, *args):
        self.extend(self._stringio.getvalue().splitlines())
        sys.stdout = self._stdout

This does not work. The 'output' variable contains only a small string from a print somewhere in the call structure.

The 'run_integration_testing_exe' function is calling another function and the external exe program is called there. In the shell, everthing outputs fine, so I was wondering if there was a way to capture all of that and parse it.

TheSoundDefense
  • 6,753
  • 1
  • 30
  • 42
Amaranth
  • 2,433
  • 6
  • 36
  • 58
  • You probably need to include the code for the function that actually runs the external program, since it depends on how e.g. `subprocess.Popen` is invoked, if that is what is running the exe. – deinonychusaur Jul 15 '14 at 18:29
  • I wish I could. That function is part of the testing framework and I can't modify it (I import it in my test script). – Amaranth Jul 15 '14 at 18:31
  • Are you sure that the stuff you are missing was actually written to stdout and not stderr? Else, if you can't get to the code that launches `DiagnosticTool.exe` you are probably without luck from within python. – deinonychusaur Jul 15 '14 at 18:50
  • I'm not a windows user, but could be related to http://stackoverflow.com/questions/3018848/cannot-redirect-output-when-i-run-python-script-on-windows-using-just-scripts-n maybe? – deinonychusaur Jul 15 '14 at 18:51
  • `nose` has a command line argument `--no-capture` that retains `stdout` within the test fixtures, which would allow you to capture/parse the `stdout` of your new process. – blakev Jul 15 '14 at 19:07

1 Answers1

1

You could give a shot redirecting from sys.__stdout__ in your Capturing class, just to eliminate the possibility that nose or other plugins within nose are messing with you capturing the output. This object contains the original values of stdout at the start of the program, as described in sys docs. This will only work if your executable process already properly redirected its stdout stream to the python interpreter's stream.

But I think it would not make much difference. The key here is that capturing and redirecting sys.stdout in most cases doesn’t affect the standard I/O streams of processes executed by subprocess() family of functions, which I suppose is happening here.

Your best bet is to explicitly capture stdout from your subprocess.Popen call using subprocess.PIPE and communicate() (like here), print it out within the test and let the nose capture it. There is a good chance that subprocess call is done via shell and is outside the stdout which python has control over.

And if you cannot modify this code, you can always monkey patch it ;-)

Community
  • 1
  • 1
Oleksiy
  • 6,337
  • 5
  • 41
  • 58
  • I tried it, but did not work. I don't know what you mean exactly by "monkey path it". However, I was able to contact the people in charge of that plugin and asked them to capture and return the output with the function. – Amaranth Aug 01 '14 at 21:00
  • I was referring to dynamically modifying plugin code to something else that actually captures STDOUT - but looks like you do have power to do it properly. – Oleksiy Aug 01 '14 at 22:32