e-maks 2 years ago
parent
commit
238bb4bb8a
  1. 37
      .github/workflows/main.yaml
  2. 1
      .gitignore
  3. 74
      tests/e2e/test_bank.py
  4. 27
      tests/unit/test_account.py
  5. 43
      tests/unit/test_customer.py
  6. 68
      tests/unit/test_database.py
  7. 55
      tests/unit/test_transaction.py

37
.github/workflows/main.yaml

@ -1,3 +1,40 @@ @@ -1,3 +1,40 @@
name: lab-testing
# add your pipline description below
on:
pull_request:
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v4
with:
python-version: '3.11.6'
- name: Run image
uses: abatilo/actions-poetry@v2
with:
poetry-version: '1.7.1'
- name: Install dependencies
run: poetry install; poetry add pytest; poetry add pytest-mock;
- name: Run pytest
run: poetry run pytest tests/e2e/test_*.py
push:
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v4
with:
python-version: '3.11.6'
- name: Run image
uses: abatilo/actions-poetry@v2
with:
poetry-version: '1.7.1'
- name: Install dependencies
run: poetry install; poetry add pytest; poetry add pytest-mock;
- name: Run pytest
run: poetry run pytest tests/unit/test_*.py

1
.gitignore vendored

@ -160,3 +160,4 @@ cython_debug/ @@ -160,3 +160,4 @@ cython_debug/
#.idea/
.DS_Store
*.db
/.idea/

74
tests/e2e/test_bank.py

@ -3,4 +3,78 @@ @@ -3,4 +3,78 @@
# - For understanding purposes, you can interact with main.py
# - Create a real life usage scenario for this project and follow the order for testing components
# - Make sure that the test tests almost all of the functionalities of the project.
import os
import pytest
from app.bank import Bank
@pytest.fixture
def bank():
return Bank(db_path='db')
def test_customer_operations(bank):
customer_id = bank.add_customer("Maks", "Universitetskaaya 1")
assert customer_id is not None
customers = bank.get_all_customers()
assert len(customers) >= 1
bank.update_customer_details(customer_id, "Maks New", "Universitetskaaya 1/3")
updated_customer = bank.get_all_customers()[0]
print(updated_customer)
assert updated_customer[1] == "Maks New"
bank.delete_customer(customer_id)
customers_after_delete = bank.get_all_customers()
assert len(customers_after_delete) == 0
def test_account_operations(bank):
customer_id = bank.add_customer("Nikita", "Universitetskaya 1/1")
account_id = bank.open_account(customer_id, "deposit", 1000)
assert account_id is not None
account = bank.get_account(account_id)
assert account[1] == customer_id
bank.deposit_to_account(account_id, 500)
account = bank.get_account(account_id)
assert account[3] == 1500
bank.withdraw_from_account(account_id, 200)
account = bank.get_account(account_id)
assert account[3] == 1300
bank.close_account(account_id)
closed_account = bank.get_account(account_id)
assert closed_account is None
def test_transfer_between_accounts(bank):
customer_id = bank.add_customer("Nikita", "Universitetskaya 1/1")
account1_id = bank.open_account(customer_id, "deposit", 1000)
account2_id = bank.open_account(customer_id, "sending", 2000)
bank.transfer_between_accounts(account1_id, account2_id, 500)
account1 = bank.get_account(account1_id)
account2 = bank.get_account(account2_id)
assert account1[3] == 500
assert account2[3] == 2500
def test_get_account_transactions(bank):
customer_id = bank.add_customer("Nikita", "Universitetskaya 1/1")
account_id = bank.open_account(customer_id, "deposit", 1000)
transactions = bank.get_account_transactions(account_id)
assert len(transactions) == 0
bank.deposit_to_account(account_id, 500)
bank.withdraw_from_account(account_id, 200)
transactions = bank.get_account_transactions(account_id)
assert len(transactions) == 2
@pytest.fixture(scope="session", autouse=True)
def delete_test_database():
db_file = 'db'
yield
if os.path.exists(db_file):
os.remove(db_file)

27
tests/unit/test_account.py

