添加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:
161
test/test_stock_gui.py
Normal file
161
test/test_stock_gui.py
Normal file
@@ -0,0 +1,161 @@
|
||||
"""
|
||||
库存管理GUI测试模块
|
||||
使用PyQt测试框架测试库存入库和查询功能
|
||||
"""
|
||||
|
||||
import unittest
|
||||
import os
|
||||
import sys
|
||||
import tempfile
|
||||
from PyQt5.QtWidgets import QApplication, QMessageBox, QInputDialog
|
||||
from PyQt5.QtTest import QTest
|
||||
from PyQt5.QtCore import Qt
|
||||
|
||||
# 添加父目录到路径以导入模块
|
||||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
|
||||
from database import DatabaseManager
|
||||
from stock_dialog import StockInDialog
|
||||
|
||||
|
||||
class TestStockGUI(unittest.TestCase):
|
||||
"""库存管理GUI测试类"""
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
"""测试类初始化:创建QApplication实例"""
|
||||
cls.app = QApplication.instance()
|
||||
if cls.app is None:
|
||||
cls.app = QApplication(sys.argv)
|
||||
|
||||
def setUp(self):
|
||||
"""每个测试前准备:创建临时数据库和对话框"""
|
||||
self.temp_dir = tempfile.mkdtemp()
|
||||
self.db_path = os.path.join(self.temp_dir, "test_fabric.db")
|
||||
self.db_manager = DatabaseManager(self.db_path)
|
||||
|
||||
# 添加测试原料
|
||||
with self.db_manager.get_conn() as conn:
|
||||
conn.execute('''
|
||||
INSERT INTO fabrics (model, category, color, supplier, unit, timestamp)
|
||||
VALUES (?, ?, ?, ?, ?, datetime('now'))
|
||||
''', ("TEST-STOCK-001", "布料", "白色", "供应商A", "米"))
|
||||
conn.commit()
|
||||
|
||||
# 创建对话框实例
|
||||
self.dialog = StockInDialog(self.db_path)
|
||||
|
||||
# 保存原始消息框和输入框
|
||||
self._original_msgbox = QMessageBox.information
|
||||
self._original_warning = QMessageBox.warning
|
||||
self._original_input = QInputDialog.getDouble
|
||||
|
||||
# Mock消息框
|
||||
QMessageBox.information = lambda *args, **kwargs: None
|
||||
QMessageBox.warning = lambda *args, **kwargs: None
|
||||
|
||||
def tearDown(self):
|
||||
"""每个测试后清理"""
|
||||
# 恢复消息框
|
||||
QMessageBox.information = self._original_msgbox
|
||||
QMessageBox.warning = self._original_warning
|
||||
QInputDialog.getDouble = self._original_input
|
||||
|
||||
# 关闭对话框
|
||||
self.dialog.close()
|
||||
self.dialog.deleteLater()
|
||||
|
||||
# 清理数据库
|
||||
import gc
|
||||
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 test_load_models(self):
|
||||
"""测试加载原料列表"""
|
||||
self.dialog.load_models()
|
||||
|
||||
# 验证表格有数据
|
||||
self.assertGreater(self.dialog.table.rowCount(), 0, "表格应该有数据")
|
||||
|
||||
# 验证第一行是测试数据
|
||||
model_item = self.dialog.table.item(0, 0)
|
||||
self.assertIsNotNone(model_item, "应该有型号数据")
|
||||
self.assertEqual(model_item.text(), "TEST-STOCK-001", "型号应该匹配")
|
||||
|
||||
def test_search_models(self):
|
||||
"""测试搜索原料"""
|
||||
# 添加更多测试数据
|
||||
with self.dialog.get_conn() as conn:
|
||||
conn.execute('''
|
||||
INSERT INTO fabrics (model, category, color, unit, timestamp)
|
||||
VALUES (?, ?, ?, ?, datetime('now'))
|
||||
''', ("OTHER-001", "布料", "黑色", "米"))
|
||||
conn.commit()
|
||||
|
||||
# 搜索特定型号
|
||||
self.dialog.search_input.setText("TEST-STOCK")
|
||||
self.dialog.load_models()
|
||||
|
||||
# 验证只显示匹配的结果
|
||||
row_count = self.dialog.table.rowCount()
|
||||
for row in range(row_count):
|
||||
model_item = self.dialog.table.item(row, 0)
|
||||
if model_item:
|
||||
self.assertIn("TEST-STOCK", model_item.text(), "应该只显示匹配的型号")
|
||||
|
||||
# ========== 库存计算测试 ==========
|
||||
|
||||
def test_stock_calculation(self):
|
||||
"""测试库存数量计算"""
|
||||
# 添加入库记录
|
||||
with self.dialog.get_conn() as conn:
|
||||
conn.execute('''
|
||||
INSERT INTO fabric_stock_in (model, quantity, unit, purchase_date)
|
||||
VALUES (?, ?, ?, ?)
|
||||
''', ("TEST-STOCK-001", 100.0, "米", "2024-01-01"))
|
||||
conn.commit()
|
||||
|
||||
# 刷新表格
|
||||
self.dialog.load_models()
|
||||
|
||||
# 验证库存显示
|
||||
remaining_item = self.dialog.table.item(0, 4)
|
||||
self.assertIsNotNone(remaining_item, "应该有库存数据")
|
||||
remaining = float(remaining_item.text())
|
||||
self.assertEqual(remaining, 100.0, "库存应该是100.0")
|
||||
|
||||
def test_stock_with_consumption(self):
|
||||
"""测试库存扣除消耗后的计算"""
|
||||
# 添加入库记录
|
||||
with self.dialog.get_conn() as conn:
|
||||
conn.execute('''
|
||||
INSERT INTO fabric_stock_in (model, quantity, unit, purchase_date)
|
||||
VALUES (?, ?, ?, ?)
|
||||
''', ("TEST-STOCK-001", 100.0, "米", "2024-01-01"))
|
||||
|
||||
# 添加消耗记录
|
||||
conn.execute('''
|
||||
INSERT INTO fabric_consumption (model, style_number, consume_quantity, consume_date, unit)
|
||||
VALUES (?, ?, ?, ?, ?)
|
||||
''', ("TEST-STOCK-001", "款式001", 30.0, "2024-01-02", "米"))
|
||||
conn.commit()
|
||||
|
||||
# 刷新表格
|
||||
self.dialog.load_models()
|
||||
|
||||
# 验证库存显示(100 - 30 = 70)
|
||||
remaining_item = self.dialog.table.item(0, 4)
|
||||
remaining = float(remaining_item.text())
|
||||
self.assertEqual(remaining, 70.0, "库存应该是70.0(100-30)")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user