Code Diff 测试覆盖分析工具 — 开发提测后,自动发现遗漏的测试点

Code Diff 测试覆盖分析工具 --- 开发提测后,自动发现遗漏的测试点


一、背景

痛点

在日常开发测试流程中,你是否遇到过这些问题?

场景一:开发提测后,测试同学凭经验判断测试范围

开发说"我就改了一行代码",但这一行可能影响多个逻辑分支。测试同学需要手动看 Code Diff,凭经验判断哪些功能需要回归。遇到新人或不熟悉业务的情况,很容易遗漏关键场景。

场景二:评审通过的用例是静态的,代码变了它不会自动更新

每次迭代评审通过了一批测试用例,但随着代码多次修改,有些用例已经不适合当前版本了------前置条件变了、接口参数变了、预期结果变了。但没人记得去更新它们。

场景三:Code Diff 会告诉你"改了哪里",但不会告诉你"哪里没测"

Git 的 diff 能清晰地展示每一行代码变更,但它不会告诉你:新增的这个 if 分支有没有对应的测试用例?修改的这个条件判断是不是遗漏了边界值测试?

目标

基于这些痛点,我开发了这个工具,它能做到:

  • 自动获取 Git Code Diff,解析出结构化的变更信息
  • 分析代码变更的影响域,识别出变更的函数、逻辑分支、调用链
  • 与评审通过的测试用例智能比对,自动发现哪些逻辑分支没有被覆盖
  • 给出补充建议,告诉你要新增哪些用例、更新哪些用例

二、整体思路

核心流程可以用一句话概括:

"代码改了哪里 → 影响了哪些函数和分支 → 现有用例覆盖了没有 → 没覆盖的给出建议"

这个流程分为 5 个步骤:

复制代码
提交代码 → 提取 Diff → 分析影响域 → 匹配用例 → LLM 智能分析 → 输出报告

流程图

复制代码
┌─────────────────────────────────────────────────────────────────────┐
│                    输入:Git Commit / Diff 文件                      │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│              Step 1:DiffParser --- 解析代码差异                        │
│                                                                     │
│  输入:git diff 输出                                                 │
│  输出:结构化变更信息(文件列表、变更行、变更类型)                    │
│  示例:                                                              │
│    UserService.java  modified  +7/-1                                 │
│      Hunk L10: 8 行变更                                             │
│        [removed] login(String, String)                               │
│        [added]   login(String, String, String)                       │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│              Step 2:ImpactAnalyzer --- 分析影响域                      │
│                                                                     │
│  输入:Diff 结果 + 源文件                                            │
│  输出:变更函数、逻辑分支、调用链、风险等级                           │
│  示例:                                                              │
│    变更函数: login() params_changed=True                             │
│    影响分支: captcha != null && captcha.length() != 4                │
│    调用链:   login() → authenticate()                                │
│    风险等级: medium                                                  │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│              Step 3:CaseMatcher --- 匹配现有用例                        │
│                                                                     │
│  输入:影响域报告 + 用例库                                            │
│  匹配策略:                                                          │
│    ① 文件路径匹配 --- 用例关联了源文件                                 │
│    ② 函数名匹配   --- 用例关联了函数                                   │
│    ③ 标签匹配     --- 用例打了模块标签                                 │
│    ④ 语义匹配     --- 场景描述包含关键词                               │
│  输出:匹配到的用例列表 + 匹配度                                     │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│              Step 4:LLMAnalyzer --- 智能分析覆盖缺口                     │
│                                                                     │
│  将 Diff + 影响域 + 用例 打包成 Prompt,发给 LLM                     │
│  LLM 分析:                                                         │
│    ① 现有用例覆盖了哪些逻辑分支?                                    │
│    ② 哪些分支没有覆盖?                                              │
│    ③ 需要补充哪些测试场景?                                          │
│    ④ 哪些现有用例需要更新?                                          │
│  输出:结构化的分析结果(JSON)                                      │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│              Step 5:ReportGenerator --- 生成报告                       │
│                                                                     │
│  输出格式:Markdown / HTML                                          │
│  报告内容:                                                          │
│    ① 变更概览(文件、行数、风险等级)                                │
│    ② 影响域分析(函数、分支、调用链)                                │
│    ③ 用例覆盖分析(已覆盖/部分覆盖/未覆盖)                          │
│    ④ 建议新增用例(场景、步骤、预期结果)                            │
│    ⑤ 需更新用例(修改建议)                                          │
└─────────────────────────────────────────────────────────────────────┘

三、项目结构

复制代码
code_diff_test_reviewer/
├── main.py                        # 主入口(CLI 命令行)
├── config.py                      # 配置(Ollama 地址、模型等)
├── requirements.txt               # 依赖
│
├── models/                        # 数据模型层
│   ├── diff.py                    # Diff 数据结构
│   ├── impact.py                  # 影响域数据结构
│   └── test_case.py               # 测试用例数据结构
│
├── parsers/                       # 解析层
│   └── diff_parser.py             # Git Diff 解析器
│
├── analyzers/                     # 分析层
│   ├── impact_analyzer.py         # 影响域分析器
│   └── llm_analyzer.py            # LLM 智能分析器
│
├── matchers/                      # 匹配层
│   └── case_matcher.py            # 用例匹配器
│
├── reporters/                     # 报告层
│   └── report_generator.py        # 报告生成器
│
└── examples/                      # 示例数据
    ├── sample_diff.txt            # 示例 Diff
    └── sample_cases.json          # 示例用例库

架构分层说明

复制代码
┌──────────────────────────────────────────────┐
│              入口层 (main.py)                 │
│   命令行参数解析、流程编排、异常处理           │
├──────────────────────────────────────────────┤
│              数据模型层 (models/)             │
│   定义核心数据结构,各模块间通过模型通信       │
├──────────────┬───────────────┬───────────────┤
│   解析层      │   分析层      │   匹配层      │
│  diff_parser │ impact_analyzer│ case_matcher │
│              │ llm_analyzer  │               │
├──────────────┴───────────────┴───────────────┤
│              报告层 (reporters/)              │
│   Markdown/HTML 报告生成                      │
└──────────────────────────────────────────────┘

四、核心代码展示

4.1 数据模型层

数据模型是各模块之间通信的"协议",定义了清晰的数据结构。

Diff 数据结构models/diff.py):

python 复制代码
@dataclass
class LineChange:
    line_num: int           # 行号
    content: str            # 行内容
    type: str               # added / removed / context

@dataclass
class Hunk:
    start_line: int         # 起始行号
    lines: List[LineChange] # 行级变更列表

@dataclass
class FileChange:
    file_path: str          # 文件路径
    change_type: str        # added / modified / deleted / renamed
    hunks: List[Hunk]       # 变更块列表
    added_lines: int        # 新增行数
    removed_lines: int      # 删除行数

@dataclass
class DiffResult:
    files: List[FileChange] # 变更文件列表
    summary: DiffSummary    # 变更概览

影响域数据结构models/impact.py):

python 复制代码
@dataclass
class FunctionChange:
    func_name: str          # 函数名
    file_path: str          # 文件路径
    change_type: str        # added / modified / deleted
    params_changed: bool    # 参数是否变更

@dataclass
class Branch:
    file_path: str          # 文件路径
    line: int               # 行号
    condition: str          # 条件表达式
    branch_type: str        # if / else / switch / try / catch
    is_changed: bool        # 是否被修改

@dataclass
class CallChain:
    caller_func: str        # 调用方函数
    callee_func: str        # 被调用方函数
    is_direct: bool         # 是否直接调用

@dataclass
class ImpactReport:
    changed_functions: List[FunctionChange]
    call_chains: List[CallChain]
    affected_branches: List[Branch]
    risk_level: str          # high / medium / low

测试用例数据结构models/test_case.py):

