#11 REFACTOR: Moved all tests into test classes

This commit is contained in:
Luke Else 2024-02-23 21:15:06 +00:00
parent 68f738a241
commit 7a9bc61d04
13 changed files with 210 additions and 188 deletions

1
pep8.bat Normal file
View File

@ -0,0 +1 @@
autopep8 --exclude '*/.*/*' --in-place --recursive .

View File

@ -37,11 +37,6 @@ def create_connection(path: str, filename: str):
conn.close() conn.close()
# Ensure a directory is created given a path to it
if __name__ == "__main__":
run()
def run(): def run():
""" Create the database for the application""" """ Create the database for the application"""
dir = r"./data/" dir = r"./data/"
@ -55,3 +50,8 @@ def run():
remove_file(dir + db_name) remove_file(dir + db_name)
create_connection(dir, db_name) create_connection(dir, db_name)
# Ensure a directory is created given a path to it
if __name__ == "__main__":
run()

View File

@ -1,28 +0,0 @@
import pytest
import os
from scripts.create_database import run
from app import app
from dotenv import load_dotenv
from flask.testing import FlaskClient
# Setup test environment variables
load_dotenv()
# Capture environment variables at start of testing so we can
# Monitor current setting during tests
old_env = os.environ.get("ENVIRON")
os.environ["ENVIRON"] = "test"
run()
@pytest.fixture(scope="module")
def test_client() -> FlaskClient:
""" Enables tests to create requests to the web app
"""
os.environ['CONFIG_TYPE'] = 'config.TestingConfig'
with app.test_client() as testing_client:
with app.app_context():
yield testing_client

39
tests/base_test.py Normal file
View File

@ -0,0 +1,39 @@
import pytest
import os
from scripts.create_database import run
from app import app
from dotenv import load_dotenv
from flask.testing import FlaskClient
class TestBase:
""" Base test class that ensures environment variables
and test setup is complete before any other unit tests are run
"""
def setup_class(self):
""" Setup class level resources or configurations
Setup test environment variables
"""
load_dotenv()
# Capture environment variables at start of testing so we can
# Monitor current setting during tests
self.old_env = os.environ.get("ENVIRON")
os.environ["ENVIRON"] = "test"
run()
def teardown_class(self):
""" Teardown class level resources or configurations """
pass
@pytest.fixture(scope="class")
def test_client(self) -> FlaskClient:
""" Enables tests to create requests to the web app
"""
os.environ['CONFIG_TYPE'] = 'config.TestingConfig'
with app.test_client() as testing_client:
with app.app_context():
yield testing_client

View File

@ -1,9 +1,9 @@
import pytest
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
from tests import test_client
from flask.testing import FlaskClient from flask.testing import FlaskClient
from tests.base_test import TestBase
def test_use_case(test_client: FlaskClient): class TestFunctionalRequirements(TestBase):
response = test_client.get('/products/Car Parts') def test_use_case(self, test_client: FlaskClient):
assert response.status_code == 200 response = test_client.get('/products/Car Parts')
assert response.status_code == 200

View File

@ -1,39 +0,0 @@
from flask.testing import FlaskClient
from tests import test_client
import pytest
def test_homepage(test_client: FlaskClient):
""" Tests that the main homepage loads correctly
once the '/' endpoint is hit
"""
response = test_client.get('/')
assert response.status_code == 302
response = test_client.get('/products')
assert response.status_code == 308
def test_products(test_client: FlaskClient):
""" Tests that a product page is displayed when
hitting one of the product endpoints
"""
response = test_client.get('/products/2')
assert response.status_code == 200
response = test_client.get('/products/50')
assert response.status_code == 302
response = test_client.get('/products/Books')
assert response.status_code == 200
def test_admin(test_client: FlaskClient):
""" Tests that the admin pages can be reached and redirect
upon reaching
"""
response = test_client.get('/admin/users/')
assert response.status_code == 302
response = test_client.get('/admin/products/')
assert response.status_code == 302

View File

