SuperAPI AI 工具集

code-permutation-testing

测试与质量

查看项目

更新于 10-13 17:18

技能介绍

Code Permutation Testing

概述

该技能用于对代码变体、边界情况和替代实现进行系统化测试,以保证代码的健壮性和全面的测试覆盖率。它提供输入置换、代码路径分析、变异测试和实现探索的方法论。

适用场景

在以下情况调用该技能:

  • 测试具有复杂输入域、需要边界测试的函数
  • 系统化探索边界情况和角落条件
  • 分析代码路径覆盖率和分支条件
  • 运行变异测试以验证测试套件的有效性
  • 比较替代实现以验证正确性
  • 为关键代码生成全面的测试套件
  • 验证错误处理与恢复路径

核心测试模式

1. 输入置换测试

生成覆盖以下内容的全面测试用例:

  • 边界值:最小值、最大值、刚好在边界内、刚好在边界外
  • 边界情况:空输入、null 值、极端尺寸
  • 类型变化:不同数值类型、字符串编码、数据结构
  • 组合测试:输入组合的成对测试与 n 路测试

加载 references/boundary_patterns.md 获取常见边界测试模式与策略。

使用 scripts/generate_boundaries.py 从函数签名自动生成边界测试用例。

2. 代码路径分析

分析代码中所有可能的执行路径:

  • 分支覆盖:测试所有条件分支
  • 循环覆盖:零次、一次、多次、最大迭代次数
  • 异常路径:系统化地强制触发错误条件
  • 状态转换:测试所有有效和无效的状态变更

使用 scripts/analyze_paths.py 识别未覆盖的代码路径并生成测试建议。

3. 变异测试

通过引入受控变异来验证测试套件的有效性:

Rust 项目:

# Install cargo-mutants
cargo install cargo-mutants

# Run mutation testing
cargo mutants --no-shuffle --test-timeout 30

# Generate detailed report
cargo mutants --json > mutations.json

Python 项目:

# Install mutmut
pip install mutmut

# Run mutation testing
mutmut run --paths-to-mutate src/

# Show results
mutmut results

加载 references/mutation_testing.md 获取详细的变异测试指南与结果解读。

4. 实现替代方案

测试不同的算法实现方式:

  • 迭代 vs 递归:比较实现以验证栈安全性
  • 可变 vs 不可变:测试函数式与命令式变体
  • 同步 vs 异步:验证并发行为
  • 朴素 vs 优化:验证优化是否保持正确性

工作流

第一步:分析目标代码

首先理解代码结构:

  • 识别函数签名与参数类型
  • 梳理控制流与决策点
  • 记录错误处理与边界情况
  • 记录假设与不变量

第二步:生成测试矩阵

创建全面的测试覆盖:

# Example for a function: divide(a: i32, b: i32) -> Result<i32, Error>

# Boundary tests
test_cases = [
    # Normal cases
    (10, 2, Ok(5)),
    (10, 3, Ok(3)),

    # Boundary values
    (i32::MAX, 1, Ok(i32::MAX)),
    (i32::MIN, 1, Ok(i32::MIN)),
    (i32::MIN, -1, Err(Overflow)),  # Special overflow case

    # Edge cases
    (0, 5, Ok(0)),
    (5, 0, Err(DivisionByZero)),
    (0, 0, Err(DivisionByZero)),

    # Sign variations
    (-10, 2, Ok(-5)),
    (10, -2, Ok(-5)),
    (-10, -2, Ok(5)),
]

第三步:执行置换测试

运行生成的测试矩阵:

  • 执行每个测试用例
  • 验证预期结果
  • 检查意外行为
  • 监控性能特征

第四步:分析覆盖率

评估测试完整性:

  • 生成覆盖率报告
  • 识别未覆盖路径
  • 运行变异测试
  • 为缺口添加测试

第五步:记录结果

创建全面的测试文档:

  • 列出所有已测场景
  • 记录发现的边界情况
  • 记录性能特征
  • 标注关键路径

语言特定指南

Rust

#[cfg(test)]
mod permutation_tests {
    use super::*;
    use proptest::prelude::*;

    // Property-based testing for automatic permutation
    proptest! {
        #[test]
        fn test_function_properties(
            a in any::<i32>(),
            b in any::<i32>().prop_filter("non-zero", |x| *x != 0)
        ) {
            let result = divide(a, b);
            prop_assert!(result.is_ok());
            prop_assert_eq!(result.unwrap(), a / b);
        }
    }

    // Boundary value testing
    #[test]
    fn test_boundaries() {
        let boundaries = vec![
            i32::MIN, i32::MIN + 1, -1, 0, 1, i32::MAX - 1, i32::MAX
        ];

        for a in &boundaries {
            for b in &boundaries {
                if *b != 0 {
                    let result = divide(*a, *b);
                    // Verify result or expected error
                }
            }
        }
    }
}

Python

import hypothesis.strategies as st
from hypothesis import given, assume
import pytest

# Property-based testing
@given(st.integers(), st.integers())
def test_division_properties(a, b):
    assume(b != 0)  # Precondition
    result = divide(a, b)
    assert result == a // b

# Parametrized boundary testing
@pytest.mark.parametrize("a,b,expected", [
    (10, 2, 5),
    (sys.maxsize, 1, sys.maxsize),
    (-sys.maxsize-1, 1, -sys.maxsize-1),
    (0, 5, 0),
    # Add more boundary cases
])
def test_boundaries(a, b, expected):
    assert divide(a, b) == expected

资源

脚本:

  • scripts/generate_boundaries.py - 分析函数签名并生成边界测试用例
  • scripts/analyze_paths.py - 识别代码路径并为未覆盖分支建议测试

参考:

  • references/boundary_patterns.md - 边界值分析与边界情况识别的常见模式
  • references/mutation_testing.md - 变异测试工具与结果解读的综合指南

最佳实践

  • 从边界开始:在正常用例之前先测试极限值
  • 考虑组合:对多个参数使用成对测试
  • 测试错误路径:确保错误处理健壮
  • 使用基于属性的测试:让工具自动生成测试用例
  • 用变异验证:确保测试确实能捕获缺陷
  • 记录发现:为将来参考记录边界情况
  • 自动化生成:使用脚本创建测试矩阵
  • 监控性能:跟踪各置换下的执行时间