Add unit tests for deferred layer refresh

QgsMapCanvas test is rather messy, but I can't find anyway to
avoid showing the canvas in order to get a predictable result
This commit is contained in:
Nyall Dawson 2017-02-07 09:05:48 +10:00
parent 04d392b5a3
commit 9b9d49ade9
4 changed files with 119 additions and 0 deletions

View File

@ -63,6 +63,7 @@ ADD_PYTHON_TEST(PyQgsGraduatedSymbolRenderer test_qgsgraduatedsymbolrenderer.py)
ADD_PYTHON_TEST(PyQgsInterval test_qgsinterval.py)
ADD_PYTHON_TEST(PyQgsJSONUtils test_qgsjsonutils.py)
ADD_PYTHON_TEST(PyQgsLineSymbolLayers test_qgslinesymbollayers.py)
ADD_PYTHON_TEST(PyQgsMapCanvas test_qgsmapcanvas.py)
ADD_PYTHON_TEST(PyQgsMapCanvasAnnotationItem test_qgsmapcanvasannotationitem.py)
ADD_PYTHON_TEST(PyQgsMapLayerModel test_qgsmaplayermodel.py)
ADD_PYTHON_TEST(PyQgsMapRenderer test_qgsmaprenderer.py)

View File

@ -0,0 +1,111 @@
# -*- coding: utf-8 -*-
"""QGIS Unit tests for QgsMapCanvas
.. note:: This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
"""
__author__ = 'Nyall Dawson'
__date__ = '24/1/2017'
__copyright__ = 'Copyright 2017, The QGIS Project'
# This will get replaced with a git SHA1 when you do a git archive
__revision__ = '$Format:%H$'
import qgis # NOQA
from qgis.core import (QgsMapSettings,
QgsCoordinateReferenceSystem,
QgsRectangle,
QgsVectorLayer,
QgsFeature,
QgsGeometry,
QgsMultiRenderChecker,
QgsApplication)
from qgis.gui import (QgsMapCanvas)
from qgis.PyQt.QtCore import (Qt,
QDir)
import time
from qgis.testing import start_app, unittest
app = start_app()
class TestQgsMapCanvas(unittest.TestCase):
def setUp(self):
self.report = "<h1>Python QgsMapCanvas Tests</h1>\n"
def tearDown(self):
report_file_path = "%s/qgistest.html" % QDir.tempPath()
with open(report_file_path, 'a') as report_file:
report_file.write(self.report)
def testDeferredUpdate(self):
""" test that map canvas doesn't auto refresh on deferred layer update """
canvas = QgsMapCanvas()
canvas.setDestinationCrs(QgsCoordinateReferenceSystem(4326))
canvas.setFrameStyle(0)
canvas.resize(600, 400)
self.assertEqual(canvas.width(), 600)
self.assertEqual(canvas.height(), 400)
layer = QgsVectorLayer("Polygon?crs=epsg:4326&field=fldtxt:string",
"layer", "memory")
canvas.setLayers([layer])
canvas.setExtent(QgsRectangle(10, 30, 20, 35))
canvas.show()
# need to wait until first redraw can occur (note that we first need to wait till drawing starts!)
while not canvas.isDrawing():
app.processEvents()
while canvas.isDrawing():
app.processEvents()
self.assertTrue(self.canvasImageCheck('empty_canvas', 'empty_canvas', canvas))
# add polygon to layer
f = QgsFeature()
f.setGeometry(QgsGeometry.fromRect(QgsRectangle(5, 25, 25, 45)))
self.assertTrue(layer.dataProvider().addFeatures([f]))
# deferred update - so expect that canvas will not been refreshed
layer.triggerRepaint(True)
timeout = time.time() + 0.1
while time.time() < timeout:
# messy, but only way to check that canvas redraw doesn't occur
self.assertFalse(canvas.isDrawing())
# canvas should still be empty
self.assertTrue(self.canvasImageCheck('empty_canvas', 'empty_canvas', canvas))
# refresh canvas
canvas.refresh()
while not canvas.isDrawing():
app.processEvents()
while canvas.isDrawing():
app.processEvents()
# now we expect the canvas check to fail (since they'll be a new polygon rendered over it)
self.assertFalse(self.canvasImageCheck('empty_canvas', 'empty_canvas', canvas))
def canvasImageCheck(self, name, reference_image, canvas):
self.report += "<h2>Render {}</h2>\n".format(name)
temp_dir = QDir.tempPath() + '/'
file_name = temp_dir + 'mapcanvas_' + name + ".png"
print(file_name)
canvas.saveAsImage(file_name)
checker = QgsMultiRenderChecker()
checker.setControlPathPrefix("mapcanvas")
checker.setControlName("expected_" + reference_image)
checker.setRenderedImage(file_name)
checker.setColorTolerance(2)
result = checker.runTest(name, 20)
self.report += checker.report()
print((self.report))
return result
if __name__ == '__main__':
unittest.main()

View File

@ -116,6 +116,13 @@ class TestQgsMapRendererCache(unittest.TestCase):
self.assertFalse(cache.hasCacheImage('xxx'))
QgsProject.instance().removeMapLayer(layer.id())
# test that cache is also cleared on deferred update
layer = QgsVectorLayer("Point?field=fldtxt:string",
"layer", "memory")
cache.setCacheImage('xxx', im, [layer])
layer.triggerRepaint(True)
self.assertFalse(cache.hasCacheImage('xxx'))
def testRequestRepaintMultiple(self):
""" test requesting repaint with multiple dependent layers """
layer1 = QgsVectorLayer("Point?field=fldtxt:string",

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB