添加PyQt GUI自动化测试套件
新增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>
This commit is contained in:
272
test/test_stock.py
Normal file
272
test/test_stock.py
Normal file
@@ -0,0 +1,272 @@
|
||||
"""
|
||||
库存管理模块测试 - 测试入库和库存查询功能
|
||||
"""
|
||||
|
||||
import unittest
|
||||
import os
|
||||
import tempfile
|
||||
import gc
|
||||
from datetime import datetime
|
||||
from database import DatabaseManager, get_db_connection
|
||||
|
||||
|
||||
class TestStock(unittest.TestCase):
|
||||
"""库存管理测试类"""
|
||||
|
||||
def setUp(self):
|
||||
self.temp_dir = tempfile.mkdtemp()
|
||||
self.db_path = os.path.join(self.temp_dir, "test_stock.db")
|
||||
self.db_manager = DatabaseManager(self.db_path)
|
||||
self.conn = None
|
||||
self._setup_test_data()
|
||||
|
||||
def tearDown(self):
|
||||
if self.conn:
|
||||
try:
|
||||
self.conn.close()
|
||||
except:
|
||||
pass
|
||||
gc.collect()
|
||||
try:
|
||||
if os.path.exists(self.db_path):
|
||||
os.remove(self.db_path)
|
||||
if os.path.exists(self.temp_dir):
|
||||
os.rmdir(self.temp_dir)
|
||||
except:
|
||||
pass
|
||||
|
||||
def get_conn(self):
|
||||
self.conn = get_db_connection(self.db_path)
|
||||
return self.conn
|
||||
|
||||
def _setup_test_data(self):
|
||||
"""准备测试数据"""
|
||||
with get_db_connection(self.db_path) as conn:
|
||||
conn.execute('''
|
||||
INSERT INTO fabrics (model, category, supplier, color, unit, timestamp)
|
||||
VALUES (?, ?, ?, ?, ?, datetime('now'))
|
||||
''', ("STOCK-001", "布料", "供应商A", "白色", "米"))
|
||||
conn.commit()
|
||||
|
||||
# ========== 入库测试 ==========
|
||||
|
||||
def test_stock_in_basic(self):
|
||||
"""测试基本入库功能"""
|
||||
with self.get_conn() as conn:
|
||||
conn.execute('''
|
||||
INSERT INTO fabric_stock_in (model, quantity, unit, purchase_date, note)
|
||||
VALUES (?, ?, ?, ?, ?)
|
||||
''', ("STOCK-001", 100.0, "米", "2024-01-01", "测试入库"))
|
||||
conn.commit()
|
||||
cursor = conn.execute(
|
||||
"SELECT quantity, note FROM fabric_stock_in WHERE model = ?",
|
||||
("STOCK-001",)
|
||||
)
|
||||
row = cursor.fetchone()
|
||||
self.assertEqual(row[0], 100.0)
|
||||
self.assertEqual(row[1], "测试入库")
|
||||
|
||||
def test_stock_in_multiple(self):
|
||||
"""测试多次入库"""
|
||||
with self.get_conn() as conn:
|
||||
conn.execute('''
|
||||
INSERT INTO fabric_stock_in (model, quantity, unit, purchase_date)
|
||||
VALUES (?, ?, ?, ?)
|
||||
''', ("STOCK-001", 50.0, "米", "2024-01-01"))
|
||||
conn.execute('''
|
||||
INSERT INTO fabric_stock_in (model, quantity, unit, purchase_date)
|
||||
VALUES (?, ?, ?, ?)
|
||||
''', ("STOCK-001", 30.0, "米", "2024-01-02"))
|
||||
conn.commit()
|
||||
cursor = conn.execute(
|
||||
"SELECT SUM(quantity) FROM fabric_stock_in WHERE model = ?",
|
||||
("STOCK-001",)
|
||||
)
|
||||
total = cursor.fetchone()[0]
|
||||
self.assertEqual(total, 80.0)
|
||||
|
||||
def test_stock_in_with_note(self):
|
||||
"""测试带备注的入库"""
|
||||
with self.get_conn() as conn:
|
||||
conn.execute('''
|
||||
INSERT INTO fabric_stock_in (model, quantity, unit, purchase_date, note)
|
||||
VALUES (?, ?, ?, ?, ?)
|
||||
''', ("STOCK-001", 25.5, "米", "2024-01-15", "批次号:B001"))
|
||||
conn.commit()
|
||||
cursor = conn.execute(
|
||||
"SELECT note FROM fabric_stock_in WHERE model = ? AND quantity = ?",
|
||||
("STOCK-001", 25.5)
|
||||
)
|
||||
row = cursor.fetchone()
|
||||
self.assertEqual(row[0], "批次号:B001")
|
||||
|
||||
# ========== 消耗测试 ==========
|
||||
|
||||
def test_consumption_basic(self):
|
||||
"""测试基本消耗记录"""
|
||||
with self.get_conn() as conn:
|
||||
conn.execute('''
|
||||
INSERT INTO fabric_consumption
|
||||
(style_number, model, single_usage, quantity_made, loss_rate, consume_quantity, consume_date, unit)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
||||
''', ("G001", "STOCK-001", 0.5, 100, 0.05, 52.5, "2024-01-10", "米"))
|
||||
conn.commit()
|
||||
cursor = conn.execute(
|
||||
"SELECT consume_quantity FROM fabric_consumption WHERE model = ?",
|
||||
("STOCK-001",)
|
||||
)
|
||||
row = cursor.fetchone()
|
||||
self.assertEqual(row[0], 52.5)
|
||||
|
||||
def test_consumption_calculation(self):
|
||||
"""测试消耗量计算"""
|
||||
single_usage = 0.5
|
||||
quantity_made = 100
|
||||
loss_rate = 0.05
|
||||
expected = single_usage * quantity_made * (1 + loss_rate)
|
||||
self.assertEqual(expected, 52.5)
|
||||
|
||||
# ========== 库存计算测试 ==========
|
||||
|
||||
def test_stock_remaining_calculation(self):
|
||||
"""测试剩余库存计算"""
|
||||
with self.get_conn() as conn:
|
||||
conn.execute('''
|
||||
INSERT INTO fabric_stock_in (model, quantity, unit, purchase_date)
|
||||
VALUES (?, ?, ?, ?)
|
||||
''', ("STOCK-001", 100.0, "米", "2024-01-01"))
|
||||
conn.execute('''
|
||||
INSERT INTO fabric_consumption
|
||||
(style_number, model, consume_quantity, consume_date, unit)
|
||||
VALUES (?, ?, ?, ?, ?)
|
||||
''', ("G001", "STOCK-001", 30.0, "2024-01-05", "米"))
|
||||
conn.commit()
|
||||
|
||||
cursor_in = conn.execute(
|
||||
"SELECT COALESCE(SUM(quantity), 0) FROM fabric_stock_in WHERE model = ?",
|
||||
("STOCK-001",)
|
||||
)
|
||||
total_in = cursor_in.fetchone()[0]
|
||||
|
||||
cursor_out = conn.execute(
|
||||
"SELECT COALESCE(SUM(consume_quantity), 0) FROM fabric_consumption WHERE model = ?",
|
||||
("STOCK-001",)
|
||||
)
|
||||
total_out = cursor_out.fetchone()[0]
|
||||
|
||||
remaining = total_in - total_out
|
||||
self.assertEqual(remaining, 70.0)
|
||||
|
||||
def test_stock_zero_remaining(self):
|
||||
"""测试库存清零"""
|
||||
with self.get_conn() as conn:
|
||||
conn.execute('''
|
||||
INSERT INTO fabric_stock_in (model, quantity, unit, purchase_date)
|
||||
VALUES (?, ?, ?, ?)
|
||||
''', ("STOCK-001", 50.0, "米", "2024-01-01"))
|
||||
conn.execute('''
|
||||
INSERT INTO fabric_consumption
|
||||
(style_number, model, consume_quantity, consume_date, unit)
|
||||
VALUES (?, ?, ?, ?, ?)
|
||||
''', ("库存清零", "STOCK-001", 50.0, "2024-01-10", "米"))
|
||||
conn.commit()
|
||||
|
||||
cursor_in = conn.execute(
|
||||
"SELECT COALESCE(SUM(quantity), 0) FROM fabric_stock_in WHERE model = ?",
|
||||
("STOCK-001",)
|
||||
)
|
||||
total_in = cursor_in.fetchone()[0]
|
||||
|
||||
cursor_out = conn.execute(
|
||||
"SELECT COALESCE(SUM(consume_quantity), 0) FROM fabric_consumption WHERE model = ?",
|
||||
("STOCK-001",)
|
||||
)
|
||||
total_out = cursor_out.fetchone()[0]
|
||||
|
||||
remaining = total_in - total_out
|
||||
self.assertEqual(remaining, 0.0)
|
||||
|
||||
# ========== 编辑库存并清除历史记录测试 ==========
|
||||
|
||||
def test_edit_stock_and_clear_history(self):
|
||||
"""测试编辑剩余库存并清除历史记录"""
|
||||
with self.get_conn() as conn:
|
||||
conn.execute('''
|
||||
INSERT INTO fabric_stock_in (model, quantity, unit, purchase_date)
|
||||
VALUES (?, ?, ?, ?)
|
||||
''', ("STOCK-001", 100.0, "米", "2024-01-01"))
|
||||
conn.execute('''
|
||||
INSERT INTO fabric_stock_in (model, quantity, unit, purchase_date)
|
||||
VALUES (?, ?, ?, ?)
|
||||
''', ("STOCK-001", 50.0, "米", "2024-01-05"))
|
||||
conn.execute('''
|
||||
INSERT INTO fabric_consumption
|
||||
(style_number, model, consume_quantity, consume_date, unit)
|
||||
VALUES (?, ?, ?, ?, ?)
|
||||
''', ("G001", "STOCK-001", 30.0, "2024-01-10", "米"))
|
||||
conn.commit()
|
||||
|
||||
conn.execute("DELETE FROM fabric_stock_in WHERE model = ?", ("STOCK-001",))
|
||||
conn.execute("DELETE FROM fabric_consumption WHERE model = ?", ("STOCK-001",))
|
||||
new_stock = 80.0
|
||||
conn.execute('''
|
||||
INSERT INTO fabric_stock_in (model, quantity, unit, purchase_date, note)
|
||||
VALUES (?, ?, ?, ?, ?)
|
||||
''', ("STOCK-001", new_stock, "米", datetime.now().strftime('%Y-%m-%d'), "库存盘点调整"))
|
||||
conn.commit()
|
||||
|
||||
cursor_in = conn.execute(
|
||||
"SELECT COUNT(*) FROM fabric_stock_in WHERE model = ?", ("STOCK-001",)
|
||||
)
|
||||
in_count = cursor_in.fetchone()[0]
|
||||
|
||||
cursor_out = conn.execute(
|
||||
"SELECT COUNT(*) FROM fabric_consumption WHERE model = ?", ("STOCK-001",)
|
||||
)
|
||||
out_count = cursor_out.fetchone()[0]
|
||||
|
||||
cursor_qty = conn.execute(
|
||||
"SELECT SUM(quantity) FROM fabric_stock_in WHERE model = ?", ("STOCK-001",)
|
||||
)
|
||||
total_qty = cursor_qty.fetchone()[0]
|
||||
|
||||
self.assertEqual(in_count, 1)
|
||||
self.assertEqual(out_count, 0)
|
||||
self.assertEqual(total_qty, 80.0)
|
||||
|
||||
def test_edit_stock_clear_history_multiple_models(self):
|
||||
"""测试编辑库存时只清除指定型号的历史记录"""
|
||||
with self.get_conn() as conn:
|
||||
conn.execute('''
|
||||
INSERT INTO fabrics (model, category, unit)
|
||||
VALUES (?, ?, ?)
|
||||
''', ("STOCK-002", "布料", "米"))
|
||||
|
||||
conn.execute('''
|
||||
INSERT INTO fabric_stock_in (model, quantity, unit, purchase_date)
|
||||
VALUES (?, ?, ?, ?)
|
||||
''', ("STOCK-001", 100.0, "米", "2024-01-01"))
|
||||
conn.execute('''
|
||||
INSERT INTO fabric_stock_in (model, quantity, unit, purchase_date)
|
||||
VALUES (?, ?, ?, ?)
|
||||
''', ("STOCK-002", 200.0, "米", "2024-01-01"))
|
||||
conn.commit()
|
||||
|
||||
conn.execute("DELETE FROM fabric_stock_in WHERE model = ?", ("STOCK-001",))
|
||||
conn.execute("DELETE FROM fabric_consumption WHERE model = ?", ("STOCK-001",))
|
||||
conn.execute('''
|
||||
INSERT INTO fabric_stock_in (model, quantity, unit, purchase_date, note)
|
||||
VALUES (?, ?, ?, ?, ?)
|
||||
''', ("STOCK-001", 50.0, "米", datetime.now().strftime('%Y-%m-%d'), "库存盘点调整"))
|
||||
conn.commit()
|
||||
|
||||
cursor_002 = conn.execute(
|
||||
"SELECT SUM(quantity) FROM fabric_stock_in WHERE model = ?", ("STOCK-002",)
|
||||
)
|
||||
stock_002 = cursor_002.fetchone()[0]
|
||||
|
||||
self.assertEqual(stock_002, 200.0)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user