Add test for server

A test fixture to start the server and a first test case is added.

The fixture tries to assure that the server is installed and running.
If it is not installed the fixture uses pip to install it.

The server and the installation by pip is run bei the same Python
executable that also runs pytest.

The github workflow for pytest is adapted to install akkudoktor-eos.

Signed-off-by: Bobby Noelte <b0661n0e17e@gmail.com>
This commit is contained in:
Bobby Noelte 2024-10-08 14:29:45 +02:00 committed by Andreas
parent 1e78abb074
commit 65044b6c6c
5 changed files with 131 additions and 0 deletions

View File

@ -23,7 +23,9 @@ jobs:
sudo apt install -y libmariadb3 libmariadb-dev sudo apt install -y libmariadb3 libmariadb-dev
python -m pip install --upgrade pip python -m pip install --upgrade pip
pip install -r requirements.txt pip install -r requirements.txt
pip install -r requirements-dev.txt
- name: Run Pytest - name: Run Pytest
run: | run: |
pip install -e .
python -m pytest -vs --cov modules --cov-report term-missing tests/ python -m pytest -vs --cov modules --cov-report term-missing tests/

View File

@ -9,6 +9,7 @@ help:
@echo "Available targets:" @echo "Available targets:"
@echo " venv - Set up a Python 3 virtual environment." @echo " venv - Set up a Python 3 virtual environment."
@echo " pip - Install dependencies from requirements.txt." @echo " pip - Install dependencies from requirements.txt."
@echo " pip-dev - Install dependencies from requirements-dev.txt."
@echo " install - Install EOS in editable form (development mode) into virtual environment." @echo " install - Install EOS in editable form (development mode) into virtual environment."
@echo " docker-run - Run entire setup on docker @echo " docker-run - Run entire setup on docker
@echo " docs - Generate HTML documentation using pdoc." @echo " docs - Generate HTML documentation using pdoc."
@ -27,6 +28,11 @@ pip: venv
.venv/bin/pip install -r requirements.txt .venv/bin/pip install -r requirements.txt
@echo "Dependencies installed from requirements.txt." @echo "Dependencies installed from requirements.txt."
# Target to install dependencies from requirements.txt
pip-dev: pip
.venv/bin/pip install -r requirements-dev.txt
@echo "Dependencies installed from requirements-dev.txt."
# Target to install EOS in editable form (development mode) into virtual environment. # Target to install EOS in editable form (development mode) into virtual environment.
install: pip install: pip
.venv/bin/pip install build .venv/bin/pip install build
@ -54,6 +60,10 @@ run:
@echo "Starting flask server, please wait..." @echo "Starting flask server, please wait..."
.venv/bin/python -m akkudoktoreosserver.flask_server .venv/bin/python -m akkudoktoreosserver.flask_server
# Target to setup tests.
test-setup: pip-dev
@echo "Setup tests"
# Target to run tests. # Target to run tests.
test: test:
@echo "Running tests..." @echo "Running tests..."

View File

@ -1,2 +1,5 @@
build==1.2.2.post1
pytest==8.3.3 pytest==8.3.3
pytest-xprocess==1.0.2
requests==2.32.3
pre-commit pre-commit

53
tests/conftest.py Normal file
View File

@ -0,0 +1,53 @@
import os
import subprocess
import sys
import pytest
from xprocess import ProcessStarter
@pytest.fixture
def server(xprocess):
class Starter(ProcessStarter):
# assure server to be installed
try:
subprocess.run(
[sys.executable, "-c", "import akkudoktoreosserver"],
check=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
except subprocess.CalledProcessError:
test_dir = os.path.dirname(os.path.realpath(__file__))
project_dir = os.path.abspath(os.path.join(test_dir, ".."))
subprocess.run(
[sys.executable, "-m", "pip", "install", "-e", project_dir],
check=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
# command to start server process
args = [sys.executable, "-m", "akkudoktoreosserver.flask_server"]
# startup pattern
pattern = "Serving Flask app 'flask_server'"
# search the first 12 lines for the startup pattern, if not found
# a RuntimeError will be raised informing the user
max_read_lines = 12
# will wait for 10 seconds before timing out
timeout = 10
# xprocess will now attempt to clean up upon interruptions
terminate_on_interrupt = True
# ensure process is running and return its logfile
logfile = xprocess.ensure("akkudoktoreosserver", Starter)
# create url/port info to the server
url = "http://127.0.0.1:8503"
yield url
# clean up whole process tree afterwards
xprocess.getinfo("akkudoktoreosserver").terminate()

63
tests/test_server.py Normal file
View File

@ -0,0 +1,63 @@
import requests
def test_server(server):
"""
Test the server
"""
result = requests.get(f"{server}/gesamtlast_simple?year_energy=2000&")
assert result.status_code == 200
assert (
result.text
== """[
0.12399409965368197,
0.12082955072761034,
0.1186152098599658,
0.13282048719613798,
0.16801614895243458,
0.18833079485066814,
0.2060958576163904,
0.23815979421159755,
0.256794470747979,
0.2730286944402595,
0.2837831370699189,
0.2880791113592318,
0.27868845536305187,
0.2593976275300202,
0.26565341182134644,
0.2834322084492842,
0.3385133447353511,
0.36541124595269503,
0.33781770981176945,
0.29218838246014817,
0.24535542466592053,
0.19484917288665324,
0.15634028941335018,
0.13309410380383394,
0.1239736903705896,
0.12074280282759843,
0.11849705069574769,
0.1320224904313182,
0.16699106562771282,
0.18856343364342354,
0.20578134176859084,
0.23760516695843145,
0.25675411140321175,
0.2729442256919556,
0.2837782018548114,
0.2882881388086184,
0.2800061651414149,
0.26039842637914645,
0.26613497240454587,
0.28441116400389416,
0.33941195977626437,
0.36621100374643395,
0.3391062422788601,
0.29391186081171267,
0.24686897327498972,
0.19620626090788126,
0.1570820352949701,
0.13332596485058107
]
"""
)