mirror of
https://github.com/qgis/QGIS.git
synced 2025-11-22 00:14:55 -05:00
239 lines
6.6 KiB
Markdown
239 lines
6.6 KiB
Markdown
Algorithm tests
|
||
===============
|
||
|
||
To test QGIS Processing algorithms, YAML-based test cases are defined in the following files:
|
||
|
||
- `qgis_algorithm_tests1.yaml` through `qgis_algorithm_tests5.yaml` – QGIS core algorithm tests
|
||
- `gdal_algorithm_vector_tests.yaml` – GDAL vector-related tests
|
||
- `gdal_algorithm_raster_tests.yaml` – GDAL raster-related tests
|
||
- `script_algorithm_tests.yaml` – Custom script-based tests
|
||
|
||
All of these files are located in: `python/plugins/processing/tests/testdata/`
|
||
|
||
This file is structured with [yaml syntax](https://yaml.org/).
|
||
|
||
A basic test appears under the toplevel key `tests` and looks like this:
|
||
|
||
```yaml
|
||
- name: centroid
|
||
algorithm: qgis:polygoncentroids
|
||
params:
|
||
- type: vector
|
||
name: polys.gml
|
||
results:
|
||
OUTPUT_LAYER:
|
||
type: vector
|
||
name: expected/polys_centroid.gml
|
||
```
|
||
|
||
How To
|
||
------
|
||
To add a new test for a QGIS Processing algorithm, follow these steps:
|
||
|
||
### 1. Run the Algorithm in QGIS
|
||
|
||
- Use the **Processing Toolbox** to run the algorithm you want to test.
|
||
- For **vector outputs**, prefer using **GML format with XSD** — this format supports mixed geometry types and offers good readability.
|
||
- Save the output to: `python/plugins/processing/tests/testdata/expected/`
|
||
- For input layers, reuse data already present in: `python/plugins/processing/tests/testdata/`
|
||
|
||
If additional data is required, place it under: `python/plugins/processing/tests/testdata/custom/`
|
||
|
||
### 2. Generate the Test Definition
|
||
|
||
- Open **Processing ► History** after running the algorithm.
|
||
- Locate your algorithm run, right-click it, and select **Create Test**.
|
||
- A new window will appear with the YAML test definition.
|
||
|
||
### 3. Add the Test to the Appropriate File
|
||
|
||
Paste the test definition into the correct YAML file inside: `python/plugins/processing/tests/testdata/`
|
||
|
||
Use the following guidelines:
|
||
- `qgis_algorithm_tests1.yaml` to `qgis_algorithm_tests5.yaml`: QGIS core algorithms
|
||
- `gdal_algorithm_vector_tests.yaml`: GDAL vector-related algorithms
|
||
- `gdal_algorithm_raster_tests.yaml`: GDAL raster-related algorithms
|
||
- `script_algorithm_tests.yaml`: Custom script-based tests
|
||
|
||
### 4. Example YAML Test Entry
|
||
|
||
```yaml
|
||
- name: densify
|
||
algorithm: qgis:densifygeometriesgivenaninterval
|
||
params:
|
||
- type: vector
|
||
name: polys.gml
|
||
- 2 # Interval
|
||
results:
|
||
OUTPUT:
|
||
type: vector
|
||
name: expected/polys_densify.gml
|
||
```
|
||
### 5. Adding Script-Based Tests
|
||
To create tests for custom Processing scripts:
|
||
- Place the script file in the following directory: `python/plugins/processing/tests/testdata/scripts/`
|
||
- The script file name must exactly match the script algorithm name used in your test definition.
|
||
|
||
For example, if your test refers to an algorithm named my_custom_buffer, your script should be saved as: `python/plugins/processing/tests/testdata/scripts/my_custom_buffer.py`
|
||
|
||
Params and results
|
||
------------------
|
||
|
||
### Trivial type parameters
|
||
|
||
Params and results are specified as lists or dictionaries:
|
||
|
||
```yaml
|
||
params:
|
||
INTERVAL: 5
|
||
INTERPOLATE: True
|
||
NAME: A processing test
|
||
```
|
||
|
||
or
|
||
|
||
```yaml
|
||
params:
|
||
- 2
|
||
- string
|
||
- another param
|
||
```
|
||
|
||
### Layer type parameters
|
||
|
||
You will often need to specify layers as parameters. To specify a layer you will need to specify:
|
||
|
||
* the type
|
||
* `vector` or `raster`
|
||
* a name
|
||
* relative path like `expected/polys_centroid.gml`
|
||
|
||
This is what it looks like in action:
|
||
|
||
```yaml
|
||
params:
|
||
PAR: 2
|
||
STR: string
|
||
LAYER:
|
||
type: vector
|
||
name: polys.gml
|
||
OTHER: another param
|
||
```
|
||
|
||
### File type parameters
|
||
|
||
If you need an external file for the algorithm test, you need to specify the 'file' type and the (relative) path to the file in its 'name':
|
||
|
||
```yaml
|
||
params:
|
||
PAR: 2
|
||
STR: string
|
||
EXTFILE:
|
||
type: file
|
||
name: custom/grass7/extfile.txt
|
||
OTHER: another param
|
||
```
|
||
|
||
### Results
|
||
|
||
Results are specified very similar.
|
||
|
||
#### Basic vector files
|
||
|
||
It couldn't be more trivial
|
||
|
||
```yaml
|
||
OUTPUT:
|
||
name: expected/qgis_intersection.gml
|
||
type: vector
|
||
```
|
||
|
||
Add the expected GML and XSD in the folder.
|
||
|
||
#### Vector with tolerance
|
||
|
||
Sometimes different platforms create slightly different results which are
|
||
still acceptable. In this case (but only then) you may also use additional
|
||
properties to define how exactly a layer is compared.
|
||
|
||
To deal with a certain tolerance for output values you can specify a
|
||
`compare` property for an output. The compare property can contain sub-properties
|
||
for `fields`. This contains information about how precisely a certain field is
|
||
compared (`precision`) or a field can even entirely be `skip`ed. There is a special
|
||
field name `__all__` which will apply a certain tolerance to all fields.
|
||
There is another property `geometry` which also accepts a `precision` which is
|
||
applied to each vertex.
|
||
|
||
```yaml
|
||
OUTPUT:
|
||
type: vector
|
||
name: expected/abcd.gml
|
||
compare:
|
||
fields:
|
||
__all__:
|
||
precision: 5 # compare to a precision of .00001 on all fields
|
||
A: skip # skip field A
|
||
geometry:
|
||
precision: 5 # compare coordinates with a precision of 5 digits
|
||
```
|
||
|
||
#### Raster files
|
||
|
||
Raster files are compared with a hash checksum. This is calculated when you create
|
||
a test from the processing history.
|
||
|
||
```yaml
|
||
OUTPUT:
|
||
type: rasterhash
|
||
hash: f1fedeb6782f9389cf43590d4c85ada9155ab61fef6dc285aaeb54d6
|
||
```
|
||
|
||
#### Files
|
||
|
||
You can compare the content of an output file by an expected result reference file
|
||
|
||
```yaml
|
||
OUTPUT_HTML_FILE:
|
||
name: expected/basic_statistics_string.html
|
||
type: file
|
||
```
|
||
|
||
Or you can use one or more regular expressions that will be [matched](https://docs.python.org/3/library/re.html#re.search) against the file
|
||
content
|
||
|
||
```yaml
|
||
OUTPUT:
|
||
name: layer_info.html
|
||
type: regex
|
||
rules:
|
||
- 'Extent: \(-1.000000, -3.000000\) - \(11.000000, 5.000000\)'
|
||
- 'Geometry: Line String'
|
||
- 'Feature Count: 6'
|
||
```
|
||
|
||
#### Directories
|
||
|
||
You can compare the content of an output directory with an 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
|
||
ctest -V -R ProcessingQgisAlgorithmsTest
|
||
```
|
||
or one of the following value listed in the [CMakelists.txt](https://github.com/qgis/QGIS/blob/master/python/plugins/processing/tests/CMakeLists.txt)
|