新增5个GUI测试模块,覆盖所有主要功能: - test_login_gui.py: 登录和密码管理测试(7个测试) - test_stock_gui.py: 库存管理测试(4个测试) - test_raw_material_gui.py: 原料管理测试(7个测试) - test_garment_gui.py: 款式管理测试(2个测试) - test_purchase_order_gui.py: 采购单生成测试(2个测试) 测试特点: - 真实GUI交互测试(填写表单、点击按钮、搜索过滤) - 业务逻辑验证(重复数据拒绝、空值验证、计算正确性) - 独立测试环境(临时数据库,自动清理) - 自动化消息框(Mock QMessageBox) 总计22个GUI测试,全部通过 ✓ 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
262 lines
8.6 KiB
Python
262 lines
8.6 KiB
Python
"""
|
|
数据库模块测试
|
|
"""
|
|
|
|
import unittest
|
|
import tempfile
|
|
import os
|
|
from database import (
|
|
DatabaseManager, get_db_connection, get_fabric_categories,
|
|
get_fabric_types_by_category, get_fabric_models_by_category_type,
|
|
get_password, update_password
|
|
)
|
|
|
|
|
|
class TestDatabaseManager(unittest.TestCase):
|
|
|
|
def setUp(self):
|
|
self.temp_dir = tempfile.mkdtemp()
|
|
self.db_path = os.path.join(self.temp_dir, "test.db")
|
|
self.db_manager = DatabaseManager(self.db_path)
|
|
|
|
def tearDown(self):
|
|
self.db_manager = None
|
|
import gc
|
|
gc.collect()
|
|
try:
|
|
if os.path.exists(self.db_path):
|
|
os.remove(self.db_path)
|
|
os.rmdir(self.temp_dir)
|
|
except:
|
|
pass
|
|
|
|
def test_init_db_creates_tables(self):
|
|
with self.db_manager.get_conn() as conn:
|
|
cursor = conn.execute("SELECT name FROM sqlite_master WHERE type='table'")
|
|
tables = [row[0] for row in cursor.fetchall()]
|
|
|
|
self.assertIn("fabrics", tables)
|
|
self.assertIn("garments", tables)
|
|
self.assertIn("garment_materials", tables)
|
|
self.assertIn("admin_settings", tables)
|
|
self.assertIn("fabric_stock_in", tables)
|
|
self.assertIn("fabric_consumption", tables)
|
|
|
|
def test_default_passwords_initialized(self):
|
|
admin_pwd = self.db_manager.get_setting("admin_password")
|
|
user_pwd = self.db_manager.get_setting("user_password")
|
|
|
|
self.assertEqual(admin_pwd, "123456")
|
|
self.assertEqual(user_pwd, "123456")
|
|
|
|
def test_get_setting_returns_none_for_missing_key(self):
|
|
result = self.db_manager.get_setting("nonexistent_key")
|
|
self.assertIsNone(result)
|
|
|
|
def test_set_setting(self):
|
|
result = self.db_manager.set_setting("test_key", "test_value")
|
|
self.assertTrue(result)
|
|
|
|
value = self.db_manager.get_setting("test_key")
|
|
self.assertEqual(value, "test_value")
|
|
|
|
def test_set_setting_overwrites_existing(self):
|
|
self.db_manager.set_setting("test_key", "value1")
|
|
self.db_manager.set_setting("test_key", "value2")
|
|
|
|
value = self.db_manager.get_setting("test_key")
|
|
self.assertEqual(value, "value2")
|
|
|
|
|
|
class TestFabricOperations(unittest.TestCase):
|
|
|
|
def setUp(self):
|
|
self.temp_dir = tempfile.mkdtemp()
|
|
self.db_path = os.path.join(self.temp_dir, "test.db")
|
|
self.db_manager = DatabaseManager(self.db_path)
|
|
self._insert_test_fabrics()
|
|
|
|
def tearDown(self):
|
|
self.db_manager = None
|
|
import gc
|
|
gc.collect()
|
|
try:
|
|
if os.path.exists(self.db_path):
|
|
os.remove(self.db_path)
|
|
os.rmdir(self.temp_dir)
|
|
except:
|
|
pass
|
|
|
|
def _insert_test_fabrics(self):
|
|
with self.db_manager.get_conn() as conn:
|
|
conn.execute("""
|
|
INSERT INTO fabrics (model, category, fabric_type, supplier, color, unit)
|
|
VALUES ('F001', '布料', '棉布', '供应商A', '红色', '米')
|
|
""")
|
|
conn.execute("""
|
|
INSERT INTO fabrics (model, category, fabric_type, supplier, color, unit)
|
|
VALUES ('F002', '布料', '丝绸', '供应商B', '蓝色', '码')
|
|
""")
|
|
conn.execute("""
|
|
INSERT INTO fabrics (model, category, fabric_type, supplier, color, unit)
|
|
VALUES ('F003', '辅料', '拉链', '供应商C', '黑色', '个')
|
|
""")
|
|
conn.commit()
|
|
|
|
def test_get_fabric_categories(self):
|
|
categories = get_fabric_categories(self.db_path)
|
|
|
|
self.assertIn("布料", categories)
|
|
self.assertIn("辅料", categories)
|
|
self.assertIn("其他", categories)
|
|
|
|
def test_get_fabric_types_by_category(self):
|
|
types = get_fabric_types_by_category(self.db_path, "布料")
|
|
|
|
self.assertIn("棉布", types)
|
|
self.assertIn("丝绸", types)
|
|
self.assertNotIn("拉链", types)
|
|
|
|
def test_get_fabric_types_by_category_empty(self):
|
|
types = get_fabric_types_by_category(self.db_path, "不存在的类目")
|
|
self.assertEqual(types, [])
|
|
|
|
|
|
class TestPasswordOperations(unittest.TestCase):
|
|
|
|
def setUp(self):
|
|
self.temp_dir = tempfile.mkdtemp()
|
|
self.db_path = os.path.join(self.temp_dir, "test.db")
|
|
self.db_manager = DatabaseManager(self.db_path)
|
|
|
|
def tearDown(self):
|
|
self.db_manager = None
|
|
import gc
|
|
gc.collect()
|
|
try:
|
|
if os.path.exists(self.db_path):
|
|
os.remove(self.db_path)
|
|
os.rmdir(self.temp_dir)
|
|
except:
|
|
pass
|
|
|
|
def test_get_password_default(self):
|
|
admin_pwd = get_password(self.db_path, "admin")
|
|
user_pwd = get_password(self.db_path, "user")
|
|
|
|
self.assertEqual(admin_pwd, "123456")
|
|
self.assertEqual(user_pwd, "123456")
|
|
|
|
def test_update_password(self):
|
|
result = update_password(self.db_path, "admin", "newpassword")
|
|
self.assertTrue(result)
|
|
|
|
new_pwd = get_password(self.db_path, "admin")
|
|
self.assertEqual(new_pwd, "newpassword")
|
|
|
|
|
|
class TestStockOperations(unittest.TestCase):
|
|
|
|
def setUp(self):
|
|
self.temp_dir = tempfile.mkdtemp()
|
|
self.db_path = os.path.join(self.temp_dir, "test.db")
|
|
self.db_manager = DatabaseManager(self.db_path)
|
|
self._setup_test_data()
|
|
|
|
def tearDown(self):
|
|
self.db_manager = None
|
|
import gc
|
|
gc.collect()
|
|
try:
|
|
if os.path.exists(self.db_path):
|
|
os.remove(self.db_path)
|
|
os.rmdir(self.temp_dir)
|
|
except:
|
|
pass
|
|
|
|
def _setup_test_data(self):
|
|
with self.db_manager.get_conn() as conn:
|
|
conn.execute("""
|
|
INSERT INTO fabrics (model, category, unit)
|
|
VALUES ('F001', '布料', '米')
|
|
""")
|
|
conn.execute("""
|
|
INSERT INTO fabric_stock_in (model, quantity, unit, purchase_date)
|
|
VALUES ('F001', 100, '米', '2024-01-01')
|
|
""")
|
|
conn.execute("""
|
|
INSERT INTO fabric_stock_in (model, quantity, unit, purchase_date)
|
|
VALUES ('F001', 50, '米', '2024-01-02')
|
|
""")
|
|
conn.execute("""
|
|
INSERT INTO fabric_consumption (model, consume_quantity, unit, consume_date, style_number, quantity_made, loss_rate)
|
|
VALUES ('F001', 30, '米', '2024-01-03', 'G001', 10, 0.05)
|
|
""")
|
|
conn.commit()
|
|
|
|
def test_stock_calculation(self):
|
|
with self.db_manager.get_conn() as conn:
|
|
cursor = conn.execute("""
|
|
SELECT current_stock FROM fabric_stock_view WHERE model = 'F001'
|
|
""")
|
|
row = cursor.fetchone()
|
|
|
|
self.assertEqual(row[0], 120)
|
|
|
|
|
|
class TestGarmentOperations(unittest.TestCase):
|
|
|
|
def setUp(self):
|
|
self.temp_dir = tempfile.mkdtemp()
|
|
self.db_path = os.path.join(self.temp_dir, "test.db")
|
|
self.db_manager = DatabaseManager(self.db_path)
|
|
|
|
def tearDown(self):
|
|
self.db_manager = None
|
|
import gc
|
|
gc.collect()
|
|
try:
|
|
if os.path.exists(self.db_path):
|
|
os.remove(self.db_path)
|
|
os.rmdir(self.temp_dir)
|
|
except:
|
|
pass
|
|
|
|
def test_insert_garment(self):
|
|
with self.db_manager.get_conn() as conn:
|
|
conn.execute("""
|
|
INSERT INTO garments (style_number, image_path)
|
|
VALUES ('G001', 'images/g001.jpg')
|
|
""")
|
|
conn.commit()
|
|
|
|
cursor = conn.execute("SELECT * FROM garments WHERE style_number = 'G001'")
|
|
row = cursor.fetchone()
|
|
|
|
self.assertIsNotNone(row)
|
|
self.assertEqual(row[0], 'G001')
|
|
|
|
def test_insert_garment_materials(self):
|
|
with self.db_manager.get_conn() as conn:
|
|
conn.execute("""
|
|
INSERT INTO garments (style_number) VALUES ('G001')
|
|
""")
|
|
conn.execute("""
|
|
INSERT INTO garment_materials (style_number, category, fabric_type, model, usage_per_piece, unit)
|
|
VALUES ('G001', '布料', '棉布', 'F001', 1.5, '米')
|
|
""")
|
|
conn.commit()
|
|
|
|
cursor = conn.execute("""
|
|
SELECT * FROM garment_materials WHERE style_number = 'G001'
|
|
""")
|
|
row = cursor.fetchone()
|
|
|
|
self.assertIsNotNone(row)
|
|
self.assertEqual(row[2], '布料')
|
|
self.assertEqual(row[5], 1.5)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
unittest.main()
|