Parece que es posible utilizar unittest
para probar plugins de Python cargados en un archivo aplicación Python independiente .
qgis.core.iface no está disponible desde aplicaciones independientes, así que he escrito una instancia ficticia que devuelve una función que aceptará cualquier argumento que se le dé y no hará nada más. Esto significa que las llamadas como self.iface.addToolBarIcon(self.action)
no arrojan errores.
El siguiente ejemplo carga un plugin myplugin
que tiene algunos menús desplegables con nombres de capas tomados del registro de capas de mapas. Las pruebas comprueban si los menús se han rellenado correctamente y se puede interactuar con ellos. No estoy seguro de si esta es la mejor manera de cargar el plugin, pero parece que funciona.
#!/usr/bin/env python
import unittest
import os
import sys
# configure python to play nicely with qgis
osgeo4w_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))
# import Qt
from PyQt4 import QtCore, QtGui, QtTest
from PyQt4.QtCore import Qt
# import PyQGIS
from qgis.core import *
from qgis.gui import *
# disable debug messages
os.environ['QGIS_DEBUG'] = '-1'
def setUpModule():
# load qgis providers
QgsApplication.setPrefixPath('{}/apps/qgis'.format(osgeo4w_root), True)
QgsApplication.initQgis()
globals()['shapefile_path'] = 'D:/MasterMap.shp'
# FIXME: this seems to throw errors
#def tearDownModule():
# QgsApplication.exitQgis()
# dummy instance to replace qgis.utils.iface
class QgisInterfaceDummy(object):
def __getattr__(self, name):
# return an function that accepts any arguments and does nothing
def dummy(*args, **kwargs):
return None
return dummy
class ExamplePluginTest(unittest.TestCase):
def setUp(self):
# create a new application instance
self.app = app = QtGui.QApplication(sys.argv)
# create a map canvas widget
self.canvas = canvas = QgsMapCanvas()
canvas.setCanvasColor(QtGui.QColor('white'))
canvas.enableAntiAliasing(True)
# load a shapefile
layer = QgsVectorLayer(shapefile_path, 'MasterMap', 'ogr')
# add the layer to the canvas and zoom to it
QgsMapLayerRegistry.instance().addMapLayer(layer)
canvas.setLayerSet([QgsMapCanvasLayer(layer)])
canvas.setExtent(layer.extent())
# display the map canvas widget
#canvas.show()
iface = QgisInterfaceDummy()
# import the plugin to be tested
import myplugin
self.plugin = myplugin.classFactory(iface)
self.plugin.initGui()
self.dlg = self.plugin.dlg
#self.dlg.show()
def test_populated(self):
'''Are the combo boxes populated correctly?'''
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')
def test_dlg_name(self):
self.assertEqual(self.dlg.windowTitle(), 'Testing')
def test_click_widget(self):
'''The OK button should close the dialog'''
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)
def tearDown(self):
self.plugin.unload()
del(self.plugin)
del(self.app) # do not forget this
if __name__ == "__main__":
unittest.main()