A pytest plugin for testing QGIS python plugins.
This plugin makes it easier to write QGIS plugin tests with the help of some fixtures and hooks:
qgis_app
returns and eventually exits fully configuredQgsApplication
. This fixture is called automatically on the start of pytest session.qgis_bot
returns aQgisBot
, which holds common utility methods for interacting with QGIS.qgis_canvas
returnsQgsMapCanvas
.qgis_parent
returns the QWidget used as parent of theqgis_canvas
qgis_iface
returns stubbedQgsInterface
qgis_new_project
makes sure that all the map layers and configurations are removed. This should be used with tests that add stuff toQgsProject
.qgis_processing
initializes the processing framework. This can be used when testing code that callsprocessing.run(...)
.qgis_version
returns QGIS version number as integer.qgis_world_map_geopackage
returns Path to the world_map.gpkg that ships with QGISqgis_countries_layer
returns Natural Earth countries layer from world.map.gpkg as QgsVectorLayer
qgis_show_map
lets developer inspect the QGIS map visually during the test and also at the teardown of the test. Full signature of the marker is:@pytest.mark.qgis_show_map(timeout: int = 30, add_basemap: bool = False, zoom_to_common_extent: bool = True, extent: QgsRectangle = None)
timeout
is the time in seconds until the map is closed. If timeout is zero, the map will be closed in teardown.add_basemap
when set to True, adds Natural Earth countries layer as the basemap for the map.zoom_to_common_extent
when set to True, centers the map around all layers in the project.extent
is alternative tozoom_to_common_extent
and lets user specify the extent asQgsRectangle
Check the marker api documentation and examples for the ways markers can be used.
-
pytest_configure
hook is used to initialize and configureQgsApplication
. With QGIS >= 3.18 it is also used to patchqgis.utils.iface
withqgis_iface
automatically.Be careful not to import modules importing
qgis.utils.iface
in the root of conftest, because thepytest_configure
hook has not yet patchediface
in that point. See this issue for details. -
pytest_runtest_teardown
hook is used to ensure that all layer fixtures of any scope are cleaned properly without causing segmentation faults. The layer fixtures that are cleaned automatically must have some of the following keywords in their name: "layer", "lyr", "raster", "rast", "tif".
-
clean_qgis_layer
decorator found inpytest_qgis.utils
can be used withQgsMapLayer
fixtures to ensure that they are cleaned properly if they are used but not added to theQgsProject
. This is only needed with layers with other than memory provider.This decorator works only with fixtures that return QgsMapLayer instances. There is no support for fixtures that use yield.
This decorator is an alternative way of cleaning the layers, since
pytest_runtest_teardown
hook cleans layer fixtures automatically by the keyword.# conftest.py or start of a test file import pytest from pytest_qgis.utils import clean_qgis_layer from qgis.core import QgsVectorLayer @pytest.fixture() @clean_qgis_layer def geojson() -> QgsVectorLayer: return QgsVectorLayer("layer_file.geojson", "some layer") # This will be cleaned automatically since it contains the keyword "layer" in its name @pytest.fixture() def geojson_layer() -> QgsVectorLayer: return QgsVectorLayer("layer_file2.geojson", "some layer")
--qgis_disable_gui
can be used to disable graphical user interface in tests. This speeds up the tests that use Qt widgets of the plugin.--qgis_disable_init
can be used to prevent QGIS (QgsApplication) from initializing. Mainly used in internal testing.
qgis_qui_enabled
whether the QUI will be visible or not. Defaults toTrue
. Command line option--qgis_disable_gui
will override this.qgis_canvas_width
width of the QGIS canvas in pixels. Defaults to 600.qgis_canvas_height
height of the QGIS canvas in pixels. Defaults to 600.
Class to hold common utility methods for interacting with QGIS. Check test_qgis_bot.py for usage examples. Here are some of the methods:
create_feature_with_attribute_dialog
method can be used to create a feature with default values using QgsAttributeDialog. This ensures that all the default values are honored and for example boolean fields are either true or false, not null.get_qgs_attribute_dialog_widgets_by_name
function can be used to get dictionary of theQgsAttributeDialog
widgets. Check the test test_qgis_ui.py::test_attribute_dialog_change for a usage example.
This pytest plugin requires QGIS >= 3.16 to work though it might work with older versions.
Install with pip
:
pip install pytest-qgis
# Create a virtual environment with qgis and dependencies available
$ python -m venv .venv --system-site-packages
# Activate the virtual environment
$ source .venv/bin/activate
# Update pip and setuptools
$ python -m pip install -U pip setuptools
$ pip install pip-tools
# Install dependencies
$ pip-sync requirements.txt requirements-dev.txt
# Install pre-commit hooks
$ pre-commit install
pip-compile --upgrade
pip-compile --upgrade requirements-dev.in
Contributions are very welcome.
Distributed under the terms of the GNU GPL v2.0
license, "pytest-qgis" is free and open source software.