Parece que isso é possível de ser usado unittest
para testar plugins Python carregados em um aplicativo Python independente .
O qgis.core.iface não está disponível em aplicativos independentes, por isso escrevi uma instância fictícia que retorna uma função que aceita qualquer argumento fornecido e não faz mais nada. Isso significa que chamadas como self.iface.addToolBarIcon(self.action)
não geram erros.
O exemplo abaixo carrega um plug-in myplugin
, que possui alguns menus suspensos com nomes de camadas retirados do registro da camada de mapa. Os testes verificam se os menus foram preenchidos corretamente e podem ser interagidos. Não tenho certeza se essa é a melhor maneira de carregar o plugin, mas parece funcionar.
#!/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()