新增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>
117 lines
3.8 KiB
Python
117 lines
3.8 KiB
Python
"""
|
||
采购单生成GUI测试模块
|
||
使用PyQt测试框架测试采购单生成功能
|
||
"""
|
||
|
||
import unittest
|
||
import os
|
||
import sys
|
||
import tempfile
|
||
from PyQt5.QtWidgets import QApplication, QMessageBox
|
||
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 purchase_order_dialog import PurchaseOrderDialog
|
||
|
||
|
||
class TestPurchaseOrderGUI(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 garments (style_number)
|
||
VALUES (?)
|
||
''', ("TEST-STYLE-001",))
|
||
|
||
# 添加原料
|
||
conn.execute('''
|
||
INSERT INTO fabrics (model, category, color, unit)
|
||
VALUES (?, ?, ?, ?)
|
||
''', ("TEST-FABRIC-001", "布料", "白色", "米"))
|
||
|
||
# 添加款式材料用量
|
||
conn.execute('''
|
||
INSERT INTO garment_materials (style_number, category, model, usage_per_piece, unit)
|
||
VALUES (?, ?, ?, ?, ?)
|
||
''', ("TEST-STYLE-001", "布料", "TEST-FABRIC-001", 2.5, "米"))
|
||
conn.commit()
|
||
|
||
# 保存原始消息框
|
||
self._original_msgbox = QMessageBox.information
|
||
self._original_warning = QMessageBox.warning
|
||
|
||
# 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
|
||
|
||
# 清理数据库
|
||
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_generate_purchase_order(self):
|
||
"""测试生成采购单"""
|
||
# 创建采购单对话框
|
||
dialog = PurchaseOrderDialog(self.db_path, "TEST-STYLE-001", 100, 0.05)
|
||
|
||
# 验证采购单文本已生成
|
||
po_text = dialog.po_text.toPlainText()
|
||
self.assertIn("TEST-STYLE-001", po_text, "采购单应包含款号")
|
||
self.assertIn("100 件", po_text, "采购单应包含生产数量")
|
||
self.assertIn("5.0%", po_text, "采购单应包含损耗率")
|
||
|
||
dialog.close()
|
||
dialog.deleteLater()
|
||
|
||
def test_material_calculation(self):
|
||
"""测试材料用量计算"""
|
||
# 创建采购单对话框(100件,损耗率5%)
|
||
dialog = PurchaseOrderDialog(self.db_path, "TEST-STYLE-001", 100, 0.05)
|
||
|
||
# 验证采购单包含材料信息
|
||
po_text = dialog.po_text.toPlainText()
|
||
self.assertIn("TEST-FABRIC-001", po_text, "采购单应包含原料型号")
|
||
|
||
# 计算预期用量:100件 * 2.5米/件 * (1 + 0.05) = 262.5米
|
||
self.assertIn("262.5", po_text, "采购单应包含正确的用量计算")
|
||
|
||
dialog.close()
|
||
dialog.deleteLater()
|
||
|
||
|
||
if __name__ == "__main__":
|
||
unittest.main()
|