diff --git a/python/plugins/processing/tests/AlgorithmsTestBase.py b/python/plugins/processing/tests/AlgorithmsTestBase.py index 62d0df7f8a00..78d39491e57a 100644 --- a/python/plugins/processing/tests/AlgorithmsTestBase.py +++ b/python/plugins/processing/tests/AlgorithmsTestBase.py @@ -86,7 +86,12 @@ def check_algorithm(self, name, defs): :param defs: A python dict containing a test algorithm definition """ self.vector_layer_params = {} - QgsProject.instance().removeAllMapLayers() + QgsProject.instance().clear() + + if 'project' in defs: + full_project_path = os.path.join(processingTestDataPath(), defs['project']) + project_read_success = QgsProject.instance().read(full_project_path) + self.assertTrue(project_read_success, 'Failed to load project file: ' + defs['project']) if 'project_crs' in defs: QgsProject.instance().setCrs(QgsCoordinateReferenceSystem(defs['project_crs'])) @@ -212,6 +217,9 @@ def load_result_param(self, param): basename = 'raster.tif' filepath = os.path.join(outdir, basename) return filepath + elif param['type'] == 'directory': + outdir = tempfile.mkdtemp() + return outdir raise KeyError("Unknown type '{}' specified for parameter".format(param['type'])) @@ -350,6 +358,11 @@ def check_results(self, results, context, params, expected): result_filepath = results[id] self.assertFilesEqual(expected_filepath, result_filepath) + elif 'directory' == expected_result['type']: + expected_dirpath = self.filepath_from_param(expected_result) + result_dirpath = results[id] + + self.assertDirectoriesEqual(expected_dirpath, result_dirpath) elif 'regex' == expected_result['type']: with open(results[id], 'r') as file: data = file.read() diff --git a/python/plugins/processing/tests/README.md b/python/plugins/processing/tests/README.md index db46027f42e4..7b884feb8efe 100644 --- a/python/plugins/processing/tests/README.md +++ b/python/plugins/processing/tests/README.md @@ -194,6 +194,25 @@ OUTPUT: - 'Feature Count: 6' ``` +#### Directories + +You can compare the content of an output directory by en expected result reference directory + +```yaml +OUTPUT_DIR: + name: expected/tiles_xyz/test_1 + type: directory +``` + +### Algorithm Context + +There are few more definitions that can modify context of the algorithm - these can be specified at top level of test: + +- `project` - will load a specified QGIS project file before running the algorithm. If not specified, algorithm will run with empty project +- `project_crs` - overrides the default project CRS - e.g. `EPSG:27700` +- `ellipsoid` - overrides the default project ellipsoid used for measurements - e.g. `GRS80` + + Running tests locally ------------------ ```bash diff --git a/python/testing/__init__.py b/python/testing/__init__.py index 4f648db2b494..fbe5e1c9b688 100644 --- a/python/testing/__init__.py +++ b/python/testing/__init__.py @@ -29,6 +29,7 @@ import sys import difflib import functools +import filecmp from qgis.PyQt.QtCore import QVariant from qgis.core import QgsApplication, QgsFeatureRequest, NULL @@ -196,6 +197,20 @@ def assertFilesEqual(self, filepath_expected, filepath_result): diff = list(diff) self.assertEqual(0, len(diff), ''.join(diff)) + def assertDirectoriesEqual(self, dirpath_expected, dirpath_result): + """ Checks whether both directories have the same content (recursively) and raises an assertion error if not. """ + dc = filecmp.dircmp(dirpath_expected, dirpath_result) + dc.report_full_closure() + + def _check_dirs_equal_recursive(dcmp): + self.assertEqual(dcmp.left_only, []) + self.assertEqual(dcmp.right_only, []) + self.assertEqual(dcmp.diff_files, []) + for sub_dcmp in dcmp.subdirs.values(): + _check_dirs_equal_recursive(sub_dcmp) + + _check_dirs_equal_recursive(dc) + def assertGeometriesEqual(self, geom0, geom1, geom0_id='geometry 1', geom1_id='geometry 2', precision=14, topo_equal_check=False): self.checkGeometriesEqual(geom0, geom1, geom0_id, geom1_id, use_asserts=True, precision=precision, topo_equal_check=topo_equal_check)