看起来可以用来unittest
测试加载到独立Python应用程序中的 Python插件。
qgis.core.iface在独立的应用程序中不可用,因此我编写了一个虚拟实例,该实例返回一个函数,该函数将接受为其提供的任何参数,并且不执行其他任何操作。这意味着像self.iface.addToolBarIcon(self.action)
这样的调用不会引发错误。
以下示例加载了一个插件myplugin
,该插件具有一些下拉菜单,其中的图层名称来自于地图图层注册表。测试将检查菜单是否已正确填充,并且可以进行交互。我不确定这是否是加载插件的最佳方法,但它似乎有效。
#!/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()