python 复制代码
@dataclass
class TestCase:
    id: str                          # 用例编号
    module: str                      # 所属模块
    scenario: str                    # 测试场景
    precondition: str                # 前置条件
    steps: str                       # 测试步骤
    expected: str                    # 预期结果
    priority: str                    # P0 / P1 / P2
    tags: List[str]                  # 标签
    source_files: List[str]          # 关联源文件
    source_functions: List[str]      # 关联函数

@dataclass
class AnalysisResult:
    covered_branches: List[str]           # 已覆盖的分支
    uncovered_branches: List[str]         # 未覆盖的分支
    suggested_new_cases: List[SuggestedCase]  # 建议新增用例
    need_update_cases: List[CaseUpdate]       # 需更新用例
    risk_assessment: str                     # 风险评估
    summary: str                             # 总结

4.2 DiffParser --- 解析 Git Diff

这是整个流程的第一步,也是最基础的一步。它的核心能力是:

  1. 解析 git diff 输出,提取文件级变更
  2. 提取每个文件的变更块(Hunk)和行级变更
  3. 计算新增/删除行数

核心代码parsers/diff_parser.py):

python 复制代码
class DiffParser:
    def parse(self, diff_text: str) -> Optional[DiffResult]:
        """
        解析 diff 文本,返回结构化结果
        """
        if not diff_text.strip():
            return None

        files = []
        current_file = None
        current_hunk = None
        summary = DiffSummary()

        for line in diff_text.split("\n"):
            # 文件头: diff --git a/file b/file
            if line.startswith("diff --git "):
                # 保存上一个文件
                if current_file and current_hunk:
                    current_file.hunks.append(current_hunk)
                if current_file:
                    files.append(current_file)

                parts = line.split()
                b_path = parts[3]
                file_path = b_path[2:] if b_path.startswith("b/") else b_path
                current_file = FileChange(
                    file_path=file_path, change_type="modified", hunks=[]
                )
                continue

            # 变更块头: @@ -a,b +c,d @@
            hunk_match = re.match(r"^@@ -(\d+),?\d* \+(\d+),?\d* @@", line)
            if hunk_match:
                if current_file and current_hunk:
                    current_file.hunks.append(current_hunk)
                current_hunk = Hunk(
                    start_line=int(hunk_match.group(2)), lines=[]
                )
                continue

            # 行级变更
            if current_hunk and line.startswith(("+", "-", " ")):
                line_type = {"+": "added", "-": "removed", " ": "context"}[line[0]]
                current_hunk.lines.append(LineChange(
                    line_num=current_hunk.start_line + len(current_hunk.lines),
                    content=line[1:],
                    type=line_type,
                ))
                # 统计
                if line_type == "added":
                    current_file.added_lines += 1
                elif line_type == "removed":
                    current_file.removed_lines += 1
                # context 行不计数,但影响行号
                if line_type in ("added", "removed"):
                    pass  # 行号增长由 context 行驱动

        # 收尾
        if current_file and current_hunk:
            current_file.hunks.append(current_hunk)
        if current_file:
            files.append(current_file)

        # 计算 summary
        summary.total_files = len(files)
        summary.total_added = sum(f.added_lines for f in files)
        summary.total_removed = sum(f.removed_lines for f in files)
        summary.modified_files = [f.file_path for f in files]

        return DiffResult(files=files, summary=summary)

4.3 ImpactAnalyzer --- 影响域分析

这个模块是核心分析能力之一,它需要做到:

  1. 函数识别:通过正则匹配函数定义,用括号匹配确定函数范围
  2. 分支提取:识别变更行附近的条件分支(if/else/switch/try-catch)
  3. 调用链追踪:分析变更函数调用了哪些函数,以及哪些函数调用了它
  4. 风险评估:根据参数变更、分支数量、调用链长度综合评估风险

函数识别核心逻辑analyzers/impact_analyzer.py):

