- 实现基于 PySide6 的 GUI 界面 - 集成 FastAPI 知识库服务器 API - 支持查看、编辑、提交 Markdown 文件 - 包含完整的 pytest-qt 测试套件 - 添加功能列表文档
180 lines
6.0 KiB
Python
180 lines
6.0 KiB
Python
import pytest
|
||
from PySide6.QtWidgets import QApplication, QMessageBox
|
||
from PySide6.QtCore import Qt
|
||
from unittest.mock import Mock, patch
|
||
from main_window import KnowledgeBaseApp
|
||
|
||
|
||
@pytest.fixture(scope="module")
|
||
def app():
|
||
"""创建 QApplication 实例"""
|
||
if not QApplication.instance():
|
||
app = QApplication([])
|
||
else:
|
||
app = QApplication.instance()
|
||
yield app
|
||
|
||
|
||
@pytest.fixture
|
||
def main_window(app, qtbot):
|
||
"""创建主窗口实例"""
|
||
window = KnowledgeBaseApp()
|
||
qtbot.addWidget(window)
|
||
window.show()
|
||
return window
|
||
|
||
|
||
def test_window_initialization(main_window, qtbot):
|
||
"""测试窗口初始化"""
|
||
assert main_window.windowTitle() == '知识库管理器'
|
||
assert main_window.server_input.text() == 'http://43.134.1.17:8800/'
|
||
assert main_window.config_button.text() == '配置'
|
||
assert main_window.refresh_button.text() == '刷新列表'
|
||
assert main_window.save_button.text() == '保存到服务器'
|
||
assert main_window.post_button.text() == '提交新文件'
|
||
|
||
|
||
def test_server_input_exists(main_window, qtbot):
|
||
"""测试服务器地址输入框"""
|
||
assert main_window.server_input is not None
|
||
assert main_window.server_input.placeholderText() == ''
|
||
qtbot.keyClicks(main_window.server_input, 'http://test.com')
|
||
assert 'http://test.com' in main_window.server_input.text()
|
||
|
||
|
||
def test_filename_input_exists(main_window, qtbot):
|
||
"""测试文件名输入框"""
|
||
assert main_window.filename_input is not None
|
||
assert main_window.filename_input.placeholderText() == '输入文件名(例如:example.md)'
|
||
qtbot.keyClicks(main_window.filename_input, 'test.md')
|
||
assert main_window.filename_input.text() == 'test.md'
|
||
|
||
|
||
def test_text_editor_exists(main_window, qtbot):
|
||
"""测试文本编辑器"""
|
||
assert main_window.text_editor is not None
|
||
test_content = '# Test Markdown\n\nThis is a test.'
|
||
main_window.text_editor.setPlainText(test_content)
|
||
assert main_window.text_editor.toPlainText() == test_content
|
||
|
||
|
||
def test_file_list_exists(main_window):
|
||
"""测试文件列表"""
|
||
assert main_window.file_list is not None
|
||
assert main_window.file_list.count() == 0
|
||
|
||
|
||
def test_buttons_clickable(main_window, qtbot):
|
||
"""测试按钮可点击"""
|
||
assert main_window.config_button.isEnabled()
|
||
assert main_window.refresh_button.isEnabled()
|
||
assert main_window.save_button.isEnabled()
|
||
assert main_window.post_button.isEnabled()
|
||
|
||
|
||
def test_configure_server_without_url(main_window, qtbot):
|
||
"""测试配置服务器(无URL)"""
|
||
main_window.server_input.clear()
|
||
|
||
with patch.object(QMessageBox, 'warning') as mock_warning:
|
||
main_window.configure_server()
|
||
mock_warning.assert_called_once()
|
||
assert main_window.api is None
|
||
|
||
|
||
def test_configure_server_invalid_url(main_window, qtbot):
|
||
"""测试配置服务器(无效URL)"""
|
||
main_window.server_input.setText('http://invalid-url-that-does-not-exist.com')
|
||
|
||
with patch.object(QMessageBox, 'critical') as mock_critical:
|
||
main_window.configure_server()
|
||
mock_critical.assert_called_once()
|
||
|
||
|
||
def test_refresh_file_list_without_api(main_window, qtbot):
|
||
"""测试刷新文件列表(未配置服务器)"""
|
||
main_window.api = None
|
||
|
||
with patch.object(QMessageBox, 'warning') as mock_warning:
|
||
main_window.refresh_file_list()
|
||
mock_warning.assert_called_once()
|
||
|
||
|
||
def test_save_file_without_api(main_window, qtbot):
|
||
"""测试保存文件(未配置服务器)"""
|
||
main_window.api = None
|
||
|
||
with patch.object(QMessageBox, 'warning') as mock_warning:
|
||
main_window.save_file()
|
||
mock_warning.assert_called_once()
|
||
|
||
|
||
def test_save_file_without_selection(main_window, qtbot):
|
||
"""测试保存文件(未选择文件)"""
|
||
main_window.api = Mock()
|
||
main_window.current_filename = None
|
||
|
||
with patch.object(QMessageBox, 'warning') as mock_warning:
|
||
main_window.save_file()
|
||
mock_warning.assert_called_once()
|
||
|
||
|
||
def test_post_new_file_without_api(main_window, qtbot):
|
||
"""测试提交新文件(未配置服务器)"""
|
||
main_window.api = None
|
||
|
||
with patch.object(QMessageBox, 'warning') as mock_warning:
|
||
main_window.post_new_file()
|
||
mock_warning.assert_called_once()
|
||
|
||
|
||
def test_post_new_file_without_filename(main_window, qtbot):
|
||
"""测试提交新文件(无文件名)"""
|
||
main_window.api = Mock()
|
||
main_window.filename_input.clear()
|
||
|
||
with patch.object(QMessageBox, 'warning') as mock_warning:
|
||
main_window.post_new_file()
|
||
mock_warning.assert_called_once()
|
||
|
||
|
||
def test_post_new_file_without_content(main_window, qtbot):
|
||
"""测试提交新文件(无内容)"""
|
||
main_window.api = Mock()
|
||
main_window.filename_input.setText('test.md')
|
||
main_window.text_editor.clear()
|
||
|
||
with patch.object(QMessageBox, 'warning') as mock_warning:
|
||
main_window.post_new_file()
|
||
mock_warning.assert_called_once()
|
||
|
||
|
||
def test_post_new_file_auto_add_extension(main_window, qtbot):
|
||
"""测试提交新文件(自动添加.md扩展名)"""
|
||
main_window.api = Mock()
|
||
main_window.filename_input.setText('test')
|
||
main_window.text_editor.setPlainText('# Test')
|
||
|
||
with patch.object(QMessageBox, 'information') as mock_info:
|
||
with patch.object(main_window, 'refresh_file_list'):
|
||
main_window.post_new_file()
|
||
assert main_window.filename_input.text() == 'test.md'
|
||
|
||
|
||
def test_ui_layout_elements(main_window):
|
||
"""测试UI布局元素"""
|
||
assert main_window.server_input.parent() is not None
|
||
assert main_window.file_list.parent() is not None
|
||
assert main_window.text_editor.parent() is not None
|
||
assert main_window.status_label.parent() is not None
|
||
|
||
|
||
def test_status_label_updates(main_window, qtbot):
|
||
"""测试状态标签更新"""
|
||
initial_text = main_window.status_label.text()
|
||
main_window.status_label.setText('测试状态')
|
||
assert main_window.status_label.text() == '测试状态'
|
||
|
||
|
||
if __name__ == '__main__':
|
||
pytest.main([__file__, '-v']) |