¿Cómo puedo probar la salida STDOUT de una secuencia de comandos de Python con un marco de prueba como doctest, unittest, nose, etc.? Por ejemplo, digamos que ejecutar mi script "todo.py --list" debería devolver "take the garbage". Leí a alguien que separa la parte de impresión STDOUT del guión de la parte que genera el resultado que se imprimirá. Estoy acostumbrado a rociar las instrucciones de impresión alrededor de mis scripts de shell. ¿Es esto simplemente un hábito desagradable de TDD que debería romper o hay una manera de probar fácilmente la impresión correcta?Prueba de las secuencias de comandos de Python
Respuesta
Aquí hay algo que escribí una tarde que prueba la secuencia de comandos. Tenga en cuenta que la prueba cubre los casos básicos, pero no es lo suficientemente minuciosa como para ser una prueba unitaria por sí misma. Considéralo un primer borrador.
import sys
import subprocess
if sys.platform == "win32":
cmd = "zs.py"
else:
cmd = "./zs.py"
def testrun(cmdline):
try:
retcode = subprocess.call(cmdline, shell=True)
if retcode < 0:
print >>sys.stderr, "Child was terminated by signal", -retcode
else:
return retcode
except OSError, e:
return e
tests = []
tests.append((0, " string pattern 4"))
tests.append((1, " string pattern"))
tests.append((3, " string pattern notanumber"))
passed = 0
for t in tests:
r = testrun(cmd + t[1])
if r == t[0]:
res = "passed"
passed += 1
else:
res = "FAILED"
print res, r, t[1]
print
if passed != len(tests):
print "only",passed,"tests passed"
else:
print "all tests passed"
Y aquí es el guión que se estaba probando, zs.py, esto búsquedas de patrones en una secuencia similar a la forma en la búsqueda bioquímicos patrones en datos de ADN o datos de la cadena de proteína.
#!/usr/bin/env python
# zs - some example Python code to demonstrate to Z??s
# interviewers that the writer really does know Python
import sys
from itertools import *
usage = '''
Usage: zs <string> <pattern> <n>"
print top n matches of pattern in substring"
'''
if sys.hexversion > 0x03000000:
print "This script is only intended to run on Python version 2"
sys.exit(2)
if len(sys.argv) != 4:
print usage
sys.exit(1)
A = sys.argv[1] # string to be searched
B = sys.argv[2] # pattern being searched for
N = sys.argv[3] # number of matches to report
if not N.isdigit():
print "<n> must be a number"
print usage
sys.exit(3)
def matchscore(s1, s2):
''' a helper function to calculate the match score
'''
matches = 0
for i in xrange(len(s1)):
if s1[i] == s2[i]:
matches += 1
return (matches + 0.0)/len(s1) # added 0.0 to force floating point div
def slices(s, n):
''' this is a generator that returns the sequence of slices of
the input string s that are n characters long '''
slen = len(s)
for i in xrange(slen - n + 1):
yield s[i:i+n]
matchlen = len(B)
allscores = ((matchscore(x,B),x,i) for i,x in enumerate(slices(A,matchlen)))
nonzeros = [ y for y in allscores if y[0] != 0 ]
for elem in sorted(nonzeros,key=lambda e: e[0],reverse=True):
nprinted = 0 # We will count them; in case num elements > N
print elem[1], str(round(elem[0],4)), elem[2]
nprinted += 1
if nprinted >= N:
break
Veo dos maneras:
Redirigir stdout durante el unittest:
class YourTest(TestCase): def setUp(self): self.output = StringIO() self.saved_stdout = sys.stdout sys.stdout = self.output def tearDown(self): self.output.close() sys.stdout = self.saved_stdout def testYourScript(self): yourscriptmodule.main() assert self.output.getvalue() == "My expected ouput"
utilizar un registrador para sus salidas y escucharla en su prueba.
cuando utiliza py.test para su prueba. Puede utilizar los "CAPSYS" o los argumentos de la función de prueba "capfd" para ejecutar afirma contra STDOUT y STDIN
def test_myoutput(capsys): # or use "capfd" for fd-level
print ("hello")
sys.stderr.write("world\n")
out, err = capsys.readouterr()
assert out == "hello\n"
assert err == "world\n"
print "next"
out, err = capsys.readouterr()
assert out == "next\n"
Más detalles se pueden encontrar in the py.test docs
Yo también puede que desee ver en el marco TextTest prueba . Se centra más en las pruebas funcionales/de aceptación (por lo que es menos susceptible a las pruebas unitarias) y se basa en gran medida en el resultado textual de un programa. De esta forma, tu hábito se convierte en uno bueno :-).
propio banco de pruebas de Python hace esto un poco, y se utilizan dos técnicas principales:
Redirigir la salida estándar (como han sugerido otros). Utilizamos un gestor de contexto para esto:
import io import sys import contextlib @contextlib.contextmanager def captured_output(stream_name): """Run the 'with' statement body using a StringIO object in place of a specific attribute on the sys module. Example use (with 'stream_name=stdout'): with captured_stdout() as s: print("hello") assert s.getvalue() == "hello" """ orig_stdout = getattr(sys, stream_name) setattr(sys, stream_name, io.StringIO()) try: yield getattr(sys, stream_name) finally: setattr(sys, stream_name, orig_stdout) def captured_stdout(): return captured_output("stdout") def captured_stderr(): return captured_output("stderr") def captured_stdin(): return captured_output("stdin")
Con el módulo de
subprocess
. Usamos esto cuando específicamente queremos probar el manejo de los argumentos de línea de comando. Ver http://hg.python.org/cpython/file/default/Lib/test/test_cmd_line_script.py para varios ejemplos.
Este código no se ejecuta en Python 2.7. Ver http://stackoverflow.com/questions/3423601/python-2-7-exec-what-is-wrong. Lo hice funcionar usando la clase StringIO del __module__ StringIO. –
- 1. variables en las secuencias de comandos TOAD
- 2. Fundamentos de las secuencias de comandos de MongoDB - Cómo
- 3. ¿Cómo integrar las secuencias de comandos de Sikuli en Selenium?
- 4. Xcode objetivo de secuencias de comandos de Python Fase
- 5. Notificaciones de escritorio de las secuencias de comandos de contenido
- 6. Detección estática de errores en las secuencias de comandos Tcl
- 7. $ * en secuencias de comandos bash
- 8. ¿Cómo se ejecutan las secuencias de comandos de Python en Windows?
- 9. ¿Cómo se pueden depurar las secuencias de comandos o servicios python de forma remota?
- 10. ¿Cómo se configuran las secuencias de comandos de Python para que funcionen en Apache 2.0?
- 11. Complemento de secuencias de comandos Javascript/plugins?
- 12. ¿Esperan las secuencias de comandos todavía vale la pena aprender?
- 13. ¿Cómo pasar el parámetro a las secuencias de comandos ant?
- 14. ALINEAR en las secuencias de comandos del enlazador
- 15. ¿Cómo ejecuto las secuencias de comandos de Groovy como Java desde la línea de comandos?
- 16. C# lenguaje de secuencias de comandos
- 17. ¿Cómo hacer que las secuencias de comandos python sean ejecutables en Windows?
- 18. Mejor práctica: Secuencias de comandos cruzadas legítimas
- 19. Secuencias de comandos eliminadas con jQuery .load
- 20. Prevención de secuencias de comandos del lado del servidor, XSS
- 21. Ejecutar secuencias de comandos R desde VBA
- 22. generar secuencias de comandos Sin Fecha
- 23. Obsesión con secuencias de comandos sin bloqueo
- 24. ¿Cómo hacer que las secuencias de comandos se eliminen automáticamente al final de la ejecución?
- 25. ¿Hay alguna herramienta para verificar las secuencias de comandos de Perl para uso innecesario?
- 26. Consigue desplazamiento de búfer en vim (en particular, a través de secuencias de comandos de Python)
- 27. secuencias de comandos de ejecución en C++ aplicación
- 28. Cómo reducir el uso de la memoria de secuencias de comandos de Python
- 29. Base de datos de secuencias de comandos SQL-Server
- 30. Depuración de secuencias de comandos de UIAutomation en Instruments
doctest ya sabe cómo manejar la salida ... –
Primero. Búsqueda: http://stackoverflow.com/questions/3481561/python-using-doctest-on-the-mainline. Segundo. Buscar: la documentación más doctest (http://docs.python.org/library/doctest.html#how-are-docstring-examples-recognized) dice "La salida a stdout se captura, pero no a stderr". –