📝 面试求职: 「面试试题小程序」 ,内容涵盖 测试基础、Linux操作系统、MySQL数据库、Web功能测试、接口测试、APPium移动端测试、Python知识、Selenium自动化测试相关、性能测试、性能测试、计算机网络知识、Jmeter、HR面试,命中率杠杠的。(大家刷起来…)

📝 职场经验干货:

软件测试工程师简历上如何编写个人信息(一周8个面试)

软件测试工程师简历上如何编写专业技能(一周8个面试)

软件测试工程师简历上如何编写项目经验(一周8个面试)

软件测试工程师简历上如何编写个人荣誉(一周8个面试)

软件测试行情分享(这些都不了解就别贸然冲了.)

软件测试面试重点,搞清楚这些轻松拿到年薪30W+

软件测试面试刷题小程序免费使用(永久使用)


在接口自动化测试中,你是否遇到过这样的问题?

测试用例第一次运行通过,第二次却失败

多人并行执行时,彼此的数据相互干扰

某个测试创建了用户 A,另一个测试也创建同名用户导致冲突

数据库中残留大量“僵尸数据”,影响后续测试和统计

这些问题的根源,就是测试脏数据。

所谓脏数据,是指测试过程中未被清理的中间状态数据,它们会破坏测试的独立性、可重复性和稳定性。如果不能有效管理,自动化测试将逐渐失去可信度。

本文将介绍如何使用 Python + Pytest + 数据库操作,实现测试前后的自动化数据清理与还原机制,确保每次执行都在干净、可控的环境中进行。‍

为什么脏数据会导致自动化失败?

这些情况都会导致测试结果不稳定,出现“偶发失败”或“环境依赖”问题,严重影响 CI/CD 流水线的可靠性。‍

核心原则:每个测试应独立且可重复

一个高质量的自动化测试,必须满足:

独立性:不依赖其他测试的执行结果

可重复性:无论执行多少次,结果一致

环境纯净:测试开始前无残留数据,结束后不留垃圾

要实现这一点,关键在于建立完整的数据生命周期管理机制:

测试前:清理历史数据 → 准备前置数据  

测试中:执行用例  

测试后:清理本次生成的数据‍

方案一:基于数据库的数据清理(推荐)

适用于直接操作数据库的场景,效率高,控制力强。

第一步:定义数据清理策略

根据业务表结构,制定清理规则。例如:

# cleanup_rules.py
CLEANUP_RULES = {
    'users': {
        'table': 'users',
        'condition': "username LIKE 'auto_%' OR phone LIKE '17%'",
        'ttl_days': 1  # 超过1天的数据清理
    },
    'orders': {
        'table': 'orders',
        'condition': "order_no LIKE 'ORD%' AND created_at < NOW() - INTERVAL 1 DAY"
    },
    'user_profiles': {
        'table': 'user_profiles',
        'condition': "user_id IN (SELECT id FROM users WHERE username LIKE 'auto_%')"
    }
}

第二步:实现通用清理类​​​​​​​

# data_cleaner.py
import pymysql
from config import DB_CONFIG
from cleanup_rules import CLEANUP_RULES
class DataCleaner:
    def __init__(self):
        self.connection = None
    def connect(self):
        try:
            self.connection = pymysql.connect(**DB_CONFIG)
        except Exception as e:
            raise RuntimeError(f"数据库连接失败: {e}")
    def clean_table(self, table, condition):
        """清理指定表中符合条件的数据"""
        if not self.connection:
            self.connect()
        with self.connection.cursor() as cursor:
            delete_sql = f"DELETE FROM {table} WHERE {condition}"
            try:
                cursor.execute(delete_sql)
                self.connection.commit()
                print(f"已清理 {cursor.rowcount} 条 {table} 表数据")
            except Exception as e:
                self.connection.rollback()
                print(f"清理失败 {table}: {e}")
    def clean_all(self):
        """执行所有预设的清理规则"""
        for name, rule in CLEANUP_RULES.items():
            self.clean_table(rule['table'], rule['condition'])
    def close(self):
        if self.connection:
            self.connection.close()

