test: add comprehensive unit test suite
- Add tests/ directory with pytest configuration - Add conftest.py with database fixtures (test_db, sample data) - Add test_core.py: 21 tests for core operations (tablet, user, loan CRUD) - Add test_edge_cases.py: 14 tests for edge cases (duplicates, invalid IDs, etc.) - Add test_minimal_app.py: 11 tests for actual application functions - Update pyproject.toml with pytest and coverage configuration - Total: 46 tests covering core functionality and edge cases Tests cover: - Tablet CRUD operations - User CRUD operations - Loan/return workflows - Duplicate prevention (serial numbers, identifications) - Invalid ID handling - Already loaned device prevention - Non-existent loan handling - Multiple loans per user (one-to-many relationship) - Non-loanable device CRUD operations To run: python3 -m pytest tests/ -v
This commit is contained in:
parent
d3d1fb1b32
commit
83ac67fea2
7 changed files with 1575 additions and 0 deletions
181
tests/conftest.py
Normal file
181
tests/conftest.py
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
"""
|
||||
Pytest configuration and fixtures for Tablet Management System tests
|
||||
"""
|
||||
|
||||
import pytest
|
||||
import sqlite3
|
||||
import os
|
||||
import sys
|
||||
from datetime import datetime
|
||||
|
||||
# Add project root to path for imports
|
||||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def test_db_path():
|
||||
"""Path to test database"""
|
||||
return 'test_tablets.db'
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def init_test_db(test_db_path):
|
||||
"""Initialize a fresh test database with schema"""
|
||||
# Remove existing test database if it exists
|
||||
if os.path.exists(test_db_path):
|
||||
os.remove(test_db_path)
|
||||
|
||||
conn = sqlite3.connect(test_db_path)
|
||||
cursor = conn.cursor()
|
||||
|
||||
# Create tables
|
||||
cursor.execute('''
|
||||
CREATE TABLE IF NOT EXISTS tablets (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
brand TEXT NOT NULL,
|
||||
model TEXT NOT NULL,
|
||||
serial_number TEXT UNIQUE NOT NULL,
|
||||
status TEXT DEFAULT 'available',
|
||||
notes TEXT
|
||||
)
|
||||
''')
|
||||
|
||||
cursor.execute('''
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT NOT NULL,
|
||||
email TEXT,
|
||||
phone TEXT,
|
||||
identification TEXT UNIQUE
|
||||
)
|
||||
''')
|
||||
|
||||
cursor.execute('''
|
||||
CREATE TABLE IF NOT EXISTS loans (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
tablet_id INTEGER NOT NULL,
|
||||
user_id INTEGER NOT NULL,
|
||||
loan_date TEXT NOT NULL,
|
||||
return_date TEXT,
|
||||
status TEXT DEFAULT 'active',
|
||||
FOREIGN KEY (tablet_id) REFERENCES tablets (id),
|
||||
FOREIGN KEY (user_id) REFERENCES users (id)
|
||||
)
|
||||
''')
|
||||
|
||||
cursor.execute('''
|
||||
CREATE TABLE IF NOT EXISTS non_loanable_devices (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
brand TEXT NOT NULL,
|
||||
model TEXT NOT NULL,
|
||||
serial_number TEXT UNIQUE NOT NULL,
|
||||
device_type TEXT NOT NULL,
|
||||
location TEXT,
|
||||
status TEXT DEFAULT 'available',
|
||||
notes TEXT,
|
||||
purchase_date TEXT,
|
||||
purchase_cost REAL
|
||||
)
|
||||
''')
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
yield test_db_path
|
||||
|
||||
# Cleanup: remove test database
|
||||
if os.path.exists(test_db_path):
|
||||
os.remove(test_db_path)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def db_conn(init_test_db):
|
||||
"""Get a database connection to the test database"""
|
||||
conn = sqlite3.connect(init_test_db)
|
||||
conn.row_factory = sqlite3.Row
|
||||
yield conn
|
||||
conn.close()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def sample_tablets(db_conn):
|
||||
"""Insert sample tablets into test database"""
|
||||
cursor = db_conn.cursor()
|
||||
|
||||
tablets = [
|
||||
('Samsung', 'Galaxy Tab S7', 'SN001', 'available'),
|
||||
('Apple', 'iPad Pro', 'SN002', 'available'),
|
||||
('Lenovo', 'Tab P11', 'SN003', 'available'),
|
||||
('Microsoft', 'Surface Pro', 'SN004', 'loaned'),
|
||||
]
|
||||
|
||||
for brand, model, serial, status in tablets:
|
||||
cursor.execute('''
|
||||
INSERT INTO tablets (brand, model, serial_number, status)
|
||||
VALUES (?, ?, ?, ?)
|
||||
''', (brand, model, serial, status))
|
||||
|
||||
db_conn.commit()
|
||||
return tablets
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def sample_users(db_conn):
|
||||
"""Insert sample users into test database"""
|
||||
cursor = db_conn.cursor()
|
||||
|
||||
users = [
|
||||
('John Doe', 'john@example.com', '1234567890', 'ID001'),
|
||||
('Jane Smith', 'jane@example.com', '0987654321', 'ID002'),
|
||||
('Bob Johnson', 'bob@example.com', '5551234567', 'ID003'),
|
||||
]
|
||||
|
||||
for name, email, phone, identification in users:
|
||||
cursor.execute('''
|
||||
INSERT INTO users (name, email, phone, identification)
|
||||
VALUES (?, ?, ?, ?)
|
||||
''', (name, email, phone, identification))
|
||||
|
||||
db_conn.commit()
|
||||
return users
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def sample_loans(db_conn, sample_tablets, sample_users):
|
||||
"""Insert sample loans into test database"""
|
||||
cursor = db_conn.cursor()
|
||||
|
||||
# Get tablet and user IDs
|
||||
cursor.execute("SELECT id FROM tablets WHERE serial_number = 'SN004'")
|
||||
loaned_tablet = cursor.fetchone()
|
||||
|
||||
cursor.execute("SELECT id FROM users WHERE identification = 'ID001'")
|
||||
user1 = cursor.fetchone()
|
||||
|
||||
cursor.execute("SELECT id FROM users WHERE identification = 'ID002'")
|
||||
user2 = cursor.fetchone()
|
||||
|
||||
if loaned_tablet and user1:
|
||||
# Active loan for SN004 to user1
|
||||
loan_date = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
||||
cursor.execute('''
|
||||
INSERT INTO loans (tablet_id, user_id, loan_date, status)
|
||||
VALUES (?, ?, ?, 'active')
|
||||
''', (loaned_tablet['id'], user1['id'], loan_date))
|
||||
|
||||
if user2:
|
||||
# Returned loan for SN001 to user2
|
||||
loan_date = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
||||
return_date = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
||||
cursor.execute('''
|
||||
INSERT INTO loans (tablet_id, user_id, loan_date, return_date, status)
|
||||
VALUES (?, ?, ?, ?, 'returned')
|
||||
''', (1, user2['id'], loan_date, return_date))
|
||||
|
||||
db_conn.commit()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def populated_db(db_conn, sample_tablets, sample_users, sample_loans):
|
||||
"""Database with all sample data loaded"""
|
||||
return db_conn
|
||||
Loading…
Add table
Add a link
Reference in a new issue