@ -2,3 +2,30 @@ @@ -2,3 +2,30 @@
# - See, app/account.py
# - Test account creation and deletion
# - Use mocks
from app.account import Account
from app.database import Database
import pytest
from unittest.mock import patch
@pytest.fixture
def db():
return Database("")
@patch('app.database.Database')
def test_account_creation(mock_db_class):
mock_db_instance = mock_db_class.return_value
mock_db_instance.add_account.return_value = 26
account = Account(mock_db_instance, customer_id=1, account_type="checking", balance=1000.0)
assert account.account_id == 26
mock_db_instance.add_account.assert_called_once_with(1, "checking", 1000.0)
@patch('app.database.Database')
def test_delete_account(mock_db_class):
mock_db_instance = mock_db_class.return_value
mock_db_instance.add_account.return_value = 26
mock_db_instance.get_account.return_value = (26, 1, "checking", 1000.0)
account = Account(mock_db_instance, customer_id=1, account_type="checking", balance=1000.0)
account.delete_account(account.account_id)
mock_db_instance.delete_account.assert_called_once_with(account.account_id)

43
tests/unit/test_customer.py

@ -3,3 +3,46 @@ @@ -3,3 +3,46 @@
# - Test customer creation, loading, updating and deletion
# - Use mocks
from app.customer import Customer
from app.database import Database
import pytest
from unittest.mock import patch
@pytest.fixture
def db():
return Database('')
@patch('app.database.Database')
def test_customer_initialization(mock_db_class):
mock_db_instance = mock_db_class.return_value
mock_db_instance.add_customer.return_value = 26
customer = Customer(mock_db_instance, name='Maks', address='Universitetskaya 1')
assert customer.customer_id is not None
mock_db_instance.add_customer.assert_called_once_with('Maks', 'Universitetskaya 1')
@patch('app.database.Database')
def test_customer_loading(mock_db_class):
mock_db_instance = mock_db_class.return_value
customer_id = 26
mock_db_instance.get_customer.return_value = (customer_id, 'Maks', 'Universitetskaya 1')
customer = Customer(mock_db_instance, customer_id=customer_id)
assert customer.name == 'Maks'
assert customer.address == 'Universitetskaya 1'
@patch('app.database.Database')
def test_update_customer_details(mock_db_class):
mock_db_instance = mock_db_class.return_value
customer_id = 26
mock_db_instance.add_customer.return_value = customer_id
customer = Customer(mock_db_instance, customer_id=customer_id, name='Maks', address='Universitetskaya 1')
customer.update_details('Maks New', 'Universitetskaya 1/3')
mock_db_instance.update_customer.assert_called_once_with(customer_id, 'Maks New', 'Universitetskaya 1/3')
@patch('app.database.Database')
def test_delete_customer(mock_db_class):
mock_db_instance = mock_db_class.return_value
customer_id = 26
mock_db_instance.add_customer.return_value = customer_id
customer = Customer(mock_db_instance, customer_id=customer_id)
customer.delete_customer()
mock_db_instance.delete_customer.assert_called_once_with(customer_id)

68
tests/unit/test_database.py