python 复制代码
class ImpactAnalyzer:
    def analyze(self, diff_result: DiffResult, repo_path: str = ".") -> ImpactReport:
        """分析变更影响域"""
        report = ImpactReport()

        for file_change in diff_result.files:
            file_path = os.path.join(repo_path, file_change.file_path)
            if not os.path.exists(file_path):
                continue

            with open(file_path, "r", encoding="utf-8", errors="ignore") as f:
                source_lines = f.readlines()

            # 收集变更行号
            changed_lines = set()
            for hunk in file_change.hunks:
                for line in hunk.lines:
                    if line.type in ("added", "removed"):
                        changed_lines.add(line.line_num)

            # 识别变更函数
            functions = self._extract_functions(
                file_change.file_path, source_lines, changed_lines
            )
            report.changed_functions.extend(functions)

            # 提取变更附近的逻辑分支
            branches = self._extract_branches(
                file_change.file_path, source_lines, changed_lines
            )
            report.affected_branches.extend(branches)

        # 追踪调用链
        if report.changed_functions:
            call_chains = self._trace_call_chains(report.changed_functions, repo_path)
            report.call_chains.extend(call_chains)

        # 评估风险等级
        report.risk_level = self._assess_risk(report)
        return report

函数范围检测:这是比较有挑战的部分。需要支持 C 风格语言(大括号匹配)和 Python(缩进匹配):

python 复制代码
def _find_func_end(self, source_lines: List[str], func_start: int) -> int:
    """通过括号匹配找到函数结束行"""
    first_line = source_lines[func_start - 1]
    brace_count = first_line.count("{") - first_line.count("}")

    if brace_count > 0:
        # C 风格:用括号匹配
        for i in range(func_start, len(source_lines)):
            line = source_lines[i]
            brace_count += line.count("{") - line.count("}")
            if brace_count <= 0:
                return i + 1
        return len(source_lines)
    else:
        # Python 风格:检测缩进
        # ... 通过缩进级别判断函数结束

4.4 CaseMatcher --- 用例匹配器

匹配策略按照优先级分为 4 种:

python 复制代码
class CaseMatcher:
    def match(self, impact_report, cases) -> MatchedCases:
        """
        匹配策略(按优先级):
        1. 文件路径匹配:用例标注了关联的源文件
        2. 函数名匹配:用例标注了关联的函数
        3. 标签匹配:用例标注了模块/功能标签
        4. 语义匹配:场景描述中的关键词匹配
        """
        for case in cases:
            score = 0.0
            match_type = ""

            # 策略 1:文件路径匹配
            for cf in case.source_files:
                for changed_file in changed_files:
                    if cf in changed_file or changed_file in cf:
                        score += 0.5
                        match_type = "file_match"

            # 策略 2:函数名匹配
            for sf in case.source_functions:
                if sf in changed_funcs:
                    score += 0.4
                    match_type = "function_match"

            # 策略 3:标签匹配
            for tag in case.tags:
                if tag.lower() in changed_tags:
                    score += 0.15
                    if not match_type:
                        match_type = "tag_match"

            # 策略 4:语义匹配
            if any(func.lower() in case.scenario.lower()
                   for func in changed_funcs):
                score += 0.1
                if not match_type:
                    match_type = "semantic_match"

            if score > 0:
                # 记录匹配结果
                ...

4.5 LLMAnalyzer --- 智能分析(核心模块)

这是最核心的模块,它将 Diff 结果、影响域分析、现有用例打包成 Prompt,发给大模型,让大模型分析覆盖缺口。

Prompt 结构

