Tengo un módulo de Python que usa la biblioteca argparse. ¿Cómo escribo pruebas para esa sección de la base del código?
python
unit-testing
argparse
pydanny
fuente
fuente
foo()
se llama a la función ". Burlarsesys.argv
es la respuesta si ese es el caso. Eche un vistazo al paquete Python de cli-test-helpers . Ver también stackoverflow.com/a/58594599/202834Respuestas:
Debería refactorizar su código y mover el análisis a una función:
Luego, en su
main
función, debe llamarlo con:(donde el primer elemento
sys.argv
que representa el nombre del script se elimina para no enviarlo como un interruptor adicional durante la operación CLI).En sus pruebas, puede llamar a la función del analizador con cualquier lista de argumentos con los que desee probarla:
De esta manera, nunca tendrá que ejecutar el código de su aplicación solo para probar el analizador.
Si necesita cambiar y / o agregar opciones a su analizador más adelante en su aplicación, cree un método de fábrica:
Luego puede manipularlo si lo desea, y una prueba podría verse así:
fuente
2
...argparse
no es muy fácil de probar ya que se imprime directamente ensys.stderr
...La "parte argparse" es un poco vaga, por lo que esta respuesta se centra en una parte: el
parse_args
método. Este es el método que interactúa con su línea de comando y obtiene todos los valores pasados. Básicamente, puede burlarse de lo queparse_args
devuelve para que no sea necesario obtener valores de la línea de comando. Elmock
paquete se puede instalar a través de pip para las versiones de python 2.6-3.2. Es parte de la biblioteca estándar a partirunittest.mock
de la versión 3.3 en adelante.Debe incluir todos los argumentos de su método de comando
Namespace
incluso si no se pasan. Dale a esos argumentos un valor deNone
. (vea los documentos ) Este estilo es útil para realizar pruebas rápidamente en casos en los que se pasan valores diferentes para cada argumento de método. Si opta por burlarseNamespace
de la total falta de confianza argparse en sus pruebas, asegúrese de que se comporta de manera similar a laNamespace
clase real .A continuación se muestra un ejemplo con el primer fragmento de la biblioteca argparse.
fuente
argparse
y suNamespace
clase. Deberías burlarteNamespace
.from unittest import mock
ahora es el método de importación correcto, al menos para python3Namespace
clase aquí es exactamente lo que estaba buscando. A pesar de que la prueba aún se basaargparse
, no se basa en la implementación particularargparse
del código bajo prueba, que es importante para las pruebas de mi unidad. Además, es fácil usarpytest
elparametrize()
método para probar rápidamente varias combinaciones de argumentos con una simulación con plantilla que incluyereturn_value=argparse.Namespace(accumulate=accumulate, integers=integers)
.Haga que su
main()
función tomeargv
como argumento en lugar de dejar que se leasys.argv
como lo hará de manera predeterminada :Entonces puedes probar normalmente.
fuente
sys.argv.append()
y luego llameparse()
, verifique los resultados y repita.if __name__ == "__main__":
análisis de llamadas y volcar / evaluar los resultados y luego probar esto desde un archivo por lotes / bash.fuente
No quería modificar el script de publicación original, así que simplemente me
sys.argv
burlé de la parte en argparse.Esto se rompe si la implementación de argparse cambia pero es suficiente para una secuencia de comandos de prueba rápida. La sensibilidad es mucho más importante que la especificidad en los scripts de prueba de todos modos.
fuente
Una forma simple de probar un analizador es:
Otra forma es modificar
sys.argv
y llamarargs = parser.parse_args()
Hay muchos ejemplos de pruebas
argparse
enlib/test/test_argparse.py
fuente
parse_args
lanzaSystemExit
ay imprime en stderr, puedes atrapar ambos:Usted inspecciona stderr (usando
err.seek(0); err.read()
pero en general no se requiere granularidad.Ahora puede usar
assertTrue
o cualquier prueba que desee:Alternativamente, le gustaría atrapar y volver a lanzar un error diferente (en lugar de
SystemExit
):fuente
Cuando paso resultados de
argparse.ArgumentParser.parse_args
a una función, a veces uso anamedtuple
para simular argumentos para la prueba.fuente
Para probar CLI (interfaz de línea de comando), y no salida de comando , hice algo como esto
fuente