293 lines
8.3 KiB
Python
293 lines
8.3 KiB
Python
import pytest
|
|
from pathlib import Path
|
|
from openpyxl import Workbook
|
|
|
|
from src.core.mil_read_case_excel import (
|
|
read_excel_case,
|
|
_get_template_version,
|
|
_analysis_action,
|
|
)
|
|
from src.core.mil_create_data_excel import (
|
|
create_excel_case,
|
|
_init_data_log,
|
|
_analysis_case,
|
|
_analysis_step,
|
|
)
|
|
from src.core.exceptions import ExcelReadError, ExcelFormatError, CaseDataError
|
|
from src.core.base import DataLog
|
|
|
|
|
|
@pytest.fixture
|
|
def sample_data_dict():
|
|
"""返回示例数据字典"""
|
|
return {
|
|
"signal1": {
|
|
"type": "Type1",
|
|
"column": 2,
|
|
"datalog": [DataLog(0.0, "initial"), DataLog(1.0, "value1")]
|
|
},
|
|
"signal2": {
|
|
"type": "Type2",
|
|
"column": 3,
|
|
"datalog": [DataLog(0.0, "init2"), DataLog(1.0, "value2")]
|
|
}
|
|
}
|
|
|
|
|
|
@pytest.fixture
|
|
def sample_sheets_dict():
|
|
"""返回示例工作表字典"""
|
|
return {
|
|
"TestSheet": {
|
|
"TestCase1": {
|
|
"enable": False,
|
|
"step": {
|
|
"step0": {
|
|
"name": "Step1",
|
|
"time": 1.0,
|
|
"action": {"signal1": "new_value1"}
|
|
},
|
|
"step1": {
|
|
"name": "Step2",
|
|
"time": 2.0,
|
|
"action": {"signal2": "new_value2"}
|
|
}
|
|
}
|
|
},
|
|
"TestCase2": {
|
|
"enable": True,
|
|
"step": {}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
def test_get_template_version():
|
|
"""验证获取模板版本号"""
|
|
wb = Workbook()
|
|
sheet = wb.active
|
|
sheet.cell(2, 1, "v1.0.0")
|
|
sheet.cell(3, 1, None)
|
|
|
|
version = _get_template_version(sheet)
|
|
assert version == "v1.0.0"
|
|
|
|
|
|
def test_get_template_version_empty():
|
|
"""验证空工作表的版本号"""
|
|
wb = Workbook()
|
|
sheet = wb.active
|
|
|
|
version = _get_template_version(sheet)
|
|
assert version is None
|
|
|
|
|
|
def test_analysis_action_valid(sample_data_dict):
|
|
"""验证解析有效操作字符串"""
|
|
wb = Workbook()
|
|
sheet = wb.create_sheet("TestSheet")
|
|
sheet.cell(1, 1, "Test")
|
|
|
|
action = _analysis_action(sheet, 1, 3, "signal1=newvalue", sample_data_dict, "test.xlsx")
|
|
assert "signal1" in action
|
|
assert action["signal1"] == "newvalue"
|
|
|
|
|
|
def test_analysis_action_multiple(sample_data_dict):
|
|
"""验证解析多个操作"""
|
|
wb = Workbook()
|
|
sheet = wb.create_sheet("TestSheet")
|
|
sheet.cell(1, 1, "Test")
|
|
|
|
action = _analysis_action(sheet, 1, 3, "signal1=v1; signal2=v2", sample_data_dict, "test.xlsx")
|
|
assert "signal1" in action
|
|
assert "signal2" in action
|
|
assert action["signal1"] == "v1"
|
|
assert action["signal2"] == "v2"
|
|
|
|
|
|
def test_analysis_action_invalid_signal(sample_data_dict):
|
|
"""验证解析无效信号时抛出异常"""
|
|
wb = Workbook()
|
|
sheet = wb.create_sheet("TestSheet")
|
|
sheet.cell(1, 1, "Test")
|
|
|
|
with pytest.raises(CaseDataError, match="信号 .* 不存在"):
|
|
_analysis_action(sheet, 1, 3, "invalid_signal=value", sample_data_dict, "test.xlsx")
|
|
|
|
|
|
def test_init_data_log(sample_data_dict):
|
|
"""验证初始化数据日志"""
|
|
data_copy = {k: v.copy() for k, v in sample_data_dict.items()}
|
|
for name in data_copy:
|
|
data_copy[name]["datalog"] = data_copy[name]["datalog"].copy()
|
|
|
|
_init_data_log(data_copy)
|
|
|
|
for name in data_copy:
|
|
assert len(data_copy[name]["datalog"]) == 1
|
|
assert data_copy[name]["datalog"][0].time == 0.0
|
|
|
|
|
|
def test_analysis_step_with_action(sample_data_dict):
|
|
"""验证分析带操作的步骤"""
|
|
step_dict = {
|
|
"step0": {
|
|
"name": "TestStep",
|
|
"time": 1.5,
|
|
"action": {"signal1": "newvalue"}
|
|
}
|
|
}
|
|
|
|
data_copy = {k: v.copy() for k, v in sample_data_dict.items()}
|
|
for name in data_copy:
|
|
data_copy[name]["datalog"] = data_copy[name]["datalog"].copy()
|
|
|
|
_analysis_step(step_dict, data_copy)
|
|
|
|
assert len(data_copy["signal1"]["datalog"]) == 3
|
|
assert data_copy["signal1"]["datalog"][-1].time == 1.5
|
|
assert data_copy["signal1"]["datalog"][-1].value == "newvalue"
|
|
|
|
|
|
def test_analysis_step_without_action(sample_data_dict):
|
|
"""验证分析不带操作的步骤"""
|
|
step_dict = {
|
|
"step0": {
|
|
"name": "TestStep",
|
|
"time": 1.0
|
|
}
|
|
}
|
|
|
|
data_copy = {k: v.copy() for k, v in sample_data_dict.items()}
|
|
for name in data_copy:
|
|
data_copy[name]["datalog"] = data_copy[name]["datalog"].copy()
|
|
|
|
initial_length = len(data_copy["signal1"]["datalog"])
|
|
_analysis_step(step_dict, data_copy)
|
|
|
|
assert len(data_copy["signal1"]["datalog"]) == initial_length + 1
|
|
|
|
|
|
def test_analysis_case(sample_data_dict, sample_sheets_dict):
|
|
"""验证用例分析"""
|
|
result = _analysis_case(sample_data_dict, sample_sheets_dict)
|
|
|
|
assert "TestCase1" in result
|
|
assert "TestCase2" not in result
|
|
|
|
|
|
def test_analysis_case_skips_enabled_cases(sample_data_dict):
|
|
"""验证跳过早启用的用例"""
|
|
sheets_dict = {
|
|
"TestSheet": {
|
|
"EnabledCase": {
|
|
"enable": True,
|
|
"step": {}
|
|
}
|
|
}
|
|
}
|
|
|
|
result = _analysis_case(sample_data_dict, sheets_dict)
|
|
assert "EnabledCase" not in result
|
|
|
|
|
|
def test_read_excel_case_file_not_found():
|
|
"""验证文件不存在时抛出异常"""
|
|
with pytest.raises(ExcelReadError, match="不存在"):
|
|
read_excel_case("nonexistent.xlsx", {}, False)
|
|
|
|
|
|
def test_read_excel_case_missing_atech_sheet(tmp_path: Path):
|
|
"""验证缺少 Atech-Hefei 表时抛出异常"""
|
|
wb = Workbook()
|
|
wb.create_sheet("OtherSheet")
|
|
invalid_path = tmp_path / "invalid.xlsx"
|
|
wb.save(invalid_path)
|
|
|
|
with pytest.raises(ExcelFormatError, match="缺少 Atech-Hefei 表"):
|
|
read_excel_case(invalid_path, {}, False)
|
|
|
|
|
|
def test_read_excel_case_missing_version(tmp_path: Path, sample_data_dict):
|
|
"""验证缺少版本号时抛出异常"""
|
|
wb = Workbook()
|
|
wb.create_sheet("Atech-Hefei")
|
|
wb.create_sheet("TestSheet")
|
|
invalid_path = tmp_path / "no_version.xlsx"
|
|
wb.save(invalid_path)
|
|
|
|
with pytest.raises(ExcelFormatError, match="缺少模板版本号"):
|
|
read_excel_case(invalid_path, sample_data_dict, False)
|
|
|
|
|
|
def test_read_excel_case_success(tmp_path: Path, sample_data_dict):
|
|
"""验证成功读取用例模板"""
|
|
wb = Workbook()
|
|
wb.remove(wb.active)
|
|
|
|
version_sheet = wb.create_sheet("Atech-Hefei")
|
|
version_sheet.cell(2, 1, "v1.0.0")
|
|
|
|
test_sheet = wb.create_sheet("TestSheet")
|
|
test_sheet.cell(2, 1, "TestCase1")
|
|
test_sheet.cell(2, 2, "未完成")
|
|
test_sheet.cell(2, 3, None)
|
|
test_sheet.cell(2, 4, "Step1")
|
|
test_sheet.cell(2, 5, 1.0)
|
|
test_sheet.cell(2, 6, None)
|
|
|
|
test_sheet.cell(3, 1, "TestCase1")
|
|
test_sheet.cell(3, 2, "未完成")
|
|
test_sheet.cell(3, 3, None)
|
|
test_sheet.cell(3, 4, "Step2")
|
|
test_sheet.cell(3, 5, 2.0)
|
|
test_sheet.cell(3, 6, None)
|
|
|
|
valid_path = tmp_path / "valid.xlsx"
|
|
wb.save(valid_path)
|
|
|
|
result = read_excel_case(valid_path, sample_data_dict, False)
|
|
|
|
assert "TestSheet" in result
|
|
assert "TestCase1" in result["TestSheet"]
|
|
|
|
|
|
def test_read_excel_case_missing_title(tmp_path: Path, sample_data_dict):
|
|
"""验证缺少标题时抛出异常"""
|
|
wb = Workbook()
|
|
|
|
version_sheet = wb.create_sheet("Atech-Hefei")
|
|
version_sheet.cell(2, 1, "v1.0.0")
|
|
|
|
test_sheet = wb.create_sheet("TestSheet")
|
|
test_sheet.cell(2, 1, None)
|
|
|
|
invalid_path = tmp_path / "missing_title.xlsx"
|
|
wb.save(invalid_path)
|
|
|
|
with pytest.raises(CaseDataError, match="必须有标题名"):
|
|
read_excel_case(invalid_path, sample_data_dict, False)
|
|
|
|
|
|
def test_read_excel_case_invalid_time(tmp_path: Path, sample_data_dict):
|
|
"""验证时间格式错误时抛出异常"""
|
|
wb = Workbook()
|
|
wb.remove(wb.active)
|
|
|
|
version_sheet = wb.create_sheet("Atech-Hefei")
|
|
version_sheet.cell(2, 1, "v1.0.0")
|
|
|
|
test_sheet = wb.create_sheet("TestSheet")
|
|
test_sheet.cell(2, 1, "TestCase1")
|
|
test_sheet.cell(2, 2, "未完成")
|
|
test_sheet.cell(2, 4, "Step1")
|
|
test_sheet.cell(2, 5, "invalid_time")
|
|
test_sheet.cell(2, 6, None)
|
|
|
|
invalid_path = tmp_path / "invalid_time.xlsx"
|
|
wb.save(invalid_path)
|
|
|
|
with pytest.raises(CaseDataError, match="时间必须是数字"):
|
|
read_excel_case(invalid_path, sample_data_dict, False)
|