Add pytest with GitHub Action workflow

This commit is contained in:
2024-11-09 13:21:50 -06:00
parent db260ecfa3
commit 818c3cb7bc
6 changed files with 156 additions and 1 deletions

40
.github/workflows/test.yaml vendored Normal file
View File

@@ -0,0 +1,40 @@
name: Pytest
on: [pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@v4
- name: Set up python
id: setup-python
uses: actions/setup-python@v5
with:
python-version: "3.12.7"
- name: Install Poetry
uses: snok/install-poetry@v1
with:
version: 1.8.4
virtualenvs-create: true
virtualenvs-in-project: true
- name: Load cached venv
id: cached-pip-wheels
uses: actions/cache@v4
with:
path: ~/.cache
key: venv-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/poetry.lock') }}
- name: Install dependencies
run: cd backend && poetry install --no-interaction --no-root
- name: Install library
run: cd backend && poetry install --no-interaction
- run: |
source $VENV
pytest --version

View File

@@ -10,10 +10,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## Added
- A release checklist to the `CHANGELOG.md` file, as a reminder for procedure.
- An action workflow for invoking `pytest`
- backend: `pwdlib[argon2]` for password hashing
- backend: provided `LOG_JSON_FORMAT` and `LOG_LEVEL` environment variable defaults in `run.sh` development script
- backend: `User` model, `Session` model with migration script
- backend: `utc_now` helper function
- backend: `pytest`, simple `/health` & `/api/migrations` endpoint tests
- frontend: Added `clsx` package
## Changed

View File

@@ -0,0 +1,16 @@
from fastapi.testclient import TestClient
from linkpulse.app import app
def test_health():
with TestClient(app) as client:
response = client.get("/health")
assert response.status_code == 200
assert response.json() == "OK"
def test_migration():
with TestClient(app) as client:
response = client.get("/api/migration")
assert response.status_code == 200

94
backend/poetry.lock generated
View File

@@ -640,6 +640,52 @@ files = [
{file = "hpack-4.0.0.tar.gz", hash = "sha256:fc41de0c63e687ebffde81187a948221294896f6bdc0ae2312708df339430095"},
]
[[package]]
name = "httpcore"
version = "1.0.6"
description = "A minimal low-level HTTP client."
optional = false
python-versions = ">=3.8"
files = [
{file = "httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f"},
{file = "httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f"},
]
[package.dependencies]
certifi = "*"
h11 = ">=0.13,<0.15"
[package.extras]
asyncio = ["anyio (>=4.0,<5.0)"]
http2 = ["h2 (>=3,<5)"]
socks = ["socksio (==1.*)"]
trio = ["trio (>=0.22.0,<1.0)"]
[[package]]
name = "httpx"
version = "0.27.2"
description = "The next generation HTTP client."
optional = false
python-versions = ">=3.8"
files = [
{file = "httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0"},
{file = "httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2"},
]
[package.dependencies]
anyio = "*"
certifi = "*"
httpcore = "==1.*"
idna = "*"
sniffio = "*"
[package.extras]
brotli = ["brotli", "brotlicffi"]
cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"]
http2 = ["h2 (>=3,<5)"]
socks = ["socksio (==1.*)"]
zstd = ["zstandard (>=0.18.0)"]
[[package]]
name = "human-readable"
version = "1.3.4"
@@ -699,6 +745,17 @@ files = [
[package.extras]
all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"]
[[package]]
name = "iniconfig"
version = "2.0.0"
description = "brain-dead simple config-ini parsing"
optional = false
python-versions = ">=3.7"
files = [
{file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"},
{file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"},
]
[[package]]
name = "jinxed"
version = "1.3.0"
@@ -929,6 +986,21 @@ tzdata = ">=2020.1"
[package.extras]
test = ["time-machine (>=2.6.0)"]
[[package]]
name = "pluggy"
version = "1.5.0"
description = "plugin and hook calling mechanisms for python"
optional = false
python-versions = ">=3.8"
files = [
{file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"},
{file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"},
]
[package.extras]
dev = ["pre-commit", "tox"]
testing = ["pytest", "pytest-benchmark"]
[[package]]
name = "priority"
version = "2.0.0"
@@ -1167,6 +1239,26 @@ files = [
[package.extras]
windows-terminal = ["colorama (>=0.4.6)"]
[[package]]
name = "pytest"
version = "8.3.3"
description = "pytest: simple powerful testing with Python"
optional = false
python-versions = ">=3.8"
files = [
{file = "pytest-8.3.3-py3-none-any.whl", hash = "sha256:a6853c7375b2663155079443d2e45de913a911a11d669df02a50814944db57b2"},
{file = "pytest-8.3.3.tar.gz", hash = "sha256:70b98107bd648308a7952b06e6ca9a50bc660be218d53c257cc1fc94fda10181"},
]
[package.dependencies]
colorama = {version = "*", markers = "sys_platform == \"win32\""}
iniconfig = "*"
packaging = "*"
pluggy = ">=1.5,<2"
[package.extras]
dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"]
[[package]]
name = "python-dateutil"
version = "2.9.0.post0"
@@ -1443,4 +1535,4 @@ h11 = ">=0.9.0,<1"
[metadata]
lock-version = "2.0"
python-versions = "^3.12"
content-hash = "b5e06928b75df2a2428032f6e37b43e44d42b184654770686471125770abe3da"
content-hash = "ffb962027e08510f6142c1a125d14e59fcf8708b53a38c10a40bcac38d36a684"

View File

@@ -35,6 +35,8 @@ pwdlib = {extras = ["argon2"], version = "^0.2.1"}
memory-profiler = "^0.61.0"
bpython = "^0.24"
types-pytz = "^2024.2.0.20241003"
pytest = "^8.3.3"
httpx = "^0.27.2"
[build-system]
requires = ["poetry-core"]

3
backend/pytest.ini Normal file
View File

@@ -0,0 +1,3 @@
[pytest]
filterwarnings =
ignore::DeprecationWarning