Merge pull request #2139 from lonvia/add-pytest

Introduce unit testing for Python code
This commit is contained in:
Sarah Hoffmann 2021-01-15 17:37:36 +01:00 committed by GitHub
commit 1c26fd489d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 134 additions and 26 deletions

View File

@ -46,21 +46,21 @@ jobs:
- uses: ./.github/actions/build-nominatim - uses: ./.github/actions/build-nominatim
- name: Install test prerequsites - name: Install test prerequsites
run: | run: sudo apt-get install -y -qq php-codesniffer pylint python3-pytest python3-behave
sudo apt-get install -y -qq php-codesniffer pylint
sudo pip3 install behave
- name: PHP linting - name: PHP linting
run: phpcs --report-width=120 . run: phpcs --report-width=120 .
- name: Python linting - name: Python linting
run: | run: pylint nominatim
pylint nominatim
- name: PHP unit tests - name: PHP unit tests
run: phpunit ./ run: phpunit ./
working-directory: test/php working-directory: test/php
- name: Python unit tests
run: py.test-3 test/python
- name: BDD tests - name: BDD tests
run: behave -DREMOVE_TEMPLATE=1 --format=progress3 run: behave -DREMOVE_TEMPLATE=1 --format=progress3
working-directory: test/bdd working-directory: test/bdd

View File

