QGIS eklentileri için otomatik testler mi yazıyorsunuz?


16

Python'da yazılmış QGIS eklentileri için otomatik testler yazmayla ilgili tavsiye arıyorum.

Geçmişte PyUnit ( unittestmodül) kullanarak Python betikleri için testler yazdım , ancak GUI'li bir uygulama için hiç yapmadım. Qt widget'larında ( http://www.voom.net/pyqt-qtest-example ) birim testleri yapmak için PyQt4.QTest'in nasıl kullanılacağını açıklayan bir sayfa buldum , ancak bunu nasıl kullanabileceğimi görmek için mücadele ediyorum QGIS içinden çalışacak şekilde tasarlanmış bir widget ile.

PyQGIS belgelerindeki "Test" bölümü özellikle yoktur.

Şimdiye kadar sahip olduğum şey:

  • İzole edilmiş modüllerde veya fonksiyonlarda verilerin gerçek işlenmesini sağlayın ve bunlar için birim testleri yazın;
  • QTest kullanarak UI'nin temel testlerini yapın;
  • QGIS içindeki eklentiyi kullanırken her şeyin bir arada kalması için dua edin.

Daha iyi bir yol var mı?

Yanıtlar:


11

QGIS eklentilerini test etme yetenekleri (özellikle OP'nin vurguladığı gibi bir QGIS ortamında entegrasyon testi sorunu) son zamanlarda büyük ölçüde iyileşti. Bu nedenle bu güncellemenin OP'ye olduğu kadar çağdaş okuyuculara da yardımcı olacağını umuyorum.

Sınırsız , QGIS eklentilerinin testini otomatik hale getirme konusunda ciddi olan herkes için Temmuz 2016'da okunması gereken bir makale yayınladı; Python Eklentileri için QGIS Sürekli Entegrasyon Test Ortamı . Hepsi açık kaynak olan kullandıkları yaklaşımı ve araçları açıklar. Temel hususlar: -

  • Onların özel test eklentisi QGIS testleri otomatik hale getirebilirsiniz içeride QGIS ortamında
  • Konteyner tabanlı bir ortamda çeşitli QGIS sürümlerine / yapılandırmalarına karşı test yapılmasına izin veren liman işçisi QGIS görüntülerinin kullanımı
  • Bir özel docker QGIS görüntü QGIS kendisi test etmek için kullanılır, fakat bu - çağırarak qgis_testrunner.shbir eklentiye birim testler için kullanılabilir
  • Travis CI'nin sürekli entegrasyon için kullanımı - yani tam test paketi her yeni kod taahhüdüyle çalıştırılır

Travis CI / docker'ı biliyorsanız, kurulumu nispeten kolay olmalıdır. Aşağıdaki 4 adımı açıklarlar ve bu şekilde oluşturulan kendi eklentilerinin 2 örneğini sunarlar.

  1. Docker görüntüsünü QGIS test ortamıyla çekin ve çalıştırın
  2. Eklentiyi yüklemek için qgis_setup.sh NameOfYourPlugin komutunu çalıştırın ve test çalıştırıcısı için QGIS hazırlayın
  3. İsteğe bağlı olarak eklentinizi oluşturmak için gereken tüm işlemleri gerçekleştirin
  4. Docker'ın içindeki test çalıştırıcısını qgis_testrunner.sh

En iyi uygulamayı istediniz ve bugün itibariyle bunu kesinlikle düşünürdüm. QGIS belgeleri hala eklenti testi konusunda özel bir bölüme sahip değil (bunun kısa bir süre içinde değişeceğini umuyorum), ancak "Her şeyin bir arada tuttuğu dua" yaklaşımı kesinlikle tek seçenek değil.


4
Sınırsız artık yok. Bu içeriği kaydeden var mı?
Pedro Camargo

8

Bunun, bağımsız bir Python uygulamasınaunittest yüklenen Python eklentilerini test etmek için kullanılması mümkün görünüyor .

qgis.core.iface bağımsız uygulamalardan kullanılamaz, bu nedenle kendisine verilen argümanları kabul edecek ve başka bir şey yapamayacak bir işlev döndüren bir kukla örnek yazdım. Bu, çağrıların self.iface.addToolBarIcon(self.action)hata atmadığı anlamına gelir .

Aşağıdaki örnek myplugin, harita katmanı kayıt defterinden alınan katman adlarıyla bazı açılır menülere sahip bir eklenti yükler . Testler, menülerin doğru şekilde yerleştirilip yerleştirilmediğini ve etkileşime girip giremeyeceğini kontrol eder. Bu eklentiyi yüklemek için en iyi yol olup olmadığından emin değilim, ama işe yarıyor gibi görünüyor.

eklentim widget'ı

#!/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()

4
O zamandan beri bu cevaba göre bir makale yazdım: snorf.net/blog/2014/01/04/…
Snorfalorpagus


-1

Bu yardımcı olabilir: PyQt GUI'lerini QTest ve unittest ile test edin http://www.voom.net/pyqt-qtest-example


1
Bu, soruda bağlantısı verilen "bu sayfa" (kuşkusuz çok net değil). Benim sorunum, QGIS katmanları ile dolu açılan kutuları gibi şeylerle çalışmak için tasarlanmış bir arayüzü nasıl test edebilirim.
Snorfalorpagus
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.