From dee7c425c3e9e67531c9912f8f7db3e6692a753e Mon Sep 17 00:00:00 2001 From: Andreas Motl Date: Sun, 28 Jan 2024 11:44:30 +0100 Subject: [PATCH 1/2] Tests: Skip OPS-based integration tests when no credentials are defined While it will only cover parts of the test suite, which is unfortunate, at least it will not break. This is relevant for CI/GHA, because pull requests submitted by external contributors do not have access to the OPS credentials per GitHub Actions Secrets. C'est la vie. --- tests/conftest.py | 13 +++++++++---- tests/secrets.py | 12 ++++++++++-- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 94b8ca1..c4c4152 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,7 +1,7 @@ import pytest from .helpers import mkcache, mksqlite, mkthrottler -from .secrets import OPS_KEY, OPS_SECRET +from .secrets import get_secrets_or_skip_tests @pytest.fixture @@ -13,8 +13,9 @@ def storage(request): def reset_cached_client(request): from epo_ops import Client + ops_key, ops_secret = get_secrets_or_skip_tests() return Client( - OPS_KEY, OPS_SECRET, middlewares=[mkcache(request), mkthrottler(request)] + ops_key, ops_secret, middlewares=[mkcache(request), mkthrottler(request)] ) @@ -32,14 +33,18 @@ def module_cache(request): def default_client(request): from epo_ops import Client - return Client(OPS_KEY, OPS_SECRET, middlewares=[mkthrottler(request)]) + ops_key, ops_secret = get_secrets_or_skip_tests() + + return Client(ops_key, ops_secret, middlewares=[mkthrottler(request)]) @pytest.fixture(scope="module") def cached_client(request, module_cache): from epo_ops import Client - return Client(OPS_KEY, OPS_SECRET, middlewares=[module_cache, mkthrottler(request)]) + ops_key, ops_secret = get_secrets_or_skip_tests() + + return Client(ops_key, ops_secret, middlewares=[module_cache, mkthrottler(request)]) @pytest.fixture(scope="module", params=["cached_client", "default_client"]) diff --git a/tests/secrets.py b/tests/secrets.py index bf13873..c5dfacb 100644 --- a/tests/secrets.py +++ b/tests/secrets.py @@ -9,6 +9,7 @@ import os from os.path import abspath, dirname, join +import pytest from dotenv import load_dotenv # Prune environment variables. @@ -20,6 +21,13 @@ dotenv_path = abspath(join(dirname(__file__), "../.env")) load_dotenv(dotenv_path) + # Set environment variables as constants. -OPS_KEY = os.environ["OPS_KEY"] -OPS_SECRET = os.environ["OPS_SECRET"] +def get_secrets_or_skip_tests(): + try: + ops_key = os.environ["OPS_KEY"] + ops_secret = os.environ["OPS_SECRET"] + except KeyError as ex: + raise pytest.skip("No OPS credentials configured") from ex + + return ops_key, ops_secret From 8a3f3c47cf7d12ebe54a703f9824b028bcbc0b9c Mon Sep 17 00:00:00 2001 From: Andreas Motl Date: Sun, 28 Jan 2024 11:45:55 +0100 Subject: [PATCH 2/2] Tests: Modernize configuration and invocation of `pytest` By centralizing common configuration settings into `pyproject.toml`, the invocation is more universal, and the configuration does not need to be maintained at different spots. --- Makefile | 8 ++++---- pyproject.toml | 12 ++++++++++++ 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 7a7102c..536b2fb 100644 --- a/Makefile +++ b/Makefile @@ -43,13 +43,13 @@ format: ## Run code formatting black . test: clean ## Run tests with virtualenv Python - py.test -s -v --lf --cov epo_ops tests --cov-report term-missing --cov-report xml + pytest --lf test-ci: clean ## Run tests in CI environment with virtualenv Python - py.test -v --cov epo_ops tests --cov-report term-missing --cov-report xml + pytest -coverage: clean ## Check code coverage locally - py.test -s -v --cov epo_ops tests --cov-report term-missing --cov-report xml --cov-report html +coverage: clean test-ci ## Check code coverage locally + coverage html open htmlcov/index.html release: clean # Package and upload a release to PyPI diff --git a/pyproject.toml b/pyproject.toml index 93a840b..b4cc0f7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,6 +9,18 @@ requires = [ ] build-backend = "setuptools.build_meta" +[tool.pytest.ini_options] +minversion = "2.0" +addopts = """ + -rsfEX -p pytester --strict-markers --verbosity=3 + --cov=epo_ops tests --cov-report=term-missing --cov-report=xml + """ +log_level = "DEBUG" +log_cli_level = "DEBUG" +testpaths = ["tests"] +xfail_strict = true +markers = [ +] [tool.ruff] line-length = 80