新增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>
207 lines
6.7 KiB
Python
207 lines
6.7 KiB
Python
"""
|
|
GUI测试模块 - 使用pytest-qt测试PyQt5界面
|
|
"""
|
|
|
|
import pytest
|
|
import os
|
|
import sys
|
|
import tempfile
|
|
|
|
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
|
|
|
from PyQt5.QtWidgets import QApplication, QMessageBox, QDialog
|
|
from PyQt5.QtCore import Qt
|
|
|
|
from database import DatabaseManager
|
|
from login_dialog import LoginDialog
|
|
from main import FabricManager
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
def qapp():
|
|
app = QApplication.instance()
|
|
if app is None:
|
|
app = QApplication([])
|
|
yield app
|
|
|
|
|
|
@pytest.fixture
|
|
def temp_db():
|
|
temp_dir = tempfile.mkdtemp()
|
|
db_path = os.path.join(temp_dir, "test_gui.db")
|
|
db_manager = DatabaseManager(db_path)
|
|
yield db_path
|
|
import gc
|
|
gc.collect()
|
|
try:
|
|
if os.path.exists(db_path):
|
|
os.remove(db_path)
|
|
os.rmdir(temp_dir)
|
|
except:
|
|
pass
|
|
|
|
|
|
class TestLoginDialog:
|
|
"""登录对话框GUI测试"""
|
|
|
|
def test_login_dialog_init(self, qapp, temp_db, qtbot):
|
|
dialog = LoginDialog(temp_db)
|
|
qtbot.addWidget(dialog)
|
|
|
|
assert dialog.windowTitle() == "选择模式并登录"
|
|
assert dialog.is_admin == False
|
|
|
|
def test_login_dialog_has_inputs(self, qapp, temp_db, qtbot):
|
|
dialog = LoginDialog(temp_db)
|
|
qtbot.addWidget(dialog)
|
|
|
|
assert hasattr(dialog, 'admin_input')
|
|
assert hasattr(dialog, 'user_input')
|
|
|
|
def test_admin_login_correct_password(self, qapp, temp_db, qtbot, monkeypatch):
|
|
dialog = LoginDialog(temp_db)
|
|
qtbot.addWidget(dialog)
|
|
|
|
dialog.admin_input.setText("123456")
|
|
monkeypatch.setattr(QMessageBox, 'warning', lambda *args: None)
|
|
|
|
dialog.login_mode(True)
|
|
|
|
assert dialog.is_admin == True
|
|
|
|
def test_admin_login_wrong_password(self, qapp, temp_db, qtbot, monkeypatch):
|
|
dialog = LoginDialog(temp_db)
|
|
qtbot.addWidget(dialog)
|
|
|
|
dialog.admin_input.setText("wrongpassword")
|
|
warning_called = []
|
|
monkeypatch.setattr(QMessageBox, 'warning', lambda *args: warning_called.append(True))
|
|
|
|
dialog.login_mode(True)
|
|
|
|
assert len(warning_called) == 1
|
|
assert dialog.is_admin == False
|
|
|
|
def test_user_login_correct_password(self, qapp, temp_db, qtbot, monkeypatch):
|
|
dialog = LoginDialog(temp_db)
|
|
qtbot.addWidget(dialog)
|
|
|
|
dialog.user_input.setText("123456")
|
|
monkeypatch.setattr(QMessageBox, 'warning', lambda *args: None)
|
|
|
|
dialog.login_mode(False)
|
|
|
|
assert dialog.is_admin == False
|
|
|
|
def test_user_login_wrong_password(self, qapp, temp_db, qtbot, monkeypatch):
|
|
dialog = LoginDialog(temp_db)
|
|
qtbot.addWidget(dialog)
|
|
|
|
dialog.user_input.setText("wrongpassword")
|
|
warning_called = []
|
|
monkeypatch.setattr(QMessageBox, 'warning', lambda *args: warning_called.append(True))
|
|
|
|
dialog.login_mode(False)
|
|
|
|
assert len(warning_called) == 1
|
|
|
|
def test_get_stored_password(self, qapp, temp_db, qtbot):
|
|
dialog = LoginDialog(temp_db)
|
|
qtbot.addWidget(dialog)
|
|
|
|
admin_pwd = dialog.get_stored_password("admin")
|
|
user_pwd = dialog.get_stored_password("user")
|
|
|
|
assert admin_pwd == "123456"
|
|
assert user_pwd == "123456"
|
|
|
|
def test_set_password(self, qapp, temp_db, qtbot):
|
|
dialog = LoginDialog(temp_db)
|
|
qtbot.addWidget(dialog)
|
|
|
|
result = dialog.set_password("admin", "newpass123")
|
|
assert result == True
|
|
|
|
new_pwd = dialog.get_stored_password("admin")
|
|
assert new_pwd == "newpass123"
|
|
|
|
|
|
@pytest.fixture
|
|
def fabric_manager_admin(qapp, temp_db, qtbot):
|
|
window = FabricManager.__new__(FabricManager)
|
|
window.is_admin = True
|
|
window.db_path = temp_db
|
|
from database import DatabaseManager
|
|
window.db_manager = DatabaseManager(temp_db)
|
|
from PyQt5.QtWidgets import QMainWindow
|
|
QMainWindow.__init__(window)
|
|
window.setWindowTitle("服装布料计算管理器 - 专业版 (管理员模式)")
|
|
window.resize(1300, 800)
|
|
window.init_ui()
|
|
window.load_garment_list()
|
|
qtbot.addWidget(window)
|
|
return window
|
|
|
|
|
|
@pytest.fixture
|
|
def fabric_manager_user(qapp, temp_db, qtbot):
|
|
window = FabricManager.__new__(FabricManager)
|
|
window.is_admin = False
|
|
window.db_path = temp_db
|
|
from database import DatabaseManager
|
|
window.db_manager = DatabaseManager(temp_db)
|
|
from PyQt5.QtWidgets import QMainWindow
|
|
QMainWindow.__init__(window)
|
|
window.setWindowTitle("服装布料计算管理器 - 专业版 (普通模式)")
|
|
window.resize(1300, 800)
|
|
window.init_ui()
|
|
window.load_garment_list()
|
|
qtbot.addWidget(window)
|
|
return window
|
|
|
|
|
|
class TestFabricManager:
|
|
"""主窗口GUI测试"""
|
|
|
|
def test_main_window_init_admin(self, fabric_manager_admin):
|
|
assert "管理员模式" in fabric_manager_admin.windowTitle()
|
|
|
|
def test_main_window_init_user(self, fabric_manager_user):
|
|
assert "普通模式" in fabric_manager_user.windowTitle()
|
|
|
|
def test_main_window_has_components(self, fabric_manager_admin):
|
|
assert hasattr(fabric_manager_admin, 'garment_combo')
|
|
assert hasattr(fabric_manager_admin, 'quantity_input')
|
|
assert hasattr(fabric_manager_admin, 'loss_input')
|
|
assert hasattr(fabric_manager_admin, 'result_text')
|
|
|
|
def test_quantity_input_default(self, fabric_manager_admin):
|
|
assert fabric_manager_admin.quantity_input.value() == 1000
|
|
|
|
def test_loss_input_default(self, fabric_manager_admin):
|
|
assert fabric_manager_admin.loss_input.value() == 5.0
|
|
|
|
def test_unit_converter_components(self, fabric_manager_admin):
|
|
assert hasattr(fabric_manager_admin, 'calc_m')
|
|
assert hasattr(fabric_manager_admin, 'calc_yard')
|
|
assert hasattr(fabric_manager_admin, 'calc_kg')
|
|
assert hasattr(fabric_manager_admin, 'calc_width')
|
|
assert hasattr(fabric_manager_admin, 'calc_gsm')
|
|
|
|
def test_unit_converter_defaults(self, fabric_manager_admin):
|
|
assert fabric_manager_admin.calc_width.value() == 150
|
|
assert fabric_manager_admin.calc_gsm.value() == 200
|
|
|
|
def test_meter_to_yard_conversion(self, fabric_manager_admin):
|
|
fabric_manager_admin.calc_m.setValue(1.0)
|
|
expected_yard = 1.0 / 0.9144
|
|
assert abs(fabric_manager_admin.calc_yard.value() - expected_yard) < 0.001
|
|
|
|
def test_quantity_input_change(self, fabric_manager_admin):
|
|
fabric_manager_admin.quantity_input.setValue(500)
|
|
assert fabric_manager_admin.quantity_input.value() == 500
|
|
|
|
def test_loss_input_change(self, fabric_manager_admin):
|
|
fabric_manager_admin.loss_input.setValue(10.0)
|
|
assert fabric_manager_admin.loss_input.value() == 10.0
|