Skip to content

Commit 88faccb

Browse files
Merge pull request #61 from traveltime-dev/2022-12_automated-tests
automated tests
2 parents fc762ae + b41e377 commit 88faccb

File tree

23 files changed

+769
-24
lines changed

23 files changed

+769
-24
lines changed

.env.example

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
COMPOSE_FILE=testing/docker-compose.yml
2+
3+
# QGIS image to test against
4+
QGIS_IMAGE=opengisch/qgis:3.28-jammy
5+
6+
# Get these from https://igeolise.3scale.net/admin
7+
API_APP_ID=
8+
API_KEY=

.github/workflows/tests.yml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
on:
2+
pull_request:
3+
push:
4+
branches:
5+
- master
6+
schedule:
7+
- cron: '0 6 * * 1' # weekly check
8+
9+
jobs:
10+
tests:
11+
runs-on: ubuntu-20.04
12+
timeout-minutes: 10
13+
14+
strategy:
15+
fail-fast: false
16+
matrix:
17+
qgis_image:
18+
- opengisch/qgis:3.28-jammy
19+
- opengisch/qgis:3.22-focal
20+
21+
env:
22+
QGIS_IMAGE: ${{ matrix.qgis_image }}
23+
API_APP_ID: ${{ secrets.API_APP_ID }}
24+
API_KEY: ${{ secrets.API_KEY }}
25+
26+
steps:
27+
- name: Check out repository code
28+
uses: actions/checkout@v3
29+
30+
- name: Copy .env
31+
run: cp .env.example .env
32+
33+
- name: Run tests (${{ matrix.qgis_image }})
34+
run: docker-compose run tests

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
__pycache__
22
.vscode
3+
.env

.pre-commit-config.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
repos:
44
# Fix end of files
55
- repo: https://github.com/pre-commit/pre-commit-hooks
6-
rev: v3.2.0
6+
rev: v4.4.0
77
hooks:
88
- id: trailing-whitespace
99
exclude: .*\.md
@@ -14,7 +14,7 @@ repos:
1414

1515
# Remove unused imports/variables
1616
- repo: https://github.com/myint/autoflake
17-
rev: v1.4
17+
rev: v2.0.0
1818
hooks:
1919
- id: autoflake
2020
args:
@@ -24,13 +24,13 @@ repos:
2424

2525
# Sort imports
2626
- repo: https://github.com/pycqa/isort
27-
rev: "5.7.0"
27+
rev: "v5.11.3"
2828
hooks:
2929
- id: isort
3030
args: ["--profile", "black"]
3131

3232
# Black formatting
3333
- repo: https://github.com/psf/black
34-
rev: 20.8b1
34+
rev: 22.12.0
3535
hooks:
3636
- id: black

README.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# ![Travel Time Platform](travel_time_platform_plugin/resources/TravelTime_logo_horizontal.svg)
22