方案二:基于测试标记的数据追踪与还原

适用于需要精确控制“本次测试产生的数据”的场景。

使用 Pytest Fixture 追踪数据​​​​​​​

# conftest.py
import pytest
from data_generator import TestDataGenerator
from data_cleaner import DataCleaner
@pytest.fixture(scope="session")
def cleaner():
    """全局清理器"""
    c = DataCleaner()
    c.connect()
    yield c
    c.close()
@pytest.fixture(scope="function")
def db_cleaner(cleaner):
    """函数级清理,在每个测试前后执行"""
    # 测试前:清理可能冲突的旧数据
    cleaner.clean_table("users", "username LIKE 'test_user_%'")
    yield cleaner
    # 测试后:清理本次测试产生的数据
    cleaner.clean_table("users", "username LIKE 'test_user_%'")
@pytest.fixture(scope="function")
def test_user(db_cleaner):
    """生成测试用户,并自动清理"""
    generator = TestDataGenerator()
    user_data = generator.generate_user(prefix="test_user_")
    # 假设有一个方法插入用户
    user_id = insert_user_to_db(user_data)
    yield user_data  # 提供给测试用例
    # 测试结束后自动清理(也可由 db_cleaner 统一处理)
    # delete_user_by_id(user_id)

方案三:事务回滚(适用于支持事务的数据库)

对于 MySQL(InnoDB)、PostgreSQL 等支持事务的数据库,可以在测试中使用事务包裹,测试结束自动回滚。​​​​​​​

@pytest.fixture(scope="function")
def transactional_session():
    conn = pymysql.connect(**DB_CONFIG)
    cursor = conn.cursor()
    # 开启事务
    cursor.execute("START TRANSACTION")
    try:
        yield conn
    finally:
        # 回滚事务,不提交任何更改
        conn.rollback()
        conn.close()
# 测试用例
def test_create_order(transactional_session):
    # 所有数据库操作都在事务中
    create_order(...)
    result = query_order_status(...)
    assert result == "created"
    # 函数结束,事务回滚,数据不会写入数据库

注意:此方案仅适用于纯数据库操作测试,不适用于验证接口对真实数据的影响。‍

高级实践:数据快照与还原

对于复杂业务场景,可实现“数据快照”机制:

测试前备份关键表或记录

测试结束后恢复备份数据​​​​​​​

def create_snapshot(table, condition):
    """创建数据快照"""
    cursor.execute(f"SELECT * FROM {table} WHERE {condition}")
    return cursor.fetchall()
def restore_from_snapshot(table, data, primary_key='id'):
    """从快照恢复数据"""
    for row in data:
        placeholders = ', '.join(['%s'] * len(row))
        columns = ', '.join(row.keys())
        sql = f"REPLACE INTO {table} ({columns}) VALUES ({placeholders})"
        cursor.execute(sql, list(row.values()))

适用于配置表、基础数据等不常变动但影响广泛的场景。‍

与持续集成(CI)集成

在 Jenkins、GitHub Actions 等 CI 环境中,建议在流水线中加入数据清理步骤:

# GitHub Actions 示例

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - name: 清理测试数据
        run: python scripts/clean_data.py --env=test
      - name: 执行测试
        run: pytest tests/
      - name: 清理本次测试数据
        run: python scripts/clean_data.py --env=test

确保每次构建都基于干净环境,避免历史数据污染。‍

最佳实践总结

结语

脏数据是接口自动化测试的“隐形杀手”。它不会立刻暴露问题,但会逐步侵蚀测试的稳定性和可信度。

通过建立系统化的数据清理与还原机制,我们可以:

提升测试的独立性和可重复性

减少偶发失败,提高 CI/CD 流水线稳定性

降低维护成本,让自动化真正发挥价值

从今天开始,把“数据清理”作为自动化测试的标准环节,告别脏数据困扰,打造健壮、可靠的测试体系。‍

最后: 下方这份完整的软件测试视频教程已经整理上传完成,需要的朋友们可以自行领取【保证100%免费】

​​

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