@ -0,0 +1,41 @@
from flask.testing import FlaskClient
from tests.base_test import TestBase
class TestPages(TestBase):
""" Test class that encapsulates tests for
the main pages on the site
"""
def test_homepage(self, test_client: FlaskClient):
""" Tests that the main homepage loads correctly
once the '/' endpoint is hit
"""
response = test_client.get('/')
assert response.status_code == 302
response = test_client.get('/products')
assert response.status_code == 308
def test_products(self, test_client: FlaskClient):
""" Tests that a product page is displayed when
hitting one of the product endpoints
"""
response = test_client.get('/products/2')
assert response.status_code == 200
response = test_client.get('/products/50')
assert response.status_code == 302
response = test_client.get('/products/Books')
assert response.status_code == 200
def test_admin(self, test_client: FlaskClient):
""" Tests that the admin pages can be reached and redirect
upon reaching
"""
response = test_client.get('/admin/users/')
assert response.status_code == 302
response = test_client.get('/admin/products/')
assert response.status_code == 302

View File

@ -0,0 +1,8 @@
from tests.base_test import TestBase
class TestDatabase(TestBase):
""" Class that controls the
testing of the WMGZON database
"""
pass

View File

@ -1,5 +1,4 @@
import pytest from tests.unit.database.database_test_class import TestDatabase
import sqlite3
from datetime import datetime from datetime import datetime
from controllers.database.product import ProductController from controllers.database.product import ProductController
from models.products.product import Product from models.products.product import Product
@ -15,53 +14,52 @@ product = Product(
1 1
) )
# Tests a new product can be created
class TestProduct(TestDatabase):
""" Class that controls the
testing of the WMGZON database
"""
def test_create_product(): def test_create_product(self):
db = ProductController() """Tests a new product can be created"""
db.create(product) db = ProductController()
db.create(product)
# Tests the database maintains integrity when we try def test_duplicate_product(self):
# and add a product with the same details """ Tests the database maintains integrity when we try
and add a product with the same detail
"""
self.test_create_product()
def test_search_category(self):
""" Tests that products can be refined by category """
db = ProductController()
def test_duplicate_product(): # Check each category for correct amount of test products
test_create_product() assert len(db.read_all("Car Parts")) == 9 + \
2 # Added in previous tests
assert len(db.read_all("Books")) == 9
assert db.read_all("Phones") is None
# Tests that products can be refined by category def test_search_term(self):
""" Tests that products can be refined by search term"""
db = ProductController()
# Check each search term for correct amount of test products
assert len(db.read_all(search_term="Alloy")) == 9
assert len(db.read_all("Car Parts", "tur")) == 2
assert len(db.read_all(search_term="fold")) == 8
assert db.read_all(search_term="Twin") is None
def test_search_category(): def test_read_product(self):
db = ProductController() """ Test we the same product details get returned from the database """
db = ProductController()
# Check each category for correct amount of test products # Test the same product is returned
assert len(db.read_all("Car Parts")) == 9 + 2 # Added in previous tests new_product = db.read("product")
assert len(db.read_all("Books")) == 9 assert isinstance(new_product, list)
assert db.read_all("Phones") is None assert isinstance(new_product[0], Product)
# Update the ID on the item as database assigns new id
# Tests that products can be refined by search term product.id = new_product[0].id
def test_search_term(): assert new_product[0].__dict__ == product.__dict__
db = ProductController()
# Check each search term for correct amount of test products
assert len(db.read_all(search_term="Alloy")) == 9
assert len(db.read_all("Car Parts", "tur")) == 2
assert len(db.read_all(search_term="fold")) == 8
assert db.read_all(search_term="Twin") is None
# Test we the same product details get returned from the database
def test_read_product():
db = ProductController()
# Test the same product is returned
new_product = db.read("product")
assert isinstance(new_product, list)
assert isinstance(new_product[0], Product)
# Update the ID on the item as database assigns new id
product.id = new_product[0].id
assert new_product[0].__dict__ == product.__dict__

View File

@ -1,5 +1,6 @@
import pytest import pytest
import sqlite3 import sqlite3
from tests.unit.database.database_test_class import TestDatabase
from controllers.database.user import UserController from controllers.database.user import UserController
from models.users.customer import Customer from models.users.customer import Customer
from models.users.seller import Seller from models.users.seller import Seller
@ -22,53 +23,53 @@ seller = Seller(
"987654321" "987654321"
) )
# Tests a new user can be created
class TestUsers(TestDatabase):
""" Class to encapsulate all of the user
datbase tests
"""
def test_create_user(): def test_create_user(self):
db = UserController() """ Tests a new user can be created """
db.create(customer) db = UserController()
# Tests the database maintains integrity when we try
# and add a user with the same details
def test_duplicate_user():
db = UserController()
with pytest.raises(sqlite3.IntegrityError):
db.create(customer) db.create(customer)
# Test we the same user details get returned from the database def test_duplicate_user(self):
""" Tests the database maintains integrity when we try
and add a user with the same details
"""
db = UserController()
with pytest.raises(sqlite3.IntegrityError):
db.create(customer)
def test_read_user(self):
""" Test we the same user details get returned from the database """
db = UserController()
def test_read_user(): # Test the same user is returned
db = UserController() user = db.read(customer.username)
assert isinstance(user, Customer)
# Test the same user is returned # Update the ID on the item as database assigns new id
user = db.read(customer.username) customer.id = user.id
assert isinstance(user, Customer) assert user.__dict__ == customer.__dict__
# Update the ID on the item as database assigns new id def test_create_seller(self):
customer.id = user.id """ Tests a new seller can be created """
assert user.__dict__ == customer.__dict__ db = UserController()
db.create(seller)
def test_read_seller(self):
""" Test that the same seller details get
returned from the database
"""
db = UserController()
# Tests a new seller can be created # Test the same user is returned
def test_create_seller(): user = db.read(seller.username)
db = UserController() assert isinstance(user, Seller)
db.create(seller)
# Test that the same seller details get returned from the database # Update the ID on the item as database assigns new id
seller.id = user.id
user.store = ""
def test_read_seller(): assert user.__dict__ == seller.__dict__
db = UserController()
# Test the same user is returned
user = db.read(seller.username)
assert isinstance(user, Seller)
# Update the ID on the item as database assigns new id
seller.id = user.id
user.store = ""
assert user.__dict__ == seller.__dict__

View File

@ -1,31 +1,31 @@
from tests.base_test import TestBase
from os import environ from os import environ
from warnings import warn from warnings import warn
from tests import old_env
# Tests environment variables used within the projects domain are
# set in the correct environment
VARS = ['ENVIRON', 'APPSECRET', 'FILESTORE']
ENV_STATES = ['test', 'prod']
def test_env_vars(): class TestEnv(TestBase):
""" Test that required environment variables are set """ Tests environment variables used within the projects domain are
ahead of runtime set in the correct environment
""" """
for var in VARS: VARS = ['ENVIRON', 'APPSECRET', 'FILESTORE']
env = environ.get(var)
# Check to see what variable we are comparing ENV_STATES = ['test', 'prod']
if env is None:
warn(f"Variable {var} is not set!")
def test_env_vars(self):
""" Test that required environment variables are set
ahead of runtime
"""
for var in self.VARS:
env = environ.get(var)
def test_environment_var_state(): # Check to see what variable we are comparing
""" Tests that the 'ENVIRON' Environment variable if env is None:
is in a correct state warn(f"Variable {var} is not set!")
"""
var = old_env def test_environment_var_state(self):
assert var is not None """ Tests that the 'ENVIRON' Environment variable
assert (var in ENV_STATES) is in a correct state
"""
var = self.old_env
assert var is not None
assert (var in self.ENV_STATES)

View File

@ -1,11 +1,13 @@
import pycodestyle import pycodestyle
from tests.base_test import TestBase
# Tests files to ensure they conform to pep8 standards # Tests files to ensure they conform to pep8 standards
def test_pep8_conformance(): class TestPep8(TestBase):
"""Test that we conform to PEP8.""" def test_pep8_conformance(self):
pep8style = pycodestyle.StyleGuide() """Test that we conform to PEP8."""
dirs = ["./controllers", "./models", "./scripts", "./tests", "./utils"] pep8style = pycodestyle.StyleGuide()
result = pep8style.check_files(dirs) dirs = ["./controllers", "./models", "./scripts", "./tests", "./utils"]
assert result.total_errors == 0 result = pep8style.check_files(dirs)
assert result.total_errors == 0

View File

@ -1 +0,0 @@
./.venv/Scripts/activate