#11 REFACTOR: Moved all tests into test classes
This commit is contained in:
parent
68f738a241
commit
7a9bc61d04
@ -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()
|
||||||
|
@ -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
39
tests/base_test.py
Normal 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
|
@ -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
|
||||||
|
@ -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
|
|
41
tests/functional/test_pages.py
Normal file
41
tests/functional/test_pages.py
Normal 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
|
8
tests/unit/database/database_test_class.py
Normal file
8
tests/unit/database/database_test_class.py
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
from tests.base_test import TestBase
|
||||||
|
|
||||||
|
|
||||||
|
class TestDatabase(TestBase):
|
||||||
|
""" Class that controls the
|
||||||
|
testing of the WMGZON database
|
||||||
|
"""
|
||||||
|
pass
|
@ -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__
|
|
||||||
|
@ -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__
|
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user