测试数据策略Skill test-data-strategy

该技能专注于规划全面的测试数据管理策略,涵盖合成数据生成、数据匿名化、版本控制和环境特定数据策略,适用于软件测试、DevOps 和持续集成场景,帮助确保测试数据质量、保护敏感信息并提高测试效率。关键词:测试数据、合成数据、匿名化、版本控制、环境策略、软件测试、数据管理。

测试 0 次安装 0 次浏览 更新于 3/11/2026

name: 测试数据策略 description: 规划全面的测试数据管理,包括合成数据生成、数据匿名化、版本控制和环境特定策略。 allowed-tools: Read, Write, Glob, Grep, Task, WebSearch, WebFetch

测试数据策略

何时使用此技能

使用此技能当:

  • 测试数据策略任务 - 处理规划全面的测试数据管理,包括合成数据生成、数据匿名化、版本控制和环境特定策略
  • 规划或设计 - 需要测试数据策略方法的指导
  • 最佳实践 - 希望遵循既定模式和标准

概述

有效的测试数据管理确保测试在正确时间拥有正确数据,同时保护敏感信息并跨环境维护数据质量。

测试数据类型

类型 来源 使用场景 隐私风险
合成数据 生成 单元/集成测试
子集数据 生产样本 性能测试 中等
脱敏数据 匿名化生产 真实场景
生产克隆 完整副本 预生产验证
基线数据 策划参考 回归测试

测试数据策略模板

# 测试数据策略: [项目名称]

## 1. 数据需求

### 按测试级别
| 级别 | 数据来源 | 体积 | 刷新 |
|-------|-------------|--------|---------|
| 单元 | 合成 | 最小 | 按需 |
| 集成 | 合成/子集 | 中等 | 每次运行 |
| 系统 | 脱敏生产 | 真实 | 每周 |
| 性能 | 缩放合成 | 生产类似 | 每次发布 |

### 按功能区域
| 功能 | 关键数据 | 所需体积 | 敏感性 |
|---------|---------------|-----------------|-------------|
| 认证 | 用户账户 | 1000 | 高 |
| 支付 | 交易 | 10000 | 高 |
| 报告 | 历史数据 | 100万条记录 | 中等 |

## 2. 数据生成策略

### 合成数据工具
- **单元测试**: AutoFixture, Bogus
- **集成**: TestContainers + 种子
- **性能**: 批量生成器

### 生成规则
| 实体 | 关键字段 | 生成逻辑 |
|--------|------------|------------------|
| 用户 | 邮箱 | `{guid}@test.example.com` |
| 订单 | 金额 | `Random(1, 10000)` |
| 日期 | 时间戳 | `Random(now-1y, now)` |

## 3. 数据匿名化

### PII 字段
| 字段 | 原始 | 匿名化方法 |
|-------|----------|---------------------|
| 姓名 | John Smith | Faker 生成 |
| 邮箱 | john@acme.com | `hash@domain.test` |
| 电话 | 555-123-4567 | `555-xxx-xxxx` |
| SSN | 123-45-6789 | `xxx-xx-xxxx` |
| 地址 | 123 Main St | Faker 地址 |
| 出生日期 | 1985-03-15 | 随机天平移 |

### 匿名化规则
- 保持数据关系
- 维护引用完整性
- 保留统计属性
- 移除唯一标识符

## 4. 环境策略

### 开发环境
- 来源: 100% 合成
- 刷新: 按需
- 体积: 最小

### QA 环境
- 来源: 脱敏生产子集
- 刷新: 每周
- 体积: 生产的 10%

### 预生产环境
- 来源: 脱敏生产克隆
- 刷新: 每次发布前
- 体积: 生产的 100%

### 性能环境
- 来源: 缩放合成
- 刷新: 性能运行前
- 体积: 生产的 150%

## 5. 数据版本控制

### 基线管理
- 版本化基线数据集
- 跟踪数据模式变化
- 保持向后兼容性
- 文档化数据依赖

### 刷新程序
1. 触发: [手动/计划/事件]
2. 来源: [生产/备份/生成器]
3. 转换: [匿名化步骤]
4. 加载: [目标环境]
5. 验证: [验证检查]

## 6. 合规要求

### GDPR 合规
- [ ] 非生产环境中无真实欧盟公民数据
- [ ] 支持删除权
- [ ] 应用数据最小化
- [ ] 匿名化同意跟踪

### HIPAA 合规
- [ ] PHI 完全去标识化
- [ ] 应用安全港方法
- [ ] 维护审计日志
- [ ] 验证访问控制

合成数据生成 (.NET)

使用 Bogus

using Bogus;

public class TestDataGenerator
{
    public static Faker<Customer> CustomerFaker => new Faker<Customer>()
        .RuleFor(c => c.Id, f => f.Random.Guid())
        .RuleFor(c => c.FirstName, f => f.Person.FirstName)
        .RuleFor(c => c.LastName, f => f.Person.LastName)
        .RuleFor(c => c.Email, (f, c) => f.Internet.Email(c.FirstName, c.LastName))
        .RuleFor(c => c.Phone, f => f.Phone.PhoneNumber())
        .RuleFor(c => c.DateOfBirth, f => f.Date.Past(50, DateTime.Now.AddYears(-18)))
        .RuleFor(c => c.Address, f => new Address
        {
            Street = f.Address.StreetAddress(),
            City = f.Address.City(),
            State = f.Address.StateAbbr(),
            Zip = f.Address.ZipCode()
        });

