Skip to content

Commit

Permalink
Merge pull request #2761 from m-kuhn/ptest
Browse files Browse the repository at this point in the history
Updates to processing tests
  • Loading branch information
m-kuhn committed Feb 23, 2016
2 parents 50aa805 + 5f0173e commit 8582f61
Show file tree
Hide file tree
Showing 22 changed files with 210 additions and 2,660 deletions.
1 change: 1 addition & 0 deletions ci/travis/linux/before_install.sh
Expand Up @@ -11,6 +11,7 @@ sudo apt-get install --force-yes --no-install-recommends --no-install-suggests \
cmake-data \ cmake-data \
doxygen \ doxygen \
flex \ flex \
gdal-bin \
git \ git \
graphviz \ graphviz \
grass-dev \ grass-dev \
Expand Down
10 changes: 5 additions & 5 deletions python/plugins/processing/gui/TestTools.py
Expand Up @@ -102,7 +102,7 @@ def createTest(text):
definition['name'] = 'Test ({})'.format(cmdname) definition['name'] = 'Test ({})'.format(cmdname)
definition['algorithm'] = cmdname definition['algorithm'] = cmdname


params = [] params = {}
results = {} results = {}


i = 0 i = 0
Expand All @@ -123,7 +123,7 @@ def createTest(text):
if not schema: if not schema:
p['location'] = '[The source data is not in the testdata directory. Please use data in the processing/tests/testdata folder.]' p['location'] = '[The source data is not in the testdata directory. Please use data in the processing/tests/testdata folder.]'


params.append(p) params[param.name] = p
elif isinstance(param, ParameterRaster): elif isinstance(param, ParameterRaster):
filename = token[1:-1] filename = token[1:-1]
schema, filepath = extractSchemaPath(filename) schema, filepath = extractSchemaPath(filename)
Expand All @@ -134,7 +134,7 @@ def createTest(text):
if not schema: if not schema:
p['location'] = '[The source data is not in the testdata directory. Please use data in the processing/tests/testdata folder.]' p['location'] = '[The source data is not in the testdata directory. Please use data in the processing/tests/testdata folder.]'


params.append(p) params[param.name] = p
elif isinstance(param, ParameterMultipleInput): elif isinstance(param, ParameterMultipleInput):
multiparams = token[1:-1].split(';') multiparams = token[1:-1].split(';')
newparam = [] newparam = []
Expand All @@ -151,9 +151,9 @@ def createTest(text):
if not schema: if not schema:
p['location'] = '[The source data is not in the testdata directory. Please use data in the processing/tests/testdata folder.]' p['location'] = '[The source data is not in the testdata directory. Please use data in the processing/tests/testdata folder.]'


params.append(p) params[param.name] = p
else: else:
params.append(token) params[param.name] = token


definition['params'] = params definition['params'] = params


Expand Down
Expand Up @@ -2,7 +2,7 @@


""" """
*************************************************************************** ***************************************************************************
test_algorithms.py AlgorithmsTest.py
--------------------- ---------------------
Date : January 2016 Date : January 2016
Copyright : (C) 2016 by Matthias Kuhn Copyright : (C) 2016 by Matthias Kuhn
Expand All @@ -27,12 +27,12 @@


import qgis import qgis
import os import os
import shutil
import yaml import yaml
import nose2 import nose2
import gdal import gdal
import hashlib import hashlib
import tempfile import tempfile
import re


from osgeo.gdalconst import GA_ReadOnly from osgeo.gdalconst import GA_ReadOnly


Expand All @@ -46,11 +46,6 @@
QgsMapLayerRegistry QgsMapLayerRegistry
) )


from qgis.testing import (
start_app,
unittest
)

from utilities import ( from utilities import (
unitTestDataPath unitTestDataPath
) )
Expand All @@ -60,25 +55,13 @@ def processingTestDataPath():
return os.path.join(os.path.dirname(__file__), 'testdata') return os.path.join(os.path.dirname(__file__), 'testdata')




class TestAlgorithms(unittest.TestCase): class AlgorithmsTest():

@classmethod
def setUpClass(cls):
start_app()
from processing.core.Processing import Processing
Processing.initialize()
cls.cleanup_paths = []

@classmethod
def tearDownClass(cls):
for path in cls.cleanup_paths:
shutil.rmtree(path)


def test_algorithms(self): def test_algorithms(self):
""" """
This is the main test function. All others will be executed based on the definitions in testdata/algorithm_tests.yaml This is the main test function. All others will be executed based on the definitions in testdata/algorithm_tests.yaml
""" """
with open(os.path.join(processingTestDataPath(), 'algorithm_tests.yaml'), 'r') as stream: with open(os.path.join(processingTestDataPath(), self.test_definition_file()), 'r') as stream:
algorithm_tests = yaml.load(stream) algorithm_tests = yaml.load(stream)


for algtest in algorithm_tests['tests']: for algtest in algorithm_tests['tests']:
Expand All @@ -104,8 +87,8 @@ def check_algorithm(self, name, defs):
for r, p in defs['results'].iteritems(): for r, p in defs['results'].iteritems():
alg.setOutputValue(r, self.load_result_param(p)) alg.setOutputValue(r, self.load_result_param(p))


