python, unittest: hay una manera de pasar las opciones de la línea de comandos a la aplicación

Tengo un módulo que importa unittest y tiene algunos TestCases. Me gustaría aceptar algunas opciones de línea de comandos (por ejemplo, a continuación, el nombre de un archivo de datos), pero cuando bash pasar la opción, aparece el mensaje “opción -i no reconocida”. ¿Es posible que unittest + proporcione opciones a la aplicación (nota: estoy usando optparse para manejar las opciones)? Gracias.

$ python test_app_data.py -i data_1.txt option -i not recognized 

=====================

seguimiento: esta es una implementación de la solución sugerida:

 import cfg_master #has the optparse option-handling code ... if __name__ == '__main__': #add you app's options here... options_tpl = ('-i', '--in_dir', '-o', '--out_dir') del_lst = [] for i,option in enumerate(sys.argv): if option in options_tpl: del_lst.append(i) del_lst.append(i+1) del_lst.reverse() for i in del_lst: del sys.argv[i] unittest.main() 

Sobre la base de la respuesta de Alex, en realidad es bastante fácil hacerlo usando argparse :

 if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument('--input', default='My Input') parser.add_argument('filename', default='some_file.txt') parser.add_argument('unittest_args', nargs='*') args = parser.parse_args() # TODO: Go do something with args.input and args.filename # Now set the sys.argv to the unittest_args (leaving sys.argv[0] alone) sys.argv[1:] = args.unittest_args unittest.main() 

No he probado todas las banderas que puedes pasar a unittest para ver si funcionan o no, pero el pasar los nombres de las pruebas funciona, por ejemplo:

 python test.py --input=foo data.txt MyTest 

Ejecuta MyTest con foo y data.txt .

En su sección if __name__ == '__main__': que no nos está mostrando, deberá optparse por optparse y luego del sys.argv[1:] antes de pasar el control al código de optparse de optparse , para que el último código no lo haga No intentes volver a interpretar las opciones de la línea de comandos cuando ya las hayas tratado. (Es un poco más difícil tener algunas opciones propias y también transmitirlas a unittest , aunque se puede hacer si tiene necesidades tan complejas).

Para aplicaciones pequeñas independientes, uso una opción inicial de centinela (-t) y llamo a unittest.main () antes de llamar a argparse.ArgumentParser ()

 if __name__ == "__main__": if len(sys.argv) > 1 and sys.argv[1] in ["-t", "--test"]: del(sys.argv[1]) sys.exit(unittest.main()) # pass sys.argv[ p = argparse.ArgumentParser() . . . 

Pensé que compartiría mi solución para agregar un interruptor –debug a la prueba para controlar el registrador:

 if __name__=='__main__': parser = argparse.ArgumentParser(description="Build a comstacktion script") parser.add_argument('--debug', help='Turn on debug messages', action='store_true', default=False) args = parser.parse_args() if args.debug: log_level = logging.DEBUG else: log_level = logging.INFO logging.basicConfig(level=log_level) sys.argv.pop() unittest.main() 

Luego extendí unittest.TestCase para agregar el registro:

  class mcs_TestCase(unittest.TestCase, object): def __init__(self, *args, **kwargs): super(mcs_TestCase,self).__init__(*args,**kwargs) logging.basicConfig() self.logger = logging.getLogger(__name__) ... 

Ahora puedo activar y desactivar los mensajes en mi prueba usando –debug, pero se ignora en las regresiones regulares.

No debe tomar argumentos y opciones para ejecutar pruebas de unidad, ya que los hace funcionar en condiciones diferentes y menos predecibles de esta manera. Debería averiguar por qué necesita ejecutar pruebas con datos diferentes y hacer que su conjunto de pruebas sea lo suficientemente completo como para abarcar todos los conjuntos de datos sin que se ejecuten de manera diferente cada vez.