@ -140,31 +140,59 @@ if (BUILD_TESTS)
set(TEST_BDD db osm2pgsql api) set(TEST_BDD db osm2pgsql api)
find_program(PYTHON_BEHAVE behave)
find_program(PYLINT NAMES pylint3 pylint) find_program(PYLINT NAMES pylint3 pylint)
find_program(PYTEST NAMES pytest py.test-3 py.test)
find_program(PHPCS phpcs)
find_program(PHPUNIT phpunit)
foreach (test ${TEST_BDD}) if (PYTHON_BEHAVE)
add_test(NAME bdd_${test} message(STATUS "Using Python behave binary ${PYTHON_BEHAVE}")
COMMAND behave ${test} foreach (test ${TEST_BDD})
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/test/bdd) add_test(NAME bdd_${test}
set_tests_properties(bdd_${test} COMMAND ${PYTHON_BEHAVE} ${test}
PROPERTIES ENVIRONMENT "NOMINATIM_DIR=${PROJECT_BINARY_DIR}") WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/test/bdd)
endforeach() set_tests_properties(bdd_${test}
PROPERTIES ENVIRONMENT "NOMINATIM_DIR=${PROJECT_BINARY_DIR}")
endforeach()
else()
message(WARNING "behave not found. BDD tests disabled." )
endif()
add_test(NAME php if (PHPUNIT)
COMMAND phpunit ./ message(STATUS "Using phpunit binary ${PHPUNIT}")
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/test/php) add_test(NAME php
COMMAND ${PHPUNIT} ./
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/test/php)
else()
message(WARNING "phpunit not found. PHP unit tests disabled." )
endif()
add_test(NAME phpcs if (PHPCS)
COMMAND phpcs --report-width=120 --colors lib website utils message(STATUS "Using phpcs binary ${PHPCS}")
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}) add_test(NAME phpcs
COMMAND ${PHPCS} --report-width=120 --colors lib website utils
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
else()
message(WARNING "phpcs not found. PHP linting tests disabled." )
endif()
if (PYLINT) if (PYLINT)
message(STATUS "Using '${PYLINT}' for Python linting.") message(STATUS "Using pylint binary ${PYLINT}")
add_test(NAME pylint add_test(NAME pylint
COMMAND ${PYLINT} nominatim COMMAND ${PYLINT} nominatim
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}) WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
else() else()
message(STATUS "pylint not found. Linting tests disabled.") message(WARNING "pylint not found. Python linting tests disabled.")
endif()
if (PYTEST)
message(STATUS "Using pytest binary ${PYTEST}")
add_test(NAME pytest
COMMAND ${PYTEST} test/python
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
else()
message(WARNING "pytest not found. Python tests disabled." )
endif() endif()
endif() endif()

View File

@ -26,12 +26,14 @@ following packages should get you started:
## Prerequisites for testing and documentation ## Prerequisites for testing and documentation
The Nominatim test suite consists of behavioural tests (using behave) and The Nominatim test suite consists of behavioural tests (using behave) and
unit tests (using PHPUnit). It has the following additional requirements: unit tests (using PHPUnit for PHP code and pytest for Python code).
It has the following additional requirements:
* [behave test framework](https://behave.readthedocs.io) >= 1.2.5 * [behave test framework](https://behave.readthedocs.io) >= 1.2.5
* [phpunit](https://phpunit.de) >= 7.3 * [phpunit](https://phpunit.de) >= 7.3
* [PHP CodeSniffer](https://github.com/squizlabs/PHP_CodeSniffer) * [PHP CodeSniffer](https://github.com/squizlabs/PHP_CodeSniffer)
* [Pylint](https://pylint.org/) * [Pylint](https://pylint.org/) (2.6.0 is used for the CI)
* [pytest](https://pytest.org)
The documentation is built with mkdocs: The documentation is built with mkdocs:
@ -49,7 +51,7 @@ To install all necessary packages run:
sudo apt install php-cgi phpunit php-codesniffer \ sudo apt install php-cgi phpunit php-codesniffer \
python3-pip python3-setuptools python3-dev pylint python3-pip python3-setuptools python3-dev pylint
pip3 install --user behave mkdocs pip3 install --user behave mkdocs pytest
``` ```
The `mkdocs` executable will be located in `.local/bin`. You may have to add The `mkdocs` executable will be located in `.local/bin`. You may have to add

View File

@ -21,14 +21,15 @@ This test directory is sturctured as follows:
| +- api Tests for API endpoints (search, reverse, etc.) | +- api Tests for API endpoints (search, reverse, etc.)
| |
+- php PHP unit tests +- php PHP unit tests
+- python Python unit tests
+- scenes Geometry test data +- scenes Geometry test data
+- testdb Base data for generating API test database +- testdb Base data for generating API test database
``` ```
## PHP Unit Tests (`test/php`) ## PHP Unit Tests (`test/php`)
Unit tests can be found in the php/ directory. They test selected php functions. Unit tests for PHP code can be found in the `php/` directory. They test selected
Very low coverage. PHP functions. Very low coverage.
To execute the test suite run To execute the test suite run
@ -36,11 +37,26 @@ To execute the test suite run
UNIT_TEST_DSN='pgsql:dbname=nominatim_unit_tests' phpunit ../ UNIT_TEST_DSN='pgsql:dbname=nominatim_unit_tests' phpunit ../
It will read phpunit.xml which points to the library, test path, bootstrap It will read phpunit.xml which points to the library, test path, bootstrap
strip and set other parameters. strip and sets other parameters.
It will use (and destroy) a local database 'nominatim_unit_tests'. You can set It will use (and destroy) a local database 'nominatim_unit_tests'. You can set
a different connection string with e.g. UNIT_TEST_DSN='pgsql:dbname=foo_unit_tests'. a different connection string with e.g. UNIT_TEST_DSN='pgsql:dbname=foo_unit_tests'.
## Python Unit Tests (`test/python`)
Unit tests for Python code can be found in the `python/` directory. The goal is
to have complete coverage of the Python library in `nominatim`.
To execute the tests run
py.test-3 test/python
or
pytest test/python
The name of the pytest binary depends on your installation.
## BDD Functional Tests (`test/bdd`) ## BDD Functional Tests (`test/bdd`)
Functional tests are written as BDD instructions. For more information on Functional tests are written as BDD instructions. For more information on

6
test/python/conftest.py Normal file
View File

@ -0,0 +1,6 @@
import sys
from pathlib import Path
# always test against the source
sys.path.insert(0, str((Path(__file__) / '..' / '..' / '..').resolve()))

View File

@ -0,0 +1,56 @@
"""
Test for loading dotenv configuration.
"""
from pathlib import Path
import tempfile
import os
import pytest
from nominatim.config import Configuration
DEFCFG_DIR = Path(__file__) / '..' / '..' / '..' / 'settings'
def test_no_project_dir():
config = Configuration(None, DEFCFG_DIR)
assert config.DATABASE_WEBUSER == 'www-data'
def test_prefer_project_setting_over_default():
with tempfile.TemporaryDirectory() as project_dir:
with open(project_dir + '/.env', 'w') as envfile:
envfile.write('NOMINATIM_DATABASE_WEBUSER=apache\n')
config = Configuration(Path(project_dir), DEFCFG_DIR)
assert config.DATABASE_WEBUSER == 'apache'
def test_prefer_os_environ_over_project_setting():
with tempfile.TemporaryDirectory() as project_dir:
with open(project_dir + '/.env', 'w') as envfile:
envfile.write('NOMINATIM_DATABASE_WEBUSER=apache\n')
os.environ['NOMINATIM_DATABASE_WEBUSER'] = 'nobody'
config = Configuration(Path(project_dir), DEFCFG_DIR)
assert config.DATABASE_WEBUSER == 'nobody'
del os.environ['NOMINATIM_DATABASE_WEBUSER']
def test_get_os_env_add_defaults():
config = Configuration(None, DEFCFG_DIR)
if 'NOMINATIM_DATABASE_WEBUSER' in os.environ:
del os.environ['NOMINATIM_DATABASE_WEBUSER']
assert config.get_os_env()['NOMINATIM_DATABASE_WEBUSER'] == 'www-data'
def test_get_os_env_prefer_os_environ():
config = Configuration(None, DEFCFG_DIR)
os.environ['NOMINATIM_DATABASE_WEBUSER'] = 'nobody'
assert config.get_os_env()['NOMINATIM_DATABASE_WEBUSER'] == 'nobody'
del os.environ['NOMINATIM_DATABASE_WEBUSER']