python 复制代码
def _build_prompt(self, diff_result, impact_report, matched_cases) -> str:
    sections = [
        "## 一、代码变更概览",
        f"修改文件: {s.total_files} 个, 新增: {s.total_added} 行, 删除: {s.total_removed} 行",
        "## 二、详细代码变更",
        diff_detail,
        "## 三、影响域分析",
        "变更函数: ...", "影响分支: ...", "调用链: ...",
        "## 四、现有测试用例",
        cases_detail,
        "## 五、分析指令",
        """请分析:
        1. 现有用例是否覆盖了所有逻辑分支?
        2. 是否引入了新的边界条件?
        3. 是否引入了新的异常路径?
        4. 哪些用例需要更新?
        5. 请列出需要补充的测试场景

        输出格式(JSON):
        {
          "covered_branches": [...],
          "uncovered_branches": [...],
          "suggested_new_cases": [
            {"scenario": "...", "reason": "...", "priority": "P1", ...}
          ],
          "need_update_cases": [...],
          "risk_assessment": "medium",
          "summary": "..."
        }"""
    ]
    return "\n\n".join(sections)

LLM 调用:使用 OpenAI 兼容 SDK 调用 Ollama 本地模型,支持流式输出:

python 复制代码
def _call_llm(self, prompt: str) -> str:
    collected = []
    stream = self.client.chat.completions.create(
        model=self.model,
        messages=[
            {"role": "system", "content": SYSTEM_PROMPT},
            {"role": "user", "content": prompt},
        ],
        temperature=ANALYSIS_TEMPERATURE,
        max_tokens=8192,
        stream=True,
    )
    for chunk in stream:
        delta = chunk.choices[0].delta if chunk.choices else None
        if delta and delta.content:
            collected.append(delta.content)
    return "".join(collected)

4.6 主入口 --- 流程编排

main.py 是整个流程的编排者,它将 5 个步骤串联起来:

python 复制代码
def main():
    # 解析命令行参数
    args = parse_args()

    # Step 1: 获取并解析 Diff
    diff_parser = DiffParser()
    diff_result = diff_parser.parse_from_commit(args.commit_id)

    # Step 2: 影响域分析
    impact_analyzer = ImpactAnalyzer()
    impact_report = impact_analyzer.analyze(diff_result, repo_path=args.repo_path)

    # Step 3: 加载并匹配用例
    cases = load_cases(args.cases)
    case_matcher = CaseMatcher()
    matched_cases = case_matcher.match(impact_report, cases)

    # Step 4: LLM 智能分析
    llm_analyzer = LLMAnalyzer()
    analysis_result = llm_analyzer.analyze(
        diff_result, impact_report, matched_cases
    )

    # Step 5: 生成报告
    report_gen = ReportGenerator()
    report_text = report_gen.generate_markdown(
        diff_result, impact_report, matched_cases, analysis_result
    )
    with open(output_path, "w", encoding="utf-8") as f:
        f.write(report_text)

4.7 用例格式

测试用例采用 JSON 格式存储,每个用例关联了源文件和函数名,便于自动匹配:

json 复制代码
{
  "test_cases": [
    {
      "id": "TC-001",
      "module": "用户登录",
      "scenario": "用户名密码正确登录成功",
      "precondition": "用户已注册",
      "steps": "1. 输入用户名\n2. 输入密码\n3. 点击登录",
      "expected": "登录成功,跳转首页",
      "priority": "P0",
      "tags": ["login", "UserService", "authentication"],
      "source_files": ["src/services/UserService.java"],
      "source_functions": ["UserService.login"]
    },
    {
      "id": "TC-002",
      "module": "用户登录",
      "scenario": "用户名为空登录失败",
      "precondition": "登录页面",
      "steps": "1. 用户名留空\n2. 输入密码\n3. 点击登录",
      "expected": "提示用户名不能为空",
      "priority": "P1",
      "tags": ["login", "validation"],
      "source_files": ["src/services/UserService.java"],
      "source_functions": ["UserService.login"]
    }
  ]
}

五、实际效果演示

场景

假设有一个电商系统,最近一次提交改了 2 个文件:

  1. UserService.java --- login() 方法新增了验证码参数,register() 新增了邮箱格式校验
  2. OrderService.java --- createOrder() 新增了优惠券参数,金额上限从 10000 调整到 50000

运行命令

bash 复制代码
python main.py --commit-id HEAD~1 --cases test_cases.json

输出结果

