diff --git a/misc/Readme_test.md b/misc/Readme_test.md new file mode 100644 index 0000000..4ba5ecc --- /dev/null +++ b/misc/Readme_test.md @@ -0,0 +1,21 @@ +# Tests + +___ + +## schemathesis + +Unter dem Verzeichnis ./src/server/tests befinden sich die Test-Cases, die Max bei der ersten Implementierung der Validierung angelegt hat. +Diese sind derzeit nicht "aktiv", bzw. noch nicht bereinigt. + +Ich möchte gern ein automatisches Framework verwenden, das aber nur "manuell" betrieben wird. Änderungen an der API sind selten. + +Aktueller Stand (7.1.26): + +Im Verzeichnis ./src/server/tests kann folgendes ausgeführt werden: + +```pytest -q --maxfail=1 contract/test_openapi_fuzz.py``` + +Das Ganze funktioniert nur, wenn auch schemathesis und hypothesis in den passenden(!) Versionen im lokalen _venv_ installiert sind. +Aktuell habe ich schemathesis ("latest") und hypothesis 6.120.0: +```pip install "hypothesis==6.120.0"``` +Das muss wegen dependencies so blöd gepinnt werden. diff --git a/src/server/tests/conftest.py b/src/server/tests/conftest.py index 5d05e47..a90a827 100644 --- a/src/server/tests/conftest.py +++ b/src/server/tests/conftest.py @@ -7,21 +7,29 @@ def base_url() -> str: # Example: https://dev.api.mycompany.com url = os.environ.get("API_BASE_URL") if not url: - raise RuntimeError("Set API_BASE_URL") + url = "http://neptun.fritz.box" + # raise RuntimeError("Set API_BASE_URL") return url.rstrip("/") @pytest.fixture(scope="session") -def jwt_token(base_url: str) -> str: +def login_payload() -> dict[str, str]: username = os.environ.get("API_USERNAME") + if not username: + username = "Londo" password = os.environ.get("API_PASSWORD") - if not username or not password: - raise RuntimeError("Set API_USERNAME and API_PASSWORD") + if not password: + password = "Hallowach" + # if not username or not password: + # raise RuntimeError("Set API_USERNAME and API_PASSWORD") + return {"username": username, "password": password} +@pytest.fixture(scope="session") +def jwt_token(base_url: str, login_payload: dict[str, str]) -> str: # Adapt these to your auth endpoint + response shape: - login_path = os.environ.get("API_LOGIN_PATH", "/auth/login") + login_path = os.environ.get("API_LOGIN_PATH", "/login") resp = requests.post( f"{base_url}{login_path}", - json={"username": username, "password": password}, + json=login_payload, timeout=30, ) resp.raise_for_status() diff --git a/src/server/tests/contract/test_openapi_fuzz.py b/src/server/tests/contract/test_openapi_fuzz.py index 2ab43ef..611cf32 100644 --- a/src/server/tests/contract/test_openapi_fuzz.py +++ b/src/server/tests/contract/test_openapi_fuzz.py @@ -1,10 +1,18 @@ import schemathesis -schema = schemathesis.from_path("../../misc/BreCalApi.yaml") +schema = schemathesis.openapi.from_path("../../../misc/BreCalApi.yaml") @schema.parametrize() -def test_api_conformance(case, base_url: str, auth_headers: dict[str, str]) -> None: +def test_api_conformance( + case, + base_url: str, + auth_headers: dict[str, str], + login_payload: dict[str, str], +) -> None: # Calls your real service: - response = case.call(base_url=base_url, headers=auth_headers) + if case.path == "/login" and case.method.upper() == "POST": + response = case.call(base_url=base_url, json=login_payload) + else: + response = case.call(base_url=base_url, headers=auth_headers) # Validates status code, headers, and body against the OpenAPI schema: - case.validate_response(response) \ No newline at end of file + case.validate_response(response) diff --git a/src/server/tests/pytest.ini b/src/server/tests/pytest.ini new file mode 100644 index 0000000..c2cf0ba --- /dev/null +++ b/src/server/tests/pytest.ini @@ -0,0 +1,3 @@ +[pytest] +addopts = -ra +testpaths = tests \ No newline at end of file