3+
[![.github/workflows/tests.yml](https://github.com/traveltime-dev/traveltime-platform-qgis-plugin/actions/workflows/tests.yml/badge.svg)](https://github.com/traveltime-dev/traveltime-platform-qgis-plugin/actions/workflows/tests.yml)
4+
35
This is the repository for the TravelTime platform plugin for QGIS.
46

57
This plugin intends to make the TravelTime platform API available for ues in QGIS through processing algorithms.
@@ -16,6 +18,28 @@ The documentation is available here : https://qgis.traveltimeplatform.com/
1618

1719
Please report any issue to the bug tracker.
1820

21+
## Contribute
22+
23+
### Tests
24+
25+
Run the integrations tests with docker
26+
27+
```bash
28+
# Copy the default config, then edit with your own API key
29+
cp .env.example .env
30+
31+
# Run tests (headless)
32+
docker-compose run tests
33+
34+
# Run tests (with visual feedback, on Windows only works under WSL)
35+
docker-compose run tests-gui
36+
```
37+
38+
These tests are run automatically in Github actions. The actions require two secrets to be set: `API_APP_ID` and `API_KEY`.
39+
40+
Alternatively, you can also run the tests from the QGIS desktop.
41+
42+
1943
## Code style
2044

2145
Formatting is done with `pre-commit`. Please run `pip install pre-commit` and `pre-commit install` prior to contributing.

testing/QGIS3.ini

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[PythonPlugins]
2+
travel_time_platform_plugin=true

testing/artifacts/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
*
2+
!.gitignore

testing/docker-compose.yml

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
version: "3"
2+
3+
services:
4+
5+
# Runs tests (headless)
6+
tests:
7+
image: ${QGIS_IMAGE:?}
8+
volumes:
9+
# mount the plugin
10+
- ../travel_time_platform_plugin:/root/.local/share/QGIS/QGIS3/profiles/default/python/plugins/travel_time_platform_plugin
11+
# include default config (enabling the plugin)
12+
- ../testing/QGIS3.ini:/root/.local/share/QGIS/QGIS3/profiles/default/QGIS/QGIS3.ini
13+
# include initialisation script (test launcher in QGIS)
14+
- ../testing/startup.py:/root/.local/share/QGIS/QGIS3/startup.py
15+
# include entrypoint script (test launcher in QGIS)
16+
- ../testing/runner.py:/runner.py
17+
# mount artifacts folder
18+
- ../testing/artifacts:/tmp/ttp_tests
19+
environment:
20+
TEST_MODE: HEADLESS
21+
API_APP_ID: ${API_APP_ID:?}
22+
API_KEY: ${API_KEY:?}
23+
init: true # not sure why, but this is necessary for xvfb (see https://stackoverflow.com/a/72017110)
24+
entrypoint: xvfb-run
25+
command: python3 /runner.py
26+
27+
# Runs tests (with visual feedback)
28+
tests-gui:
29+
extends: tests
30+
volumes:
31+
# mount the x11 socket to forward display to host
32+
- /tmp/.X11-unix:/tmp/.X11-unix
33+
environment:
34+
TEST_MODE: HEADFULL
35+
DISPLAY: :0
36+
init: false
37+
entrypoint: ""

testing/runner.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
"""
2+
This script should be used to wrap calls to QGIS. It will check the output and set exit code
3+
accordingly to test results, working around the issue about QGIS crashing on exitting from python.
4+
"""
5+
6+
import sys
7+
from subprocess import PIPE, STDOUT, Popen
8+
9+
print("Starting qgis...")
10+
11+
# Run QGIS in a subprocess
12+
process = Popen("qgis", stdout=PIPE, stderr=STDOUT, encoding="utf-8")
13+
14+
# Print output in realtime, keep full output in string
15+
full_output = ""
16+
while True:
17+
output = process.stdout.readline()
18+
if output.strip():
19+
print(output.strip(), flush=True)
20+
full_output += output
21+
if output == "" and process.poll() is not None:
22+
break
23+
24+
# Set exit code
25+
if "__SUCCESS__" in full_output and "__FAILURE__" not in full_output:
26+
sys.exit(0)
27+
else:
28+
sys.exit(1)

testing/startup.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
"""
2+
This script starts the test suite from within QGIS.
3+
4+
It should be mounted to ~/.local/share/QGIS/QGIS3/startup.py to run the tests on QGIS startup.
5+
"""
6+
7+
import sys
8+
9+
from qgis.PyQt.QtCore import qDebug
10+
from qgis.utils import iface
11+
12+
# TODO: proper tests discovery
13+
from travel_time_platform_plugin.tests import run_suite, system_info
14+
15+
# Forward pyqgis output to console
16+
sys.stdout.write = lambda text: qDebug(text.encode("ascii", "replace").strip())
17+
sys.stderr.write = lambda text: qDebug(text.encode("ascii", "replace").strip())
18+
19+
print("Waiting for initialisation...")
20+
21+
22+
def run_tests():
23+
24+
print("Starting tests...")
25+
26+
# Show output
27+
print(system_info())
28+
29+
# Maximize the window
30+
iface.mainWindow().showMaximized()
31+
iface.mainWindow().activateWindow()
32+
33+
# Run the tests
34+
tests = run_suite(stream=sys.stdout)
35+
36+
# To workaround missing exit code (see below), so we print the result value and check for it in the runner
37+
if tests.wasSuccessful():
38+
print("__SUCCESS__")
39+
else:
40+
print("__FAILURE__")
41+
42+
# Exit code here is lost, since this crashes QGIS with segfault
43+
print("notice: following `QGIS died on signal 11` can be ignored.")
44+
sys.exit(0 if tests.wasSuccessful() else 1)
45+
46+
47+
# Start tests only once init is complete
48+
iface.initializationCompleted.connect(run_tests)

0 commit comments

Comments
 (0)