From a7244942ed94c3c631736e1f9a3df36987974d07 Mon Sep 17 00:00:00 2001 From: eclipse Date: Thu, 24 Jul 2025 10:49:01 +0200 Subject: [PATCH] extended and improved tests; unit tests now mock the DB, integration tests use an empty DB with test values that is reset for each test function --- .flaskenv | 2 +- tests/conftest.py | 10 +++++ tests/integration/test_int_genre.py | 27 ++++++++++++++ tests/unit/test_unit_genre.py | 58 +++++++++++++++++++++++++++++ tests/unit/test_unit_home.py | 4 ++ 5 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 tests/integration/test_int_genre.py create mode 100644 tests/unit/test_unit_genre.py create mode 100644 tests/unit/test_unit_home.py diff --git a/.flaskenv b/.flaskenv index 2081c72..6d1f318 100644 --- a/.flaskenv +++ b/.flaskenv @@ -4,7 +4,7 @@ FLASK_APP = "the_works" FLASK_ENV = "development" FLASK_SECRET_KEY = "f8148ee5d95b0a67122b1cab9993f637a6bf29528f584a9f1575af1a55566748" FLASK_TESTING = False -FLASK_MAX_CONTENT_LENGTH = 1024 * 1024 +#FLASK_MAX_CONTENT_LENGTH = 1024 * 1024 FLASK_DEBUG = True FLASK_SQLALCHEMY_DATABASE_URI = "sqlite:///../the_works.sqlite" diff --git a/tests/conftest.py b/tests/conftest.py index e1ffdf8..6f38df7 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,5 +1,6 @@ import pytest from the_works import create_app +from the_works.database import db as _db TEST_DATABASE_URI = "sqlite:///:memory:" @@ -8,6 +9,7 @@ def app(): test_config = { "ENV": "Testing", "SQLALCHEMY_DATABASE_URI": TEST_DATABASE_URI, + "SECRET_KEY": "This is my very secret key", "TESTING": True } app = create_app(test_config) @@ -19,6 +21,14 @@ def app(): # clean up / reset resources here +@pytest.fixture(scope="function") +def db(app): + with app.app_context(): + yield _db + _db.drop_all() + _db.create_all() + + @pytest.fixture() def client(app): return app.test_client() diff --git a/tests/integration/test_int_genre.py b/tests/integration/test_int_genre.py new file mode 100644 index 0000000..d337998 --- /dev/null +++ b/tests/integration/test_int_genre.py @@ -0,0 +1,27 @@ +from sqlalchemy import select +from the_works.database import db +from the_works.models import Genre +from sqlalchemy.exc import IntegrityError +import pytest + +def test_genre_create(client, app): + """Integrated testing of adding a Genre record.""" + response = client.post("/genre/create", data={"form_Genre": "Test-Genre"}, follow_redirects=True) + + # assert there was exactly 1 redirect + assert len(response.history) == 1 + # assert the redirect led to the correct page + assert response.request.path == "/genre/all" + assert response.status_code == 200 + + # assert record was successfully added to DB + with app.app_context(): + genre = db.session.scalars(select(Genre).where(Genre.Genre == "Test-Genre")).all() + assert len(genre) == 1 + assert isinstance(genre[0], Genre) + + # assert uniqueness of records + with pytest.raises(IntegrityError) as excinfo: + response = client.post("/genre/create", data={"form_Genre": "Test-Genre"}) + assert "UNIQUE constraint failed" in str(excinfo.value) + diff --git a/tests/unit/test_unit_genre.py b/tests/unit/test_unit_genre.py new file mode 100644 index 0000000..eaee142 --- /dev/null +++ b/tests/unit/test_unit_genre.py @@ -0,0 +1,58 @@ +from the_works.models import Genre +import pytest + + +def test_genre_all(client, db, mocker): + """Test view all() from genre.py.""" + + # mock database function + # Note: The original method returns an sqlalchemy.engine.Result.ScalarResult, not a list, but the template code + # uses the return value in a way that works for both ScalarResult and list + mocker.patch("the_works.database.db.session.scalars", return_value=[ + Genre(ID=4, Genre="bla"), + Genre(ID=26, Genre="blubb") + ]) + + # test case: get request + response = client.get("/genre") + assert response.status_code == 200 + assert response.data.count(b'\n")