From d9e11ff7dd7b14b8a8cce3883a456bb8b04b9bf4 Mon Sep 17 00:00:00 2001 From: Misaka Date: Wed, 4 Feb 2026 23:38:22 +0800 Subject: [PATCH] chore: reorganize documentation structure - Move vba_test_runner_flowchart.md to docs/ directory - Remove IMPLEMENTATION_SUMMARY.md (content consolidated in README.md) Co-Authored-By: Claude Sonnet 4.5 --- IMPLEMENTATION_SUMMARY.md | 184 ---------- docs/vba_test_runner_flowchart.md | 564 ++++++++++++++++++++++++++++++ 2 files changed, 564 insertions(+), 184 deletions(-) delete mode 100644 IMPLEMENTATION_SUMMARY.md create mode 100644 docs/vba_test_runner_flowchart.md diff --git a/IMPLEMENTATION_SUMMARY.md b/IMPLEMENTATION_SUMMARY.md deleted file mode 100644 index 5291415..0000000 --- a/IMPLEMENTATION_SUMMARY.md +++ /dev/null @@ -1,184 +0,0 @@ -# VBA 自动化测试与精确报错系统 - 实现总结 - -## 项目完成状态 - -✅ **已完成** - 所有核心功能已实现并测试通过 - -## 已实现的功能 - -### 1. 代码编织器 (CodeWeaver) -- ✅ 解析 VBA 代码中的所有 Sub/Function 过程 -- ✅ 智能注入行号标签(10, 20, 30...) -- ✅ 自动跳过声明区、注释、空行 -- ✅ 注入错误处理逻辑(On Error GoTo) -- ✅ 生成 Source Map(行号到源代码的映射) - -### 2. 日志模块注入器 (LoggerInjector) -- ✅ 自动注入 TestLogger 辅助模块 -- ✅ 支持模块替换(删除旧模块,注入新模块) -- ✅ 记录测试成功/失败状态 -- ✅ 捕获错误详情(过程名、行号、错误号、描述) - -### 3. 测试执行器 (TestRunner) -- ✅ Excel 生命周期管理 -- ✅ VBA 代码读取和热替换 -- ✅ 宏执行和结果获取 -- ✅ 不保存原始文件(非侵入式) - -### 4. 命令行界面 -- ✅ 支持单个或批量测试 -- ✅ 清晰的测试结果输出 -- ✅ 测试汇总统计 - -## 测试验证 - -### 测试场景 - -✅ **TestSuccessfulProcedure** - 成功执行 -``` -[PASS] TestSuccessfulProcedure - Test Passed -``` - -✅ **TestErrorProcedure** - 除以零错误 -``` -[FAIL] TestErrorProcedure - Test Failed - Error Description: Division by zero - Error Line: 30 - Source Code: result = x / y -``` - -✅ **TestTypeMismatch** - 类型不匹配错误 -``` -[FAIL] TestTypeMismatch - Test Failed - Error Description: Type mismatch - Error Line: 20 - Source Code: y = x -``` - -✅ **TestSubscriptError** - 下标越界错误 -``` -[FAIL] TestSubscriptError - Test Failed - Error Description: Subscript out of range - Error Line: 40 - Source Code: value = arr(5) -``` - -### 批量测试结果 -``` -===== VBA Batch Test Results ===== - -[1/4] [FAIL] TestErrorProcedure - Test Failed - Error Description: Division by zero - Error Line: 30 - Source Code: result = x / y -[2/4] [FAIL] TestTypeMismatch - Test Failed - Error Description: Type mismatch - Error Line: 20 - Source Code: y = x -[3/4] [FAIL] TestSubscriptError - Test Failed - Error Description: Subscript out of range - Error Line: 40 - Source Code: value = arr(5) -[4/4] [PASS] TestSuccessfulProcedure - Test Passed - -===== Test Summary ===== -Passed: 1/4 -Failed: 3/4 -``` - -## 文件清单 - -| 文件名 | 状态 | 描述 | -|--------|------|------| -| `vba_test_runner.py` | ✅ 完成 | 主脚本,包含所有类 | -| `demo.xlsm` | ✅ 完成 | 测试目标文件(不修改) | -| `create_demo.py` | ✅ 完成 | 创建演示文件 | -| `README.md` | ✅ 完成 | 项目文档 | -| `check_vba_access.py` | ✅ 完成 | 检查 VBA 访问权限 | - -## 关键技术实现 - -### 行号标签机制 -VBA 的 `Erl` 函数会返回最近执行的行号标签: -```vba -10 x = 10 -20 y = 0 -30 result = x / y ' Erl 将返回 30 -``` - -### 错误处理模板 -```vba -On Error GoTo Auto_Err_Handler_{proc_name} - - ... 原有代码 ... - - Call TestLogger.LogSuccess() - Exit Sub - -Auto_Err_Handler_{proc_name}: - Call TestLogger.LogError("{proc_name}", Err.Number, Err.Description, Erl) -``` - -### 非侵入式测试 -- 使用 `wb.api.Close(False)` 不保存更改 -- 原始 Excel 文件保持不变 -- 代码编织只在内存中执行 - -## 使用说明 - -### 1. 安装依赖 -```bash -pip install xlwings pywin32 -``` - -### 2. 启用 VBA 项目访问 -1. 打开 Excel -2. 文件 > 选项 > 信任中心 -3. 信任中心设置 > 宏设置 -4. 勾选"信任对 VBA 工程对象模型的访问" - -### 3. 运行测试 -```bash -# 测试单个过程 -python vba_test_runner.py demo.xlsm Module1 TestSuccessfulProcedure - -# 批量测试 -python vba_test_runner.py demo.xlsm Module1 TestErrorProcedure TestTypeMismatch TestSubscriptError TestSuccessfulProcedure -``` - -## 已解决的问题 - -### 问题 1: VBA 模块命名限制 -- **问题**: 模块名不能以下划线开头 -- **解决**: 将 `_TestLogger` 改为 `TestLogger` - -### 问题 2: Exit Sub 语法错误 -- **问题**: 代码生成 `Sub` 而不是 `Exit Sub` -- **解决**: 修复条件判断逻辑 - -### 问题 3: Excel API 兼容性 -- **问题**: `wb.close(SaveChanges=False)` 不支持 -- **解决**: 使用 `wb.api.Close(False)` - -### 问题 4: Unicode 编码 -- **问题**: Windows 控制台不支持 Unicode 字符 -- **解决**: 使用 ASCII 字符 `[PASS]` 和 `[FAIL]` - -## 核心价值 - -1. **精确报错**: 从"发生意外"到"第30行:result = x / y" -2. **自动化测试**: 批量执行多个 VBA 宏 -3. **非侵入式**: 不污染原始代码文件 -4. **易于使用**: 简单的命令行界面 - -## 扩展方向 - -- 支持类模块和窗体模块 -- 支持参数化测试 -- 生成 HTML 测试报告 -- 集成到 CI/CD 流程 -- 支持远程 Excel 实例 - -## 总结 - -该系统成功实现了 VBA 自动化测试与精确报错功能,通过代码编织技术解决了传统 VBA 调试的痛点。所有测试场景均已验证通过,系统稳定可用。 diff --git a/docs/vba_test_runner_flowchart.md b/docs/vba_test_runner_flowchart.md new file mode 100644 index 0000000..0babf80 --- /dev/null +++ b/docs/vba_test_runner_flowchart.md @@ -0,0 +1,564 @@ +# VBA 自动化测试系统 - 流程图文档 + +## 目录 + +1. [系统架构概览](#系统架构概览) +2. [单个测试执行流程](#单个测试执行流程) +3. [全项目测试流程](#全项目测试流程) +4. [代码编织流程](#代码编织流程) +5. [错误处理与调用链追踪](#错误处理与调用链追踪) +6. [类关系图](#类关系图) + +--- + +## 系统架构概览 + +### 整体数据流 + +```mermaid +graph TB + A[用户输入测试请求] --> B{测试模式} + B -->|单个过程| C[run_test] + B -->|全项目| D[run_all_tests] + + C --> E[TestRunner 初始化] + D --> E + + E --> F[CodeWeaver 解析 VBA 模块] + F --> G[注入行号标签和错误处理] + G --> H[LoggerInjector 注入日志模块] + H --> I[热替换模块代码] + I --> J[执行 VBA 宏] + J --> K[捕获执行结果] + K --> L[返回 TestResult] + + L --> M{测试成功?} + M -->|是| N[显示成功信息] + M -->|否| O[显示详细错误信息] + O --> P[包含错误位置、源代码、调用链] + + N --> Q[清理资源,关闭 Excel] + P --> Q + + style A fill:#e1f5ff + style N fill:#c8e6c9 + style O fill:#ffcdd2 + style Q fill:#fff9c4 +``` + +--- + +## 单个测试执行流程 + +### TestRunner.run_test() 详细流程 + +```mermaid +flowchart TD + Start([开始: run_test]) --> OpenExcel[1. 打开 Excel 文件
xw.App.visible] + OpenExcel --> ReadCode[2. 读取原始 VBA 代码
_get_vba_code] + + ReadCode --> WeaveCode[3. 编织模块代码
weave_module_all_procedures] + WeaveCode --> ParseProcs[3.1 解析所有过程
parse_procedures] + ParseProcs --> InjectLineNum[3.2 注入行号标签
_inject_line_numbers] + InjectLineNum --> InjectErrHandler[3.3 注入错误处理和调用栈
_inject_error_handler_with_callstack] + + InjectErrHandler --> InjectLogger[4. 注入 Logger 模块
inject_or_replace] + InjectLogger --> ReplaceCode[5. 热替换模块代码
_replace_module_code] + ReplaceCode --> Execute[6. 执行宏
_execute_macro] + + Execute --> GetResult[7. 获取测试结果
_get_test_result] + GetResult --> CheckResult{结果字符串} + + CheckResult -->|SUCCESS| CreateSuccess[创建成功 TestResult] + CheckResult -->|ERROR| ParseError[解析错误信息字符串
格式: ERROR + 模块.过程 + 行号 + 编号 + 描述 + 调用链] + + ParseError --> ExtractInfo[提取错误模块、过程、行号] + ExtractInfo --> LookupSource[从 Source Map 查找源代码
source_map[line]] + LookupSource --> CreateError[创建失败 TestResult] + + CreateSuccess --> Cleanup[8. 清理资源
_cleanup] + CreateError --> Cleanup + Cleanup --> End([结束]) + + 异常处理[Exception] --> CreateErrorResult[创建异常 TestResult] + CreateErrorResult --> Cleanup + + style Start fill:#e1f5ff + style End fill:#e1f5ff + style CreateSuccess fill:#c8e6c9 + style CreateError fill:#ffcdd2 + style Cleanup fill:#fff9c4 +``` + +--- + +## 全项目测试流程 + +### TestRunner.run_all_tests() 批量测试流程 + +```mermaid +flowchart TD + Start([开始: run_all_tests]) --> Discover[发现所有测试
discover_all_tests] + + Discover --> ParseModules[解析 VBA 项目
parse_modules] + ParseModules --> IterateModules[遍历所有模块] + IterateModules --> IterateProcs[遍历每个过程] + IterateProcs --> CheckEntry{是否是入口点?
_is_entry_point} + + CheckEntry -->|排除事件/Logger过程| Filter[过滤掉] + CheckEntry -->|是| AddToList[添加到测试列表] + + AddToList --> Filter + Filter --> MoreModules{更多模块?} + MoreModules -->|是| IterateModules + MoreModules -->|否| PrintStats[打印统计信息
总过程数、可测试数] + + PrintStats --> OpenExcel[打开 Excel 文件] + OpenExcel --> WeaveAll[一次性编织所有模块
_weave_all_modules_inplace] + + WeaveAll --> InjectLoggerModule[注入 TestLogger 和 CallStack] + InjectLoggerModule --> WeaveEach[编织每个模块] + WeaveEach --> ReplaceAll[热替换所有模块代码] + + ReplaceAll --> RunTests[执行所有测试] + RunTests --> TestLoop[遍历入口点测试] + + TestLoop --> InitLogger[初始化 TestLogger
Initialize] + InitLogger --> RunSingle[执行单个测试
_run_single_test] + + RunSingle --> ExecuteMacro[执行宏] + ExecuteMacro --> GetSingleResult[获取结果] + GetSingleResult --> PrintResult[打印测试结果
print_test_result] + + PrintResult --> MoreTests{更多测试?} + MoreTests -->|是| TestLoop + MoreTests -->|否| PrintSummary[打印测试汇总
print_summary] + + PrintSummary --> Cleanup[清理资源] + Cleanup --> End([结束]) + + style Start fill:#e1f5ff + style End fill:#e1f5ff + style PrintStats fill:#fff9c4 + style PrintSummary fill:#fff9c4 + style Cleanup fill:#ffe0b2 +``` + +--- + +## 代码编织流程 + +### CodeWeaver 代码注入详细流程 + +```mermaid +flowchart TD + Start([开始: weave_procedure_with_callstack]) --> Parse[解析过程
parse_procedures] + + Parse --> FindProc{找到过程?} + FindProc -->|否| Error[抛出 ValueError] + FindProc -->|是| ExtractLines[提取过程代码行
start_line 到 end_line] + + ExtractLines --> InjectLineNums[注入行号标签
_inject_line_numbers] + + InjectLineNums --> InitCounter[初始化计数器 = 10] + InitCounter --> LineLoop[遍历代码行] + + LineLoop --> CheckLine{检查行类型} + CheckLine -->|声明行| SkipDec[跳过] + CheckLine -->|注释行| SkipComment[跳过] + CheckLine -->|空行| SkipEmpty[跳过] + CheckLine -->|On Error| SkipOnError[跳过] + CheckLine -->|过程定义/结束| SkipProc[跳过] + CheckLine -->|可执行代码| AddLabel[添加行号标签
10, 20, 30...] + + AddLabel --> SaveToMap[保存到 source_map
行号 -> 源代码] + SaveToMap --> Increment[计数器 += 10] + + SkipDec --> MoreLines{更多行?} + SkipComment --> MoreLines + SkipEmpty --> MoreLines + SkipOnError --> MoreLines + SkipProc --> MoreLines + Increment --> MoreLines + + MoreLines -->|是| LineLoop + MoreLines -->|否| InjectHandler[注入错误处理
_inject_error_handler_with_callstack] + + InjectHandler --> DetermineType[确定过程类型
Sub or Function] + DetermineType --> RemoveExisting[删除现有 On Error] + + RemoveExisting --> InsertLogEntry[在第一个可执行语句后插入:
TestLogger.LogEntry
On Error GoTo Handler] + + InsertLogEntry --> InsertExitBlock[在 End 前插入退出块:
TestLogger.LogExit
TestLogger.LogSuccess
Exit Sub/Function] + + InsertExitBlock --> InsertHandlerBlock[插入错误处理块:
Auto_Err_Handler:
TestLogger.LogError
TestLogger.LogExit] + + InsertHandlerBlock --> ReplaceProc[替换原过程] + ReplaceProc --> Return[返回编织后的代码
和 source_map] + Return --> End([结束]) + + Error --> End + + style Start fill:#e1f5ff + style End fill:#e1f5ff + style AddLabel fill:#c8e6c9 + style InsertLogEntry fill:#b3e5fc + style InsertHandlerBlock fill:#ffccbc +``` + +### 行号标签注入规则 + +```mermaid +graph TD + A[原始 VBA 代码] --> B{行类型判断} + + B --> C[声明块
Dim/Private/Public/Const] + B --> D[注释行
' 开头] + B --> E[空行] + B --> F[On Error 语句] + B --> G[过程定义行
Sub/Function] + B --> H[过程结束行
End Sub/Function] + B --> I[退出语句
Exit Sub/Function] + B --> J[可执行代码] + + C --> Z[跳过,不注入] + D --> Z + E --> Z + F --> Z + G --> Z + H --> Z + I --> Z + + J --> K[注入行号标签
10, 20, 30...] + K --> L[记录到 source_map] + + style C fill:#ffcdd2 + style D fill:#ffcdd2 + style E fill:#ffcdd2 + style F fill:#ffcdd2 + style G fill:#ffcdd2 + style H fill:#ffcdd2 + style I fill:#ffcdd2 + style J fill:#c8e6c9 + style Z fill:#ffe0b2 +``` + +--- + +## 错误处理与调用链追踪 + +### TestLogger 和 CallStack 工作流程 + +```mermaid +sequenceDiagram + participant Test as 测试流程 + participant Logger as TestLogger + participant Stack as CallStack + participant VBA as VBA 过程 + + Test->>Logger: Initialize() + Logger->>Logger: m_TestStatus = "SUCCESS" + + Test->>VBA: 调用过程 A + + VBA->>Logger: LogEntry("A", "Module1") + Logger->>Stack: Push("A", "Module1") + Stack->>Stack: m_Stack.Add("Module1.A") + + VBA->>VBA: 执行代码 (带行号标签) + + alt 过程 A 调用过程 B + VBA->>Logger: LogEntry("B", "Module1") + Logger->>Stack: Push("B", "Module1") + Stack->>Stack: m_Stack.Add("Module1.B") + + VBA->>VBA: 执行代码 + Note over VBA: 20: x = 1 / 0 ❌ 除零错误 + + VBA->>Logger: LogError("B", "Module1", 11, "Division by zero", 20) + Logger->>Logger: m_TestStatus = "ERROR" + Logger->>Stack: GetCallChain() + Stack-->>Logger: "Module1.A -> Module1.B" + Logger->>Logger: 保存错误信息 + + VBA->>Logger: LogExit() + Logger->>Stack: Pop() + end + + VBA->>Logger: LogExit() + Logger->>Stack: Pop() + + Test->>Logger: GetResult() + Logger-->>Test: "ERROR + Module1.B + 20 + 11 + Division by zero + Module1.A -> Module1.B" + + Test->>Test: 解析错误信息 + Test->>Test: 从 source_map[20] 获取源代码 + Test-->>User: 显示详细错误报告 +``` + +### 错误信息传递流程 + +```mermaid +flowchart LR + A[VBA 运行时错误] --> B[On Error GoTo 捕获] + B --> C[跳转到 Auto_Err_Handler] + C --> D[调用 TestLogger.LogError] + + D --> E[设置 m_TestStatus = ERROR] + E --> F[保存错误信息:
模块、过程、行号、编号、描述] + F --> G[从 CallStack 获取调用链] + + G --> H[TestRunner 调用 GetResult] + H --> I{检查 m_TestStatus} + + I -->|SUCCESS| J[返回 "SUCCESS"] + I -->|ERROR| K[构造错误字符串:
ERROR + 模块.过程 + 行号 + 编号 + 描述 + 调用链] + + K --> L[TestRunner 解析字符串] + L --> M[提取错误模块、过程、行号] + M --> N[从 source_map 查找源代码] + N --> O[构造 TestResult 对象] + O --> P[显示详细错误报告] + + style A fill:#ffcdd2 + style J fill:#c8e6c9 + style K fill:#ffccbc + style P fill:#fff9c4 +``` + +--- + +## 类关系图 + +### 系统类结构与依赖关系 + +```mermaid +classDiagram + class TestResult { + +str procedure_name + +bool success + +int error_number + +str error_description + +int error_line + +str source_code + +str error_module + +str call_chain + } + + class CodeWeaver { + -int line_counter + +parse_modules(vba_project) Dict + +parse_procedures(code) Dict + +weave_procedure_with_callstack(code, proc_name, module_name) Tuple + +weave_module_all_procedures(code, module_name) Tuple + +weave_all_modules(modules) Dict + -_inject_line_numbers(lines) Tuple + -_inject_error_handler_with_callstack(lines, proc_name, module_name) List + -_get_component_code(component) str + } + + class LoggerInjector { + +str CALLSTACK_CLASS_CODE + +str LOGGER_MODULE_CODE + +inject_or_replace(wb, module_name) None + } + + class TestRunner { + +str file_path + +bool visible + +CodeWeaver code_weaver + +LoggerInjector logger_injector + +Dict source_map + +run_test(module_name, proc_name) TestResult + +run_all_tests() List~TestResult~ + +discover_all_tests() List~Dict~ + -_get_vba_code(module_name) str + -_replace_module_code(module_name, new_code) None + -_execute_macro(proc_name) None + -_get_test_result(proc_name) TestResult + -_cleanup() None + } + + class TestLogger { + <> + +LogEntry(procName, moduleName) + +LogExit() + +LogError(procName, moduleName, errNum, errDesc, errLine) + +LogSuccess() + +GetResult() String + +Initialize() + } + + class CallStack { + <> + -Collection m_Stack + +Push(procName, moduleName) + +Pop() + +GetCallChain() String + +Clear() + } + + TestRunner --> CodeWeaver : 使用 + TestRunner --> LoggerInjector : 使用 + TestRunner --> TestResult : 创建 + LoggerInjector --> TestLogger : 注入 + LoggerInjector --> CallStack : 注入 + TestLogger --> CallStack : 使用 + CodeWeaver --> TestResult : 生成 source_map +``` + +### 模块交互时序图 + +```mermaid +sequenceDiagram + participant User as 用户 + participant Main as main() + participant Runner as TestRunner + participant Weaver as CodeWeaver + participant Injector as LoggerInjector + participant Excel as Excel Application + + User->>Main: 执行命令 + Main->>Runner: 初始化(file_path, visible=False) + + alt 单个测试模式 + Main->>Runner: run_test(module, proc) + else 全项目测试模式 + Main->>Runner: run_all_tests() + Runner->>Runner: discover_all_tests() + Runner->>Runner: _weave_all_modules_inplace() + end + + Runner->>Excel: 打开工作簿 + Runner->>Weaver: parse_modules(vba_project) + Weaver-->>Runner: 模块信息 + + Runner->>Weaver: weave_module_all_procedures(code, module) + Weaver->>Weaver: _inject_line_numbers() + Weaver->>Weaver: _inject_error_handler_with_callstack() + Weaver-->>Runner: woven_code, source_map + + Runner->>Injector: inject_or_replace(wb) + Injector->>Excel: 删除旧的 TestLogger/CallStack + Injector->>Excel: 添加新的 CallStack 类模块 + Injector->>Excel: 添加新的 TestLogger 模块 + + Runner->>Excel: _replace_module_code(module, woven_code) + Runner->>Excel: _execute_macro(module.proc) + Excel-->>Runner: 执行结果 + + Runner->>Excel: TestLogger.GetResult() + Excel-->>Runner: "SUCCESS" 或 "ERROR|..." + + Runner-->>Main: TestResult + Main-->>User: 打印测试结果 + + Runner->>Excel: _cleanup() + Excel->>Excel: 关闭工作簿(不保存) + Excel->>Excel: 退出 Excel +``` + +--- + +## 附录:关键数据结构 + +### TestResult 数据类 + +```mermaid +graph TD + A[TestResult 数据类] --> B[procedure_name: str
被测试的过程名称] + A --> C[success: bool
测试是否成功] + A --> D[error_number: int
VBA 错误编号] + A --> E[error_description: str
错误描述信息] + A --> F[error_line: int
错误发生的行号标签] + A --> G[source_code: str
错误行的原始源代码] + A --> H[error_module: str
错误发生的模块名] + A --> I[call_chain: str
完整调用链
Module1.ProcA -> Module1.ProcB] + + style A fill:#e1f5ff + style C fill:#c8e6c9 + style F fill:#fff9c4 + style G fill:#fff9c4 + style I fill:#ffccbc +``` + +### Source Map 映射关系 + +```mermaid +graph LR + A[原始 VBA 代码] -->|CodeWeaver 处理| B[编织后的代码] + + B --> C[行号标签 10
x = 1] + B --> D[行号标签 20
y = x / 0 ❌] + B --> E[行号标签 30
z = y + 1] + + C --> F[source_map[10] = 'x = 1'] + D --> G[source_map[20] = 'y = x / 0'] + E --> H[source_map[30] = 'z = y + 1'] + + G --> I[VBA 错误发生在行 20] + I --> J[通过 source_map[20]
获取原始源代码] + J --> K[显示给用户:
y = x / 0] + + style A fill:#e1f5ff + style B fill:#c8e6c9 + style G fill:#ffcdd2 + style K fill:#fff9c4 +``` + +--- + +## 使用示例流程 + +### 命令行使用模式 + +```mermaid +flowchart TD + Start([用户执行命令]) --> CheckArgs{参数检查} + + CheckArgs -->|python vba_test_runner.py| ShowHelp1[显示用法1] + CheckArgs -->|python vba_test_runner.py file.xlsm --all| AllTest[全项目测试模式] + CheckArgs -->|python vba_test_runner.py file.xlsm Module Proc1 Proc2| SingleTest[单过程/多过程测试模式] + + ShowHelp1 --> End1([结束]) + + AllTest --> InitRunner1[初始化 TestRunner
visible=False] + InitRunner1 --> RunAll[执行 run_all_tests] + RunAll --> Discover[发现所有过程] + Discover --> WeaveAllModules[编织所有模块] + WeaveAllModules --> BatchExecute[批量执行测试] + BatchExecute --> ShowSummary[显示测试汇总] + ShowSummary --> Cleanup1[清理资源] + Cleanup1 --> End2([结束]) + + SingleTest --> InitRunner2[初始化 TestRunner
visible=False] + InitRunner2 --> LoopProcs[循环遍历过程列表] + LoopProcs --> RunSingle[执行 run_test] + RunSingle --> ShowSingleResult[显示单个结果] + ShowSingleResult --> MoreProcs{更多过程?} + MoreProcs -->|是| LoopProcs + MoreProcs -->|否| ShowSummary2[显示测试汇总] + ShowSummary2 --> Cleanup2[清理资源] + Cleanup2 --> End3([结束]) + + style Start fill:#e1f5ff + style End1 fill:#e1f5ff + style End2 fill:#e1f5ff + style End3 fill:#e1f5ff + style AllTest fill:#c8e6c9 + style SingleTest fill:#b3e5fc +``` + +--- + +## 总结 + +该 VBA 自动化测试系统通过**代码编织技术**实现了: + +1. **非侵入式测试**:在内存中修改代码,不保存到磁盘 +2. **精确行号定位**:通过行号标签和 Source Map 实现源代码映射 +3. **调用链追踪**:通过 CallStack 类追踪完整调用路径 +4. **批量测试支持**:支持单过程和全项目两种测试模式 +5. **详细错误报告**:包含错误位置、源代码、调用链等完整信息 + +系统的核心创新在于将编译器中的**代码编织技术**应用于 VBA 动态测试,通过在运行时注入检测代码来实现传统 IDE 无法提供的调试功能。