Subprocess .Popen () output capture with nose

I use nose to test an application that uses subprocess.Popen() to call a script. Neither the capture plugin nor logcapture seem to capture the output of this script. Is there an easy way to pass this conclusion into the nose?

Here is what I have tried to do so far; The Capture Me note is not fixed:

example.py

 if __name__ == '__main__': print 'Capture me' 

test.py

 import subprocess import sys def test_popen(): # nose capture plugin replaces sys.stdout with a StringIO instance. # subprocess.Popen() expects stdout to have a fileno property, which # StringIO doesn't, so fake it. sys.stdout.fileno = lambda: 1 subprocess.Popen(['python', 'example.py'], stdout=sys.stdout) assert False # Force test to fail so we see nose output 

Output :

 $ nosetests test.py F ====================================================================== FAIL: test.test_popen ---------------------------------------------------------------------- Traceback (most recent call last): File "/Users/pmdarrow/Envs/example/lib/python2.7/site-packages/nose/case.py", line 197, in runTest self.test(*self.arg) File "/Users/pmdarrow/Code/example/API/test.py", line 8, in test_popen assert False AssertionError ---------------------------------------------------------------------- Ran 1 test in 0.004s FAILED (failures=1) Capture me 
+7
python nose nosetests
source share
2 answers

There are a few questions you should know. Perhaps I repeat @arbunet's answer, but a little with me. Therefore, if you wait for the process to complete and redirect the "stdout" process to the test stdout, everything will be written correctly with the nose:

 import subprocess import sys def test_popen(): p = subprocess.Popen(['python', 'example.py'], stdout=subprocess.PIPE) out, err = p.communicate() print out assert False 

Here PIPE is created and redirected to stdout using a print statement. Alternatively, you can pass sys.__stdout__ (the unmolested stdout of the test) or another file descriptor to the Popen call, and then clear it in sys.stdout (the StringIO.StringIO instance created by the nose), but it looks less clean (compared to a simple print operator).

+3
source share

You might think:

 p = subprocess.Popen(['python', 'example.py'], stdout=subprocess.PIPE) q = p.communicate() output = q[0] 

See communicate for more information from the subprocess. Hooray!

0
source share

All Articles