@ -3,3 +3,71 @@ @@ -3,3 +3,71 @@
# - Test most of the methods
# - Use mocks in proper parts
from app.database import Database
from unittest.mock import patch
import pytest
@pytest.fixture
def db():
return Database('')
@patch('app.database.Database')
def test_add_customer(mock_db_class):
mock_db_instance = mock_db_class.return_value
mock_db_instance.add_customer.return_value = 1
assert mock_db_instance.add_customer('Maks', 'Universitetskaya 1') == 1
mock_db_instance.add_customer.assert_called_once_with('Maks', 'Universitetskaya 1')
@patch('app.database.Database')
def test_get_customer(mock_db_class):
mock_db_instance = mock_db_class.return_value
mock_db_instance.get_customer.return_value = (1, 'Maks', 'Universitetskaya 1')
customer = mock_db_instance.get_customer(1)
assert customer[1] == 'Maks'
assert customer[2] == 'Universitetskaya 1'
@patch('app.database.Database')
def test_update_customer(mock_db_class):
mock_db_instance = mock_db_class.return_value
mock_db_instance.add_customer.return_value = 1
mock_db_instance.get_customer.return_value = (1, 'Maks New', 'Universitetskaya 1/3')
customer_id = mock_db_instance.add_customer('Maks', 'Universitetskaya 1')
mock_db_instance.update_customer(customer_id, 'Maks New', 'Universitetskaya 1/3')
updated_customer = mock_db_instance.get_customer(customer_id)
assert updated_customer[1] == 'Maks New'
assert updated_customer[2] == 'Universitetskaya 1/3'
@patch('app.database.Database')
def test_delete_customer(mock_db_class):
mock_db_instance = mock_db_class.return_value
mock_db_instance.add_customer.return_value = 1
mock_db_instance.get_customer.return_value = None
customer_id = mock_db_instance.add_customer('Maks', 'Universitetskaya 1')
mock_db_instance.delete_customer(customer_id)
deleted_customer = mock_db_instance.get_customer(customer_id)
assert deleted_customer is None
@patch('app.database.Database')
def test_add_account(mock_db_class):
mock_db_instance = mock_db_class.return_value
mock_db_instance.add_account.return_value = 1
customer_id = mock_db_class.add_customer('Maks', 'Universitetskaya 1')
account_id = mock_db_class.add_account(customer_id, 'deposit', 1000.00)
assert account_id is not None
@patch('app.database.Database')
def test_get_account(mock_db_class):
mock_db_instance = mock_db_class.return_value
mock_db_instance.add_customer.return_value = 1
mock_db_instance.add_account.return_value = 1
mock_db_instance.get_account.return_value = (1, 1, 'deposit', 1000.00)
customer_id = mock_db_instance.add_customer('Maks', 'Universitetskaya 1')
account_id = mock_db_instance.add_account(customer_id, 'deposit', 1000.00)
retrieved_account = mock_db_instance.get_account(account_id)
assert retrieved_account[2] == 'deposit'
assert retrieved_account[3] == 1000.00
@patch('app.database.Database.add_transaction')
def test_add_transaction(mock_add_transaction, db):
db.add_transaction(1, 2, 100, 'deposit')
mock_add_transaction.assert_called_once_with(1, 2, 100, 'deposit')

55
tests/unit/test_transaction.py

@ -3,3 +3,58 @@ @@ -3,3 +3,58 @@
# - Test transaction with different types - deposit, withdraw and transfer
# - Use mocks accordingly
from app.transaction import Transaction
from app.database import Database
import pytest
from unittest.mock import patch
@pytest.fixture
def mock_database():
return Database("")
@patch('app.database.Database')
def test_deposit_positive_amount(mock_db_class):
mock_db_instance = mock_db_class.return_value
transaction = Transaction(mock_db_instance)
account_id = 1
amount = 500
initial_balance = 1000
mock_db_instance.get_account.return_value = (account_id, None, None, initial_balance)
transaction.deposit(account_id, amount)
mock_db_instance.get_account.assert_called_once_with(account_id)
mock_db_instance.update_account_balance.assert_called_once_with(account_id, initial_balance + amount)
mock_db_instance.add_transaction.assert_called_once_with(None, account_id, amount, "deposit")
@patch('app.database.Database')
def test_withdraw_positive_amount(mock_db_class):
mock_db_instance = mock_db_class.return_value
transaction = Transaction(mock_db_instance)
account_id = 1
amount = 500
initial_balance = 1000
mock_db_instance.get_account.return_value = (account_id, None, None, initial_balance)
transaction.withdraw(account_id, amount)
mock_db_instance.get_account.assert_called_once_with(account_id)
mock_db_instance.update_account_balance.assert_called_once_with(account_id, initial_balance - amount)
mock_db_instance.add_transaction.assert_called_once_with(account_id, None, amount, "withdrawal")
@patch('app.database.Database')
def test_transfer_positive_amount(mock_db_class):
mock_db_instance = mock_db_class.return_value
transaction = Transaction(mock_db_instance)
from_account_id = 1
to_account_id = 2
amount = 500
initial_balance_from = 1000
initial_balance_to = 2000
mock_db_instance.get_account.side_effect = [
(from_account_id, None, None, initial_balance_from),
(to_account_id, None, None, initial_balance_to)
]
transaction.transfer(from_account_id, to_account_id, amount)
mock_db_instance.get_account.assert_any_call(from_account_id)
mock_db_instance.get_account.assert_any_call(to_account_id)
mock_db_instance.update_account_balance.assert_any_call(from_account_id, initial_balance_from - amount)
mock_db_instance.update_account_balance.assert_any_call(to_account_id, initial_balance_to + amount)
mock_db_instance.add_transaction.assert_called_once_with(from_account_id, to_account_id, amount, "transfer")
Loading…
Cancel
Save