Skip to content

Commit 15fb5d6

Browse files
committed
Add integration tests and make a distinction between public and private tests in Github CI
1 parent 9236db3 commit 15fb5d6

File tree

6 files changed

+115
-6
lines changed

6 files changed

+115
-6
lines changed

.github/workflows/Tests-Private.yaml

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# This workflow runs everything which is requiring secrets / access to external systems
2+
# It requires manual approval by a maintainer for external commiters and uses
3+
# It uses a "hack" to still execute within PR codebase despite secrets being exposed
4+
name: Private Tests
5+
6+
on:
7+
pull_request:
8+
pull_request_target:
9+
push:
10+
branches:
11+
- main
12+
13+
jobs:
14+
run-tests:
15+
environment: 'private'
16+
strategy:
17+
matrix:
18+
os: [ubuntu-24.04]
19+
python: ["3.11", "3.12"]
20+
runs-on: ${{ matrix.os }}
21+
22+
steps:
23+
- uses: actions/checkout@v4
24+
with:
25+
# /!\ important: this checks out code from the HEAD of the PR instead of the main branch (for pull_request_target)
26+
ref: ${{ github.event.pull_request.head.sha || github.ref }}
27+
28+
- name: Set up Python ${{ matrix.python }}
29+
uses: actions/setup-python@v5
30+
with:
31+
python-version: ${{ matrix.python }}
32+
architecture: x64
33+
34+
- name: Install dependencies (and project)
35+
run: |
36+
pip install -U pip
37+
pip install -e .[test,scripts]
38+
39+
- name: Run the tests
40+
run: inv coverage-integration --args "-vvv"
41+
42+
- name: Upload coverage results for integration tests
43+
if: matrix.python == '3.12'
44+
uses: actions/upload-artifact@v4
45+
with:
46+
name: coverage-integration
47+
path: coverage.xml
48+
retention-days: 1

.github/workflows/Tests.yaml renamed to .github/workflows/Tests-Public.yaml

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
name: Tests
1+
# This workflow runs everything which is mostly harmless to run on an external PR
2+
# because it does not requires secrets / access to external systems
3+
name: Public Tests
24

35
on:
46
pull_request:
@@ -29,14 +31,22 @@ jobs:
2931
pip install -e .[test,scripts]
3032
3133
- name: Run the tests
32-
run: inv coverage --args "-vvv"
34+
run: inv coverage-unit --args "-vvv"
3335

34-
- name: Upload coverage report to codecov
36+
- name: Upload coverage results for unit tests
3537
if: matrix.python == '3.12'
36-
uses: codecov/codecov-action@v4
38+
uses: actions/upload-artifact@v4
3739
with:
38-
fail_ci_if_error: true
39-
token: ${{ secrets.CODECOV_TOKEN }}
40+
name: coverage-unit
41+
path: coverage.xml
42+
retention-days: 1
43+
44+
# - name: Upload coverage report to codecov
45+
# if: matrix.python == '3.12'
46+
# uses: codecov/codecov-action@v4
47+
# with:
48+
# fail_ci_if_error: true
49+
# token: ${{ secrets.CODECOV_TOKEN }}
4050

4151
build_python:
4252
runs-on: ubuntu-24.04

src/great_project/__init__.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# pyright: strict, reportUnnecessaryIsInstance=false
22

3+
import os
4+
35
from great_project.__about__ import __version__
46

57

@@ -10,5 +12,9 @@ def compute(a: int, b: int) -> int:
1012
return a + b
1113

1214

15+
def get_env_value(env_variable: str) -> str | None:
16+
return os.environ.get(env_variable)
17+
18+
1319
def entrypoint():
1420
print(f"Hello from {__version__}") # noqa: T201

tasks.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,36 @@ def test(ctx: Context, args: str = ""):
1313
ctx.run(f"pytest {args}", pty=use_pty)
1414

1515

16+
@task(optional=["args"], help={"args": "pytest additional arguments"})
17+
def test_unit(ctx: Context, args: str = ""):
18+
"""run unit tests (without coverage)"""
19+
ctx.run(f"pytest tests/unit {args}", pty=use_pty)
20+
21+
22+
@task(optional=["args"], help={"args": "pytest additional arguments"})
23+
def test_integration(ctx: Context, args: str = ""):
24+
"""run integration tests (without coverage)"""
25+
ctx.run(f"pytest tests/integration {args}", pty=use_pty)
26+
27+
1628
@task(optional=["args"], help={"args": "pytest additional arguments"})
1729
def test_cov(ctx: Context, args: str = ""):
1830
"""run test vith coverage"""
1931
ctx.run(f"coverage run -m pytest {args}", pty=use_pty)
2032

2133

34+
@task(optional=["args"], help={"args": "pytest additional arguments"})
35+
def test_unit_cov(ctx: Context, args: str = ""):
36+
"""run test vith coverage"""
37+
ctx.run(f"coverage run -m pytest tests/unit {args}", pty=use_pty)
38+
39+
40+
@task(optional=["args"], help={"args": "pytest additional arguments"})
41+
def test_integration_cov(ctx: Context, args: str = ""):
42+
"""run test vith coverage"""
43+
ctx.run(f"coverage run -m pytest tests/integration {args}", pty=use_pty)
44+
45+
2246
@task(optional=["html"], help={"html": "flag to export html report"})
2347
def report_cov(ctx: Context, *, html: bool = False):
2448
"""report coverage"""
@@ -42,6 +66,19 @@ def coverage(ctx: Context, args: str = "", *, html: bool = False):
4266
report_cov(ctx, html=html)
4367

4468

69+
@task(
70+
optional=["args", "html"],
71+
help={
72+
"args": "pytest additional arguments",
73+
"html": "flag to export html report",
74+
},
75+
)
76+
def coverage_unit(ctx: Context, args: str = "", *, html: bool = False):
77+
"""run unit tests and report coverage"""
78+
test_unit_cov(ctx, args=args)
79+
report_cov(ctx, html=html)
80+
81+
4582
@task(optional=["args"], help={"args": "black additional arguments"})
4683
def lint_black(ctx: Context, args: str = "."):
4784
args = args or "." # needed for hatch script

tests/integration/test_integration.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# pyright: strict, reportUnusedExpression=false
2+
3+
from great_project import get_env_value
4+
5+
6+
# a fake test needing a value from environment variable secret to complete properly
7+
def test_environ():
8+
assert get_env_value("A_SECRET_VALUE_FROM_ENV") == "A_SECRET_VALUE_FROM_ENV"
File renamed without changes.

0 commit comments

Comments
 (0)