You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何构建Selenium集中式数据存储以复用测试用例数据

嘿,我来帮你搞定Selenium测试用例间的集中式数据存储与复用问题!作为常年跟自动化测试打交道的人,这事儿我太熟了——集中存储能彻底摆脱每个用例硬编码数据的麻烦,还能让用例间共享动态生成的数据(比如登录token、订单号)。下面是我实战验证过的方案,一步步来:

一、选对集中式数据存储方案

根据你的测试规模和场景,选合适的存储类型:

1. 文件型存储(适合小型项目)

最容易上手的方案,用JSON/YAML/CSV这类结构化文件就行,无需额外服务。

  • 搭建步骤:在项目根目录创建一个专门的test_data文件夹,里面放static_data.json(存固定数据:测试账号、基础配置)和dynamic_data.json(存用例生成的临时数据)。
  • 复用示例:
    先写个数据管理工具类统一读写:
    import json
    import os
    
    class FileDataManager:
        def __init__(self, static_path="test_data/static_data.json", dynamic_path="test_data/dynamic_data.json"):
            self.static_path = static_path
            self.dynamic_path = dynamic_path
            # 确保文件存在
            self._init_files()
    
        def _init_files(self):
            for path in [self.static_path, self.dynamic_path]:
                if not os.path.exists(path):
                    with open(path, 'w') as f:
                        json.dump({}, f)
    
        def get_static(self, key):
            with open(self.static_path, 'r') as f:
                return json.load(f).get(key)
    
        def set_dynamic(self, key, value):
            with open(self.dynamic_path, 'r') as f:
                dynamic_data = json.load(f)
            dynamic_data[key] = value
            with open(self.dynamic_path, 'w') as f:
                json.dump(dynamic_data, f, indent=2)
    
        def get_dynamic(self, key):
            with open(self.dynamic_path, 'r') as f:
                return json.load(f).get(key)
    
    然后在Selenium用例里调用:
    from selenium import webdriver
    from data_manager import FileDataManager
    
    def test_login_and_save_token():
        dm = FileDataManager()
        driver = webdriver.Chrome()
        driver.get("https://your-test-site.com/login")
        
        # 读取静态测试账号
        username = dm.get_static("test_username")
        password = dm.get_static("test_password")
        
        driver.find_element("id", "username").send_keys(username)
        driver.find_element("id", "password").send_keys(password)
        driver.find_element("id", "login-btn").click()
        
        # 提取登录token并存入动态存储
        auth_token = driver.get_cookie("auth_token")["value"]
        dm.set_dynamic("auth_token", auth_token)
        
        driver.quit()
    
    def test_use_token_to_create_order():
        dm = FileDataManager()
        driver = webdriver.Chrome()
        driver.get("https://your-test-site.com/order")
        
        # 读取之前存储的token,跳过登录
        auth_token = dm.get_dynamic("auth_token")
        driver.add_cookie({"name": "auth_token", "value": auth_token})
        driver.refresh()
        
        # 执行下单操作
        driver.find_element("id", "create-order").click()
        order_id = driver.find_element("id", "order-number").text
        dm.set_dynamic("latest_order_id", order_id)
        
        driver.quit()
    

2. 数据库存储(适合中型项目)

如果测试用例多、并发执行,文件存储可能出现读写冲突,用轻量数据库比如SQLite(无需额外服务)或者MySQL更稳妥。

  • 搭建步骤:创建一个test_data数据库,建两张表:static_data(key, value)和dynamic_data(key, value, expire_time)。
  • 复用示例:用Python的sqlite3模块封装操作类,核心逻辑和文件型类似,只是把读写换成数据库的增删改查。比如:
    import sqlite3
    from datetime import datetime, timedelta
    
    class DBDataManager:
        def __init__(self, db_path="test_data.db"):
            self.conn = sqlite3.connect(db_path)
            self._create_tables()
    
        def _create_tables(self):
            cursor = self.conn.cursor()
            # 静态数据表
            cursor.execute("""
                CREATE TABLE IF NOT EXISTS static_data (
                    key TEXT PRIMARY KEY,
                    value TEXT NOT NULL
                )
            """)
            # 动态数据表(带过期时间,自动清理)
            cursor.execute("""
                CREATE TABLE IF NOT EXISTS dynamic_data (
                    key TEXT PRIMARY KEY,
                    value TEXT NOT NULL,
                    expire_time DATETIME
                )
            """)
            self.conn.commit()
    
        def get_static(self, key):
            cursor = self.conn.cursor()
            cursor.execute("SELECT value FROM static_data WHERE key = ?", (key,))
            result = cursor.fetchone()
            return result[0] if result else None
    
        def set_dynamic(self, key, value, expire_hours=24):
            expire_time = datetime.now() + timedelta(hours=expire_hours)
            cursor = self.conn.cursor()
            cursor.execute("""
                REPLACE INTO dynamic_data (key, value, expire_time)
                VALUES (?, ?, ?)
            """, (key, value, expire_time))
            self.conn.commit()
    
        def get_dynamic(self, key):
            cursor = self.conn.cursor()
            cursor.execute("""
                SELECT value FROM dynamic_data 
                WHERE key = ? AND expire_time > ?
            """, (key, datetime.now()))
            result = cursor.fetchone()
            return result[0] if result else None
    

3. 缓存存储(适合大型/分布式测试)

如果是多机器分布式执行测试,或者需要超快速读写动态数据,用Redis这类缓存服务最合适,还能设置数据过期时间自动清理。

  • 搭建步骤:本地或服务器部署Redis,然后用redis-py库连接。
  • 复用示例:
    import redis
    
    class RedisDataManager:
        def __init__(self, host="localhost", port=6379, db=0):
            self.r = redis.Redis(host=host, port=port, db=db, decode_responses=True)
    
        def get_static(self, key):
            return self.r.get(f"static:{key}")
    
        def set_static(self, key, value):
            self.r.set(f"static:{key}", value)
    
        def set_dynamic(self, key, value, expire_hours=24):
            self.r.set(f"dynamic:{key}", value, ex=3600*expire_hours)
    
        def get_dynamic(self, key):
            return self.r.get(f"dynamic:{key}")
    
二、数据复用的核心逻辑与最佳实践

光有存储还不够,还要注意这些细节,避免踩坑:

  • 分层存储:把静态数据(固定账号、配置)和动态数据(临时token、订单号)严格分开,避免混淆和误修改。
  • 数据隔离:如果是多测试套件并行,给动态数据加前缀,比如suite1:auth_token、suite2:auth_token,防止数据互相覆盖。
  • 自动清理:测试结束后清理动态数据,比如用测试框架的teardown方法删除Redis的key,或者清空JSON的dynamic字段,避免影响下一次测试。
  • 封装工具类:所有数据操作都通过统一的工具类完成,不要在每个用例里写重复的读写代码,后期维护改一处就行。
  • 敏感数据加密:如果存储密码这类敏感信息,要加密后存储,读取时解密,比如用cryptography库的AES加密。
三、总结
  • 小型项目:优先用JSON/YAML,上手快、零成本。
  • 中型项目:选SQLite,稳定无冲突,适合多用例执行。
  • 大型/分布式项目:用Redis,支持多机器共享,读写速度快。

这些方案我在不同规模的项目里都用过,根据你的实际情况选就行,有问题随时问!

内容的提问来源于stack exchange,提问作者the_code

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:30:58