¿Escribir pruebas automatizadas para los complementos de QGIS?

14

Estoy buscando consejos sobre cómo escribir pruebas automáticas para los complementos de QGIS escritos en Python.

He escrito pruebas para scripts de Python en el pasado usando PyUnit (el módulo unittest ), pero nunca lo he hecho para una aplicación con una GUI. He encontrado una página que describe cómo usar PyQt4.QTest para realizar pruebas unitarias en widgets Qt ( enlace ), pero estoy luchando para ver cómo puedo usar esto con un widget que ha sido diseñado para ejecutarse desde dentro de QGIS.

La sección sobre "Pruebas" en documentación de PyQGIS está notablemente ausente.

Lo que tengo hasta ahora es:

  • Mantenga el procesamiento real de los datos en módulos o funciones aisladas, y escriba pruebas unitarias para ellos;
  • Realice pruebas básicas de la interfaz de usuario utilizando QTest;
  • Ore para que todo se mantenga unido cuando se usa el complemento desde QGIS.

¿Hay una mejor manera?

    
pregunta Snorfalorpagus 11.09.2013 - 20:11

4 respuestas

10

Las capacidades para probar los complementos de QGIS (particularmente la cuestión de las pruebas de integración, dentro de un entorno QGIS, como se destaca en el OP) han mejorado mucho recientemente. Por lo tanto, espero que esta actualización ayude a los lectores contemporáneos, así como al OP.

Boundless publicó un artículo de lectura obligatoria en julio de 2016 para cualquier persona que quiera automatizar la prueba de los complementos de QGIS con derecho; Entorno de prueba de integración continua de QGIS para complementos de Python . Describe el enfoque y las herramientas que utilizan, todos los cuales son de código abierto. Los aspectos clave son: -

  • Su especial comprobador de complementos QGIS que puede automatizar las pruebas dentro del entorno QGIS
  • El uso de docker imágenes de QGIS, lo que permite realizar pruebas con varias versiones / configuraciones de QGIS en un entorno de base de contenedor
  • Una imagen QGIS de la ventana acoplable especial , que se utiliza para probar QGIS en sí, pero que invoca qgis_testrunner.sh se puede usar para ejecutar pruebas unitarias en un complemento
  • El uso de Travis CI para la integración continua, es decir, el conjunto completo de pruebas se ejecuta con cada nuevo código confirmado

Si está familiarizado con Travis CI / docker, debería ser relativamente fácil de configurar. Describen los siguientes 4 pasos y proporcionan 2 ejemplos de sus propios complementos configurados de esta manera.

  1. Tire de la imagen de Docker con el entorno de prueba de QGIS y ejecútelo
  2. Ejecute qgis_setup.sh NameOfYourPlugin para instalar el complemento y preparar QGIS para el corredor de prueba
  3. Opcionalmente, realice todas las operaciones necesarias para compilar su complemento
  4. Ejecuta el corredor de prueba dentro del Docker invocando el qgis_testrunner.sh

Solicitaste las mejores prácticas & A partir de hoy ciertamente lo consideraría. Los documentos de QGIS aún no tienen una sección dedicada a las pruebas de complementos (espero que esto cambie pronto), pero el enfoque "Oremos para que todo se mantenga unido" ya no es la única opción.

    
respondido por el MatzFan 18.09.2016 - 17:55
7

Parece que esto es posible usar unittest para probar los complementos de Python cargados en un aplicación de Python independiente .

qgis.core.iface no está disponible en aplicaciones independientes, por lo que escribí una instancia ficticia que devuelve una función que acepta cualquier argumento que se le presente y no hace nada más. Esto significa que las llamadas como self.iface.addToolBarIcon(self.action) no generan errores.

El siguiente ejemplo carga un complemento myplugin , que tiene algunos menús desplegables con nombres de capa tomados del registro de la capa del mapa. Las pruebas verifican si los menús se han llenado correctamente y se pueden interactuar con ellos. No estoy seguro de si esta es la mejor manera de cargar el complemento, pero parece funcionar.