复制代码
============================================================
  Code Diff 测试覆盖分析工具
============================================================

[1/5] 获取代码差异...
  变更文件: 2 个 | 新增 30 行 | 删除 4 行
    modified: src/services/UserService.java (+14/-1)
    modified: src/services/OrderService.java (+16/-3)

[2/5] 分析变更影响域...
  变更函数: 6 个
    createOrder (params_changed: True)
    applyCoupon (params_changed: True)
    login (params_changed: True)
    register (params_changed: True)
  影响分支: 15 个
    L6  [if] orderId == null || orderId.isEmpty()
    L12 [if] amount > 50000
    L16 [if] couponCode != null && !couponCode.isEmpty()
    L23 [if] couponCode.equals("SAVE10")
  调用链: 24 条
  风险等级: medium

[3/5] 加载评审通过用例...
  加载用例: 6 个
  匹配到: 6 个相关用例
    [OK]   已覆盖: 4 个
    [WARN] 部分覆盖: 2 个
    [MISS] 未覆盖: 0 个

[4/5] LLM 智能分析...
  分析结论: 本次变更涉及验证码校验、邮箱格式校验、
  优惠券支持等多个新功能,现有用例覆盖不足...
  建议新增用例: 3 个
  建议更新用例: 1 个

[5/5] 生成报告...
  报告已生成: output/report.md

完成!

生成的报告内容

生成的报告包含以下核心部分:

1. 变更概览

指标
修改文件 2 个
新增行 30 行
删除行 4 行
风险等级 Medium

2. 影响域分析

检测到 6 个变更函数,15 个影响的逻辑分支,24 条调用链。其中 login()createOrder() 是参数变更,风险较高。

3. 用例覆盖分析

  • 已覆盖 4 个:基础登录、注册、订单场景
  • 部分覆盖 2 个:缺少验证码、优惠券相关的分支场景

4. LLM 建议新增的用例

编号 场景 优先级 原因
SUG-001 验证码长度不为4位登录失败 P1 新增验证码长度校验逻辑
SUG-002 邮箱格式不正确注册失败 P1 新增邮箱格式校验
SUG-003 使用优惠券下单金额计算正确 P1 新增优惠券参数和折扣计算

5. 需更新的用例

用例 原因 建议修改
TC-005 订单金额上限从 10000 变更为 50000 更新用例中的金额阈值

六、使用方式

安装

bash 复制代码
# 1. 克隆项目
git clone <项目地址>
cd code_diff_test_reviewer

# 2. 安装依赖
pip install -r requirements.txt

# 3. 配置 Ollama(可选,用于 LLM 分析)
# 修改 config.py 中的 Ollama 地址

命令行使用

bash 复制代码
# 方式1:基于 Commit 分析(在 Git 仓库中运行)
python main.py --commit-id HEAD~1 --cases test_cases.json

# 方式2:基于分支对比
python main.py --diff-branch main --cases test_cases.json

# 方式3:直接指定 Diff 文件(不需要 Git 仓库)
python main.py --diff-file diff.txt --cases test_cases.json

# 方式4:指定输出格式和路径
python main.py --commit-id HEAD~1 --cases cases.json \
    --format html -o report.html

# 方式5:过滤文件范围
python main.py --commit-id HEAD~1 --cases cases.json \
    --filter "src/services/"

# 方式6:跳过 LLM 分析(仅输出结构化信息)
python main.py --commit-id HEAD~1 --cases cases.json --no-llm

参数说明

参数 说明
--commit-id Git Commit ID 或 HEAD~N
--diff-branch 对比的目标分支名
--diff-file 直接指定 diff 文件路径
--cases / -c 评审通过用例文件(必填)
--output / -o 输出报告路径
--format / -f 报告格式:markdown / html
--filter 只分析指定路径的变更文件
--repo-path Git 仓库路径
--no-llm 跳过 LLM 分析

七、技术亮点

1. 多语言函数识别

