Skip to content
Permalink
Browse files

[labeling] Add local preconfigured test server unit tests class

- Add control images for server output
- Add class for comparison against canvas output
  • Loading branch information
dakcarto committed Aug 21, 2013
1 parent dd26e61 commit 287e0a04a9f563d6817472dc9d522f9814d05df3
@@ -25,7 +25,7 @@ ADD_PYTHON_TEST(PyQgsExpression test_qgsexpression.py)
ADD_PYTHON_TEST(PyQgsPalLabelingBase test_qgspallabeling_base.py)
ADD_PYTHON_TEST(PyQgsPalLabelingCanvas test_qgspallabeling_canvas.py)
#ADD_PYTHON_TEST(PyQgsPalLabelingComposer test_qgspallabeling_composer.py)
#ADD_PYTHON_TEST(PyQgsPalLabelingServer test_qgspallabeling_server.py)
ADD_PYTHON_TEST(PyQgsPalLabelingServer test_qgspallabeling_server.py)
ADD_PYTHON_TEST(PyQgsVectorFileWriter test_qgsvectorfilewriter.py)
ADD_PYTHON_TEST(PyQgsSpatialiteProvider test_qgsspatialiteprovider.py)
ADD_PYTHON_TEST(PyQgsZonalStatistics test_qgszonalstatistics.py)
@@ -23,6 +23,7 @@
import sys
import datetime
import glob
import shutil
import StringIO
import tempfile
from PyQt4.QtCore import *
@@ -36,6 +37,7 @@
QgsMapRenderer,
QgsPalLabeling,
QgsPalLayerSettings,
QgsProject,
QgsProviderRegistry,
QgsVectorLayer,
QgsRenderChecker
@@ -64,6 +66,7 @@ class TestQgsPalLabeling(TestCase):
_PalDataDir = os.path.join(_TestDataDir, 'labeling')
_PalFeaturesDb = os.path.join(_PalDataDir, 'pal_features_v3.sqlite')
_TestFont = TESTFONT
_TestProj = None
_MapRegistry = None
_MapRenderer = None
_Canvas = None
@@ -77,8 +80,7 @@ def setUpClass(cls):
QGISAPP, CANVAS, IFACE, PARENT

# verify that spatialite provider is available
msg = ('\nSpatialite provider not found, '
'SKIPPING TEST SUITE')
msg = '\nSpatialite provider not found, SKIPPING TEST SUITE'
res = 'spatialite' in QgsProviderRegistry.instance().providerList()
assert res, msg

@@ -90,6 +92,7 @@ def setUpClass(cls):
cls._TestGroup = ''
cls._TestGroupPrefix = ''
cls._TestGroupAbbr = ''
cls._TestImage = ''

# initialize class MapRegistry, Canvas, MapRenderer, Map and PAL
cls._MapRegistry = QgsMapLayerRegistry.instance()
@@ -98,10 +101,10 @@ def setUpClass(cls):
cls._Map = cls._Canvas.map()
cls._Map.resize(QSize(600, 400))
cls._MapRenderer = cls._Canvas.mapRenderer()
crs = QgsCoordinateReferenceSystem()
cls._CRS = QgsCoordinateReferenceSystem()
# default for labeling test data sources: WGS 84 / UTM zone 13N
crs.createFromSrid(32613)
cls._MapRenderer.setDestinationCrs(crs)
cls._CRS.createFromSrid(32613)
cls._MapRenderer.setDestinationCrs(cls._CRS)
# use platform's native logical output dpi for QgsMapRenderer on launch

cls._Pal = QgsPalLabeling()
@@ -195,7 +198,7 @@ def settingsDict(lyr):
res[attr] = value
return res

def saveContolImage(self):
def saveContolImage(self, tmpimg=''):
if 'PAL_CONTROL_IMAGE' not in os.environ:
return
testgrpdir = 'expected_' + self._TestGroupPrefix
@@ -208,21 +211,69 @@ def saveContolImage(self):
for f in glob.glob(imgbasepath + '.*'):
if os.path.exists(f):
os.remove(f)
self._Map.render()
self._Canvas.saveAsImage(imgpath)

def renderCheck(self, mismatch=0):
if tmpimg:
if os.path.exists(tmpimg):
shutil.copyfile(tmpimg, imgpath)
else:
self._Map.render()
self._Canvas.saveAsImage(imgpath)

def renderCheck(self, mismatch=0, imgpath='', grpprefix=''):
"""Check rendered map canvas or existing image against control image
mismatch: number of pixels different from control, and still valid check
imgpath: existing image; if present, skips rendering canvas
grpprefix: compare test image/rendering against different test group
"""
if not grpprefix:
grpprefix = self._TestGroupPrefix
chk = QgsRenderChecker()
chk.setControlPathPrefix('expected_' + self._TestGroupPrefix)
chk.setControlPathPrefix('expected_' + grpprefix)
chk.setControlName(self._Test)
chk.setMapRenderer(self._MapRenderer)
res = chk.runTest(self._Test, mismatch)
res = False
if imgpath:
res = chk.compareImages(self._Test, mismatch, str(imgpath))
else:
res = chk.runTest(self._Test, mismatch)
if PALREPORT and not res: # don't report ok checks
testname = self._TestGroup + ' . ' + self._Test
PALREPORTS[testname] = str(chk.report().toLocal8Bit())
msg = '\nRender check failed for "{0}"'.format(self._Test)
return res, msg