#!/usr/bin/envpythonimportunittestimportosimportsys#configurepythontoplaynicelywithqgisosgeo4w_root=r'C:/OSGeo4W'os.environ['PATH']='{}/bin{}{}'.format(osgeo4w_root,os.pathsep,os.environ['PATH'])sys.path.insert(0,'{}/apps/qgis/python'.format(osgeo4w_root))sys.path.insert(1,'{}/apps/python27/lib/site-packages'.format(osgeo4w_root))#importQtfromPyQt4importQtCore,QtGui,QtTestfromPyQt4.QtCoreimportQt#importPyQGISfromqgis.coreimport*fromqgis.guiimport*#disabledebugmessagesos.environ['QGIS_DEBUG']='-1'defsetUpModule():#loadqgisprovidersQgsApplication.setPrefixPath('{}/apps/qgis'.format(osgeo4w_root),True)QgsApplication.initQgis()globals()['shapefile_path']='D:/MasterMap.shp'#FIXME:thisseemstothrowerrors#deftearDownModule():#QgsApplication.exitQgis()#dummyinstancetoreplaceqgis.utils.ifaceclassQgisInterfaceDummy(object):def__getattr__(self,name):#returnanfunctionthatacceptsanyargumentsanddoesnothingdefdummy(*args,**kwargs):returnNonereturndummyclassExamplePluginTest(unittest.TestCase):defsetUp(self):#createanewapplicationinstanceself.app=app=QtGui.QApplication(sys.argv)#createamapcanvaswidgetself.canvas=canvas=QgsMapCanvas()canvas.setCanvasColor(QtGui.QColor('white'))canvas.enableAntiAliasing(True)#loadashapefilelayer=QgsVectorLayer(shapefile_path,'MasterMap','ogr')#addthelayertothecanvasandzoomtoitQgsMapLayerRegistry.instance().addMapLayer(layer)canvas.setLayerSet([QgsMapCanvasLayer(layer)])canvas.setExtent(layer.extent())#displaythemapcanvaswidget#canvas.show()iface=QgisInterfaceDummy()#importtheplugintobetestedimportmypluginself.plugin=myplugin.classFactory(iface)self.plugin.initGui()self.dlg=self.plugin.dlg#self.dlg.show()deftest_populated(self):'''Arethecomboboxespopulatedcorrectly?'''self.assertEqual(self.dlg.ui.comboBox_raster.currentText(),'')self.assertEqual(self.dlg.ui.comboBox_vector.currentText(),'MasterMap')self.assertEqual(self.dlg.ui.comboBox_all1.currentText(),'')self.dlg.ui.comboBox_all1.setCurrentIndex(1)self.assertEqual(self.dlg.ui.comboBox_all1.currentText(),'MasterMap')deftest_dlg_name(self):self.assertEqual(self.dlg.windowTitle(),'Testing')deftest_click_widget(self):'''TheOKbuttonshouldclosethedialog'''self.dlg.show()self.assertEqual(self.dlg.isVisible(),True)okWidget=self.dlg.ui.buttonBox.button(self.dlg.ui.buttonBox.Ok)QtTest.QTest.mouseClick(okWidget,Qt.LeftButton)self.assertEqual(self.dlg.isVisible(),False)deftearDown(self):self.plugin.unload()del(self.plugin)del(self.app)#donotforgetthisif__name__=="__main__":
    unittest.main()
    
respondido por el Snorfalorpagus 12.09.2013 - 16:38
2

También puse un DummyInterface en conjunto, lo que le permite probar los complementos de QGIS de forma independiente. Después de leer el blog Snorfalorpagus, consulte mi respuesta aquí .

Para encontrar un ejemplo de la vida real, sobre cómo pruebo (ed) los complementos de QGIS, visite este proyecto github en enlace y eche un vistazo a tests -package

    
respondido por el Kim 27.04.2015 - 17:49
-1

Esto podría ayudar: Prueba las GUI de PyQt con QTest y unittest enlace

    
respondido por el Stefan 12.09.2013 - 00:26

Lea otras preguntas en las etiquetas