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
This commit is contained in:
parent
0522c5660e
commit
a7244942ed
@ -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"
|
||||
|
||||
@ -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()
|
||||
|
||||
27
tests/integration/test_int_genre.py
Normal file
27
tests/integration/test_int_genre.py
Normal file
@ -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)
|
||||
|
||||
58
tests/unit/test_unit_genre.py
Normal file
58
tests/unit/test_unit_genre.py
Normal file
@ -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'<tr id="genre-') == 2
|
||||
|
||||
# test case: post request
|
||||
response = client.post("/genre")
|
||||
assert response.status_code == 405
|
||||
|
||||
|
||||
def test_genre_create(client, db, mocker):
|
||||
"""Test view create() from genre.py."""
|
||||
|
||||
# mock database function
|
||||
mocker.patch("the_works.database.db.session.add")
|
||||
|
||||
# test a POST request with good data
|
||||
response = client.post("/genre/create", data={"form_Genre": "Testname"}, follow_redirects=True)
|
||||
# exactly 1 redirect
|
||||
assert len(response.history) == 1
|
||||
# redirect to the right page
|
||||
assert response.request.path == "/genre/all"
|
||||
assert response.status_code == 200
|
||||
|
||||
# test a POST request with no form data
|
||||
with pytest.raises(ValueError) as excinfo:
|
||||
response = client.post("/genre/create", data={})
|
||||
assert "value can't be empty" in str(excinfo.value)
|
||||
|
||||
# test a POST request with bad form data
|
||||
with pytest.raises(ValueError) as excinfo:
|
||||
response = client.post("/genre/create", data={"wrong_key": "Genrename"})
|
||||
assert "value can't be empty" in str(excinfo.value)
|
||||
|
||||
# test a POST request with empty form data
|
||||
with pytest.raises(ValueError) as excinfo:
|
||||
response = client.post("/genre/create", data={"form_genre": ""})
|
||||
assert "value can't be empty" in str(excinfo.value)
|
||||
|
||||
# test a GET request
|
||||
response = client.get("/genre/create", query_string={"form_Genre": "GET-Genre"})
|
||||
assert response.status_code == 405
|
||||
|
||||
4
tests/unit/test_unit_home.py
Normal file
4
tests/unit/test_unit_home.py
Normal file
@ -0,0 +1,4 @@
|
||||
def test_home_startpage(client):
|
||||
response = client.get("/")
|
||||
assert response.status_code == 200
|
||||
assert response.data.startswith(b"<!DOCTYPE html>\n")
|
||||
Loading…
Reference in New Issue
Block a user