支持 Java、Python、JavaScript、Go、C++ 等主流语言的函数定义识别。通过正则匹配修饰符 + 返回类型 + 函数名的模式,结合括号匹配/缩进分析确定函数范围。

2. 智能调用链追踪

不仅能分析变更函数本身,还能追踪:

  • 向上调用:哪些函数调用了变更函数(影响范围扩散)
  • 向下调用:变更函数调用了哪些函数(内部逻辑变更)

3. 多策略用例匹配

4 种匹配策略,从文件路径到语义关键词,确保高匹配率。匹配度评分让测试同学能快速判断哪些用例是强相关、哪些是弱相关。

4. LLM 驱动的智能分析

利用大模型的理解能力,自动化分析"代码变更 vs 测试覆盖"的缺口。相比纯规则匹配,LLM 能理解代码语义,发现更隐蔽的遗漏场景。

5. 灵活的输入方式

支持 3 种输入方式:

  • Commit 模式:集成到 CI/CD 流水线,每次提交自动分析
  • 分支对比模式:MR/PR 时自动分析
  • Diff 文件模式:不需要 Git 仓库,传入任何 diff 文本即可

八、适用场景

场景 1:CI/CD 流水线集成

在 GitLab CI / GitHub Actions 中配置,每次 MR 自动运行:

yaml 复制代码
# .gitlab-ci.yml
test-coverage-check:
  script:
    - python main.py --diff-branch main \
        --cases test_cases.json \
        --output report.html
  artifacts:
    paths: [report.html]

场景 2:提测前自检

开发提测前,自己跑一遍,看看有没有遗漏的测试点:

bash 复制代码
python main.py --commit-id HEAD~1 --cases test_cases.json

场景 3:测试用例评审辅助

测试同学在看 MR 时,用工具辅助分析,快速定位需要补充的测试场景。

场景 4:新人培训

新人不熟悉业务,看 Code Diff 很难判断测试范围。用工具辅助分析,快速了解变更影响。


九、总结

这个工具的核心价值在于:把"代码变更"和"测试覆盖"之间的鸿沟自动化填补

以前,测试同学需要手动看 Code Diff,凭经验判断哪些功能需要测试。现在,工具自动分析变更影响域,与测试用例智能比对,精准定位遗漏的测试场景。

以前,评审通过的用例是静态的,代码变了也不会有任何提示。现在,工具会自动检测哪些用例需要更新,给出具体的修改建议。

整个工具基于 Python 开发,轻量易用,可以灵活集成到现有的 CI/CD 流水线中。本文配合 Ollama 本地大模型,如果其他同学公司有采购的大模型也可以接入。

本文为 CSDN 分享文档,如需了解更多细节,欢迎留言交流。

相关推荐
tachibana21 小时前
Embedding 有哪几种算法?
人工智能·算法·ai·大模型·llm·embedding·agent
小小工匠1 小时前
Open WebUI 深度解析:把大模型装进自己机房的那一层「AI 操作系统」
人工智能·openwebui
minhuan1 小时前
基于Playwright数据采集,大模型对接Flask+SQLite,平滑升级向量库与分布式微服务26.5
人工智能·flask·大模型应用·大模型业务集成·微服务架构演进
动物园猫1 小时前
驾驶员危险行为目标检测数据集:3类别、14,000张图像 | 目标检测
人工智能·目标检测·计算机视觉
AI的探索之旅1 小时前
97 个 OpenCV 实例(二十一):音频进阶,音视频同抽与麦克风采集
人工智能·opencv·音视频
Zenova EdgeOS1 小时前
储能项目 BOT 模式演变:从单一建设到全周期运营的多元路径
大数据·人工智能
TMT星球1 小时前
萤石亮相IFA 2026,多款AI创新产品集中展示,全球化智能生活体验引关注
大数据·人工智能·生活
知了一笑1 小时前
Token消费不为结果买单
人工智能·aigc·token
deepdata_cn1 小时前
机器学习≠逻辑推理!分清统计AI与符号AI
人工智能·机器学习