def defaultWmsParams(self, projpath, layername):
return {
'SERVICE': 'WMS',
'VERSION': '1.3.0',
'REQUEST': 'GetMap',
'MAP': str(projpath).strip(),
# layer stacking order for rendering: bottom,to,top
'LAYERS': ['background', str(layername).strip()], # or 'name,name'
'STYLES': ',',
'CRS': 'EPSG:32613', # self._CRS, # authid str or QgsCoordinateReferenceSystem obj
'BBOX': '606510,4823130,612510,4827130', # self.aoiExtent(),
'FORMAT': 'image/png', # or: 'image/png; mode=8bit'
'WIDTH': '600',
'HEIGHT': '400',
'DPI': '72',
'MAP_RESOLUTION': '72',
'FORMAT_OPTIONS': 'dpi:72',
'TRANSPARENT': 'FALSE',
'IgnoreGetMapUrl': '1'
}

@classmethod
def setUpServerProjectAndDir(cls, testprojpath, testdir):
cls._TestProj = QgsProject.instance()
cls._TestProj.setFileName(testprojpath)
try:
shutil.copy(cls._PalFeaturesDb, testdir)
for qml in glob.glob(cls._PalDataDir + os.sep + '*.qml'):
shutil.copy(qml, testdir)
except IOError, e:
raise IOError(str(e) + '\nCould not set up test server directory')


class TestPALConfig(TestQgsPalLabeling):

@@ -52,7 +52,7 @@ def tearDown(self):
"""Run after each test."""
pass

def checkTest(self):
def checkTest(self, **kwargs):
self.lyr.writeToLayer(self.layer)
self.saveContolImage()
self.assertTrue(*self.renderCheck())
@@ -0,0 +1,111 @@
# -*- coding: utf-8 -*-
"""QGIS unit tests for QgsPalLabeling: label rendering via QGIS Server
From build dir: ctest -R PyQgsPalLabelingServer -V
Set the following env variables when manually running tests:
PAL_SUITE to run specific tests (define in __main__)
PAL_VERBOSE to output individual test summary
PAL_CONTROL_IMAGE to trigger building of new control images
PAL_REPORT to open any failed image check reports in web browser
.. 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__ = 'Larry Shaffer'
__date__ = '07/12/2013'
__copyright__ = 'Copyright 2013, The QGIS Project'
# This will get replaced with a git SHA1 when you do a git archive
__revision__ = '$Format:%H$'

import sys
import os
from PyQt4.QtCore import *
from PyQt4.QtGui import *

from qgis.core import *

from utilities import (
unittest,
expectedFailure,
)

from test_qgspallabeling_base import TestQgsPalLabeling, runSuite
from test_qgspallabeling_tests import TestPointBase
from qgis_local_server import (QgisLocalServerConfig,
ServerConfigNotAccessibleError)

SERVER = None
TESTPROJDIR = ''
TESTPROJPATH = ''
try:
SERVER = \
QgisLocalServerConfig(str(QgsApplication.qgisSettingsDirPath()), True)
TESTPROJDIR = SERVER.projectDir()
TESTPROJPATH = os.path.join(TESTPROJDIR, 'pal_test.qgs')
except ServerConfigNotAccessibleError, e:
print e


def skipUnlessHasServer(): # skip test class decorator
if SERVER is not None:
return lambda func: func
return unittest.skip('\nConfigured local QGIS Server is not accessible\n\n')


@skipUnlessHasServer()
class TestServerPoint(TestQgsPalLabeling, TestPointBase):

@classmethod
def setUpClass(cls):
TestQgsPalLabeling.setUpClass()
cls.setUpServerProjectAndDir(TESTPROJPATH, TESTPROJDIR)
cls.layer = TestQgsPalLabeling.loadFeatureLayer('background')
cls.layer = TestQgsPalLabeling.loadFeatureLayer('point')
cls.checkmismatch = 1000
cls.checkgroup = ''

def setUp(self):
"""Run before each test."""
self.configTest('pal_server', 'sp')
self.lyr = self.defaultSettings()
self.params = self.defaultWmsParams(TESTPROJPATH, 'point')
self._TestImage = ''

def tearDown(self):
"""Run after each test."""
pass

def checkTest(self, **kwargs):
self.lyr.writeToLayer(self.layer)
# save project file
self._TestProj.write()
# get server results
res, self._TestImage = SERVER.getMap(self.params, False)
self.saveContolImage(self._TestImage)
self.assertTrue(res, 'Failed to retrieve/save image from test server')
# gp = kwargs['grpprefix'] if 'grpprefix' in kwargs else ''
self.assertTrue(*self.renderCheck(mismatch=self.checkmismatch,
imgpath=self._TestImage,
grpprefix=self.checkgroup))


@skipUnlessHasServer()
class TestServerVsCanvasPoint(TestServerPoint):

@classmethod
def setUpClass(cls):
TestServerPoint.setUpClass()
cls.checkgroup = 'pal_canvas'


if __name__ == '__main__':
# NOTE: unless PAL_SUITE env var is set all test class methods will be run
# ex: 'TestGroup(Point|Line|Curved|Polygon|Feature).test_method'
suite = [
'TestServerVsCanvasPoint.test_text_size_map_unit'
]
res = runSuite(sys.modules[__name__], suite)
sys.exit(not res.wasSuccessful())
Binary file not shown.
Binary file not shown.
Binary file not shown.

0 comments on commit 287e0a0

Please sign in to comment.
You can’t perform that action at this time.