    public static Faker<Order> OrderFaker(Customer customer) => new Faker<Order>()
        .RuleFor(o => o.Id, f => f.Random.Guid())
        .RuleFor(o => o.CustomerId, customer.Id)
        .RuleFor(o => o.OrderDate, f => f.Date.Recent(30))
        .RuleFor(o => o.Total, f => f.Finance.Amount(10, 1000))
        .RuleFor(o => o.Status, f => f.PickRandom<OrderStatus>());
}

使用 AutoFixture

using AutoFixture;
using AutoFixture.Xunit2;

public class CustomerTests
{
    [Theory, AutoData]
    public void CreateCustomer_WithValidData_Succeeds(Customer customer)
    {
        // AutoFixture 自动生成有效客户
        var result = _service.Create(customer);
        Assert.True(result.IsSuccess);
    }

    [Theory, AutoData]
    public void ProcessOrder_CalculatesCorrectTotal(
        [Frozen] Customer customer,
        Order order,
        List<OrderItem> items)
    {
        // Frozen 确保客户被重用
        // 订单和项目自动生成
        order.Items = items;
        var total = _calculator.Calculate(order);
        Assert.Equal(items.Sum(i => i.Quantity * i.Price), total);
    }
}

播种测试数据库

public class TestDatabaseSeeder
{
    public static async Task SeedAsync(AppDbContext context)
    {
        // 清除现有数据
        await context.Database.ExecuteSqlRawAsync("DELETE FROM Orders");
        await context.Database.ExecuteSqlRawAsync("DELETE FROM Customers");

        // 生成测试数据
        var customers = TestDataGenerator.CustomerFaker.Generate(100);
        await context.Customers.AddRangeAsync(customers);

        foreach (var customer in customers)
        {
            var orders = TestDataGenerator.OrderFaker(customer).Generate(5);
            await context.Orders.AddRangeAsync(orders);
        }

        await context.SaveChangesAsync();
    }
}

数据匿名化技术

技术 描述 使用场景
替换 用假数据替换 姓名、邮箱
混洗 列内重新排列 薪水、日期
掩码 部分隐藏 SSN (xxx-xx-1234)
泛化 降低精度 年龄范围、邮政编码前缀
置空 完全移除 不必要字段
令牌化 用令牌替换 交叉引用需求
哈希 单向转换 标识符

.NET 匿名化示例

public class DataAnonymizer
{
    public Customer Anonymize(Customer source)
    {
        return new Customer
        {
            Id = source.Id, // 为关系保留
            FirstName = _faker.Person.FirstName,
            LastName = _faker.Person.LastName,
            Email = $"{Guid.NewGuid():N}@test.example.com",
            Phone = MaskPhone(source.Phone),
            SSN = "xxx-xx-" + source.SSN.Substring(7, 4),
            DateOfBirth = ShiftDate(source.DateOfBirth),
            Address = new Address
            {
                Street = _faker.Address.StreetAddress(),
                City = source.Address.City, // 保留地理信息
                State = source.Address.State,
                Zip = source.Address.Zip.Substring(0, 3) + "00"
            }
        };
    }

    private string MaskPhone(string phone)
    {
        // 保留区号,掩码其余部分
        return Regex.Replace(phone, @"(\d{3})\d{3}(\d{4})", "$1-xxx-$2");
    }

    private DateTime ShiftDate(DateTime date)
    {
        // 在 ±30 天内随机平移
        return date.AddDays(_random.Next(-30, 30));
    }
}

测试数据模式

构建器模式

public class CustomerBuilder
{
    private Customer _customer = new();

    public CustomerBuilder WithName(string first, string last)
    {
        _customer.FirstName = first;
        _customer.LastName = last;
        return this;
    }

    public CustomerBuilder WithPremiumStatus()
    {
        _customer.IsPremium = true;
        _customer.PremiumSince = DateTime.Now.AddYears(-1);
        return this;
    }

    public CustomerBuilder WithOrders(int count)
    {
        _customer.Orders = TestDataGenerator.OrderFaker(_customer).Generate(count);
        return this;
    }

    public Customer Build() => _customer;
}

// 用法
var customer = new CustomerBuilder()
    .WithName("Test", "User")
    .WithPremiumStatus()
    .WithOrders(5)
    .Build();

对象母版模式

public static class TestCustomers
{
    public static Customer ValidCustomer() => new()
    {
        Id = Guid.NewGuid(),
        FirstName = "Test",
        LastName = "User",
        Email = "test@example.com",
        Status = CustomerStatus.Active
    };

    public static Customer PremiumCustomer() => new()
    {
        Id = Guid.NewGuid(),
        FirstName = "Premium",
        LastName = "User",
        Email = "premium@example.com",
        IsPremium = true,
        Status = CustomerStatus.Active
    };

    public static Customer InactiveCustomer() => new()
    {
        Id = Guid.NewGuid(),
        Status = CustomerStatus.Inactive
    };
}

集成点

输入自:

  • 数据模型 → 测试数据结构
  • 隐私要求 → 匿名化规则
  • test-strategy-planning 技能 → 数据体积需求

输出到:

  • 测试自动化 → 数据夹具
  • performance-test-planning 技能 → 负载数据
  • 环境配置 → 播种脚本