self.assertTrue(AlgorithmExecutor.runalg(alg))
print(alg.getAsCommand()) print(alg.getAsCommand())
self.assertTrue(AlgorithmExecutor.runalg(alg))
self.check_results(alg.getOutputValuesAsDictionary(), defs['results']) self.check_results(alg.getOutputValuesAsDictionary(), defs['results'])


def load_params(self, params): def load_params(self, params):
Expand Down Expand Up @@ -133,21 +116,27 @@ def load_param(self, param):
# No type specified, use whatever is there # No type specified, use whatever is there
return param return param


raise KeyError("Unknown type '{}' specified for parameter '{}'".format(param['type'], param['name'])) raise KeyError("Unknown type '{}' specified for parameter".format(param['type']))


def load_result_param(self, param): def load_result_param(self, param):
""" """
Loads a result parameter. Creates a temporary destination where the result should go to and returns this location Loads a result parameter. Creates a temporary destination where the result should go to and returns this location
so it can be sent to the algorithm as parameter. so it can be sent to the algorithm as parameter.
""" """
if param['type'] in ['vector', 'file']: if param['type'] in ['vector', 'file', 'regex']:
outdir = tempfile.mkdtemp() outdir = tempfile.mkdtemp()
self.cleanup_paths.append(outdir) self.cleanup_paths.append(outdir)
basename = os.path.basename(param['name']) basename = os.path.basename(param['name'])
filepath = os.path.join(outdir, basename) filepath = os.path.join(outdir, basename)
return filepath return filepath
elif param['type'] == 'rasterhash':
outdir = tempfile.mkdtemp()
self.cleanup_paths.append(outdir)
basename = 'raster.tif'
filepath = os.path.join(outdir, basename)
return filepath


raise KeyError("Unknown type '{}' specified for parameter '{}'".format(param['type'], param['name'])) raise KeyError("Unknown type '{}' specified for parameter".format(param['type']))


def load_layer(self, param): def load_layer(self, param):
""" """
Expand Down Expand Up @@ -188,10 +177,7 @@ def check_results(self, results, expected):


result_lyr = QgsVectorLayer(results[id], id, 'ogr') result_lyr = QgsVectorLayer(results[id], id, 'ogr')


try: compare = expected_result.get('compare', {})
compare = expected_result['compare']
except KeyError:
compare = {}


self.assertLayersEqual(expected_lyr, result_lyr, compare=compare) self.assertLayersEqual(expected_lyr, result_lyr, compare=compare)


Expand All @@ -205,6 +191,12 @@ def check_results(self, results, expected):
result_filepath = results[id] result_filepath = results[id]


self.assertFilesEqual(expected_filepath, result_filepath) self.assertFilesEqual(expected_filepath, result_filepath)
elif 'regex' == expected_result['type']:
with open(results[id], 'r') as file:
data = file.read()

for rule in expected_result.get('rules', []):
self.assertRegexpMatches(data, rule)




if __name__ == '__main__': if __name__ == '__main__':
Expand Down
3 changes: 2 additions & 1 deletion python/plugins/processing/tests/CMakeLists.txt
Expand Up @@ -7,5 +7,6 @@ PLUGIN_INSTALL(processing tests/data ${TEST_DATA_FILES})
IF(ENABLE_TESTS) IF(ENABLE_TESTS)
INCLUDE(UsePythonTest) INCLUDE(UsePythonTest)
ADD_PYTHON_TEST(ProcessingParametersTest ParametersTest.py) ADD_PYTHON_TEST(ProcessingParametersTest ParametersTest.py)
ADD_PYTHON_TEST(ProcessingAlgorithmsTest AlgorithmsTest.py) ADD_PYTHON_TEST(ProcessingQgisAlgorithmsTest QgisAlgorithmsTest.py)
ADD_PYTHON_TEST(ProcessingGdalAlgorithmsTest GdalAlgorithmsTest.py)
ENDIF(ENABLE_TESTS) ENDIF(ENABLE_TESTS)
58 changes: 58 additions & 0 deletions python/plugins/processing/tests/GdalAlgorithmsTest.py
@@ -0,0 +1,58 @@
# -*- coding: utf-8 -*-

"""
***************************************************************************
GdalAlgorithmTests.py
---------------------
Date : January 2016
Copyright : (C) 2016 by Matthias Kuhn
Email : matthias@opengis.ch
***************************************************************************
* *
* 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__ = 'Matthias Kuhn'
__date__ = 'January 2016'
__copyright__ = '(C) 2016, Matthias Kuhn'

# This will get replaced with a git SHA1 when you do a git archive

__revision__ = ':%H$'

import AlgorithmsTestBase

import nose2
import shutil

from qgis.testing import (
start_app,
unittest
)


class TestGdalAlgorithms(unittest.TestCase, AlgorithmsTestBase.AlgorithmsTest):

@classmethod
def setUpClass(cls):
start_app()
from processing.core.Processing import Processing
Processing.initialize()
cls.cleanup_paths = []

@classmethod
def tearDownClass(cls):
for path in cls.cleanup_paths:
shutil.rmtree(path)

def test_definition_file(self):
return 'gdal_algorithm_tests.yaml'


if __name__ == '__main__':
nose2.main()

0 comments on commit 8582f61

Please sign in to comment.