当前位置: 首页 > news >正文

自动化测试框架设计

📌 自动化测试框架设计

该框架基于 pytest,支持 Web + API 自动化测试,采用 关键字驱动,支持 远程执行、多机调度、失败重试、数据驱动(CSV),并结合 allure 生成可视化测试报告。


📂 目录结构

automation_framework/  
│── config/                        # 配置文件存放目录
│   ├── settings.ini               # 全局配置(浏览器、API、环境等)
│   ├── remote_hosts.ini           # 远程执行机列表
│
│── tests/                         # 测试用例目录
│   ├── web/                       # Web 相关测试
│   │   ├── test_login.py          # Web登录测试
│   ├── api/                       # API 相关测试
│   │   ├── test_api.py            # API测试示例
│   ├── conftest.py                # pytest 配置
│
│── core/                          # 关键字封装
│   ├── web_keywords.py            # Web自动化关键字库
│   ├── api_keywords.py            # API自动化关键字库
│
│── utils/                         # 工具类
│   ├── logger.py                  # 日志封装
│   ├── remote_executor.py         # 远程执行
│   ├── screenshot.py              # 截图工具
│   ├── csv_parser.py              # CSV数据驱动解析
│
│── reports/                       # 测试报告存放目录
│
│── logs/                          # 日志存放目录
│
│── requirements.txt               # 依赖包
│── run_tests.py                   # 运行测试主入口
│── pytest.ini                     # pytest 配置
│── README.md                      # 说明文档

📌 1. 依赖管理

requirements.txt

 
pytest
pytest-rerunfailures
pytest-xdist
selenium
requests
allure-pytest
paramiko
pandas


📌 2. 配置文件

config/settings.ini

 
[WEB]
browser = chrome
base_url = http://example.com
headless = false
implicit_wait = 5

[API]
base_url = http://example.com/api
timeout = 10

config/remote_hosts.ini

[executor_1]
host = 192.168.1.101
username = user
password = pass

[executor_2]
host = 192.168.1.102
username = user
password = pass

📌 3. Web 关键字封装

core/web_keywords.py

from selenium import webdriver
from selenium.webdriver.common.by import By
import configparser
import allure

class WebKeywords:
    def __init__(self):
        """初始化浏览器驱动"""
        config = configparser.ConfigParser()
        config.read("config/settings.ini")

        options = webdriver.ChromeOptions()
        if config.getboolean("WEB", "headless"):
            options.add_argument("--headless")

        self.driver = webdriver.Chrome(options=options)
        self.driver.implicitly_wait(config.getint("WEB", "implicit_wait"))

    def open_url(self, url):
        """打开指定URL"""
        self.driver.get(url)

    def find_element(self, locator):
        """查找元素"""
        return self.driver.find_element(By.XPATH, locator)

    def click(self, locator):
        """点击元素"""
        self.find_element(locator).click()

    def send_keys(self, locator, text):
        """输入文本"""
        self.find_element(locator).send_keys(text)

    def take_screenshot(self, name):
        """截图并附加到Allure报告"""
        path = f"reports/screenshots/{name}.png"
        self.driver.save_screenshot(path)
        allure.attach.file(path, name="screenshot", attachment_type=allure.attachment_type.PNG)

    def close(self):
        """关闭浏览器"""
        self.driver.quit()

📌 4. API 关键字封装

core/api_keywords.py

import requests
import configparser

class APIKeywords:
    def __init__(self):
        """初始化API测试类"""
        config = configparser.ConfigParser()
        config.read("config/settings.ini")
        self.base_url = config["API"]["base_url"]
        self.timeout = config.getint("API", "timeout")

    def get(self, endpoint, params=None, headers=None):
        """发送GET请求"""
        return requests.get(f"{self.base_url}{endpoint}", params=params, headers=headers, timeout=self.timeout)

    def post(self, endpoint, data=None, json=None, headers=None):
        """发送POST请求"""
        return requests.post(f"{self.base_url}{endpoint}", data=data, json=json, headers=headers, timeout=self.timeout)


📌 5. conftest.py 配置

 
import pytest
import allure
from core.web_keywords import WebKeywords
from core.api_keywords import APIKeywords

@pytest.fixture(scope="session")
def web():
    """Web自动化前后置"""
    web = WebKeywords()
    yield web
    web.close()

@pytest.fixture(scope="session")
def api():
    """API自动化前后置"""
    return APIKeywords()

@pytest.hookimpl(tryfirst=True, hookwrapper=True)
def pytest_runtest_makereport(item):
    """失败截图"""
    outcome = yield
    report = outcome.get_result()
    if report.when == "call" and report.failed:
        web_fixture = item.funcargs.get("web", None)
        if web_fixture:
            web_fixture.take_screenshot(item.name)


📌 6. CSV 数据驱动

utils/csv_parser.py

import pandas as pd

def parse_csv(file_path):
    """解析CSV文件"""
    return pd.read_csv(file_path).to_dict(orient="records")

CSV 用例格式

 
test_name,username,password,expected
valid_login,user1,pass123,success
invalid_login,user1,wrongpass,failure


📌 7. Web 测试用例

tests/web/test_login.py

 
import allure
import pytest
from utils.csv_parser import parse_csv

data = parse_csv("data/login_cases.csv")

@allure.feature("Login Page")
@pytest.mark.parametrize("test_name,username,password,expected", data)
def test_login(web, test_name, username, password, expected):
    web.open_url("http://example.com/login")
    web.send_keys("//input[@id='username']", username)
    web.send_keys("//input[@id='password']", password)
    web.click("//button[@id='login']")
    
    assert expected in web.driver.page_source


📌 8. API 测试用例

tests/api/test_api.py

 
import allure

@allure.feature("API Test")
def test_get_api(api):
    response = api.get("/users")
    assert response.status_code == 200

@allure.feature("API Test")
def test_post_api(api):
    response = api.post("/login", json={"username": "test", "password": "test123"})
    assert response.status_code == 200


📌 9. 远程执行

utils/remote_executor.py

import paramiko
import configparser

class RemoteExecutor:
    def __init__(self):
        self.config = configparser.ConfigParser()
        self.config.read("config/remote_hosts.ini")

    def run_remote_tests(self):
        for section in self.config.sections():
            ssh = paramiko.SSHClient()
            ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            ssh.connect(self.config[section]["host"], username=self.config[section]["username"], password=self.config[section]["password"])
            stdin, stdout, stderr = ssh.exec_command("pytest --alluredir=reports/allure-results")
            print(stdout.read().decode())
            ssh.close()


📌 10. 运行测试

 
# 本地执行
pytest --alluredir=reports/allure-results --reruns 2

# 远程执行
python utils/remote_executor.py

# 生成 Allure 报告
allure generate reports/allure-results -o reports/html-reports --clean
allure open reports/html-reports


这样,你就有了 Web + API 关键字驱动自动化框架,支持 失败重试、数据驱动、远程执行! 🚀

相关文章:

  • Unity 优化封装常用API和编辑器扩展工具包
  • Redis的过期策略及其优缺点
  • FPGA之硬件设计笔记-持续更新中
  • python-leetcode-颜色分类
  • 安全模块设计:token服务、校验注解(开启token校验、开启签名校验、允许处理API日志)、获取当前用户信息的辅助类
  • 模拟进程通过系统调用向缓冲区写入并刷新的过程
  • k8s之pod的调度之污点与容忍污点,什么是污点? 如何容忍污点
  • 校园二手交易微信小程序的设计与实现(论文源码调试讲解)
  • 在鸿蒙HarmonyOS手机上安装hap应用
  • 深度学习基础--ResNet50V2网络的讲解,ResNet50V2的复现(pytorch)以及用复现的ResNet50做鸟类图像分类
  • 【北京迅为】iTOP-RK3568OpenHarmony系统南向驱动开发-第1章 GPIO基础知识
  • 线程概述以及Java中线程的三种创建方式(继承Thread类、实现Runnable接口、实现Callable接口)
  • 鸿蒙 ArkUI 实现 2048 小游戏
  • 网络安全 越权分为几种
  • Centos7源码编译安装Sqlite最新版本
  • 算法-二叉树篇14-从中序与后序遍历序列构造二叉树
  • 深度解析 ANSI X9.31 TR-31:金融行业密钥管理核心标准20250228
  • 如何有效判断与排查Java GC问题
  • Spring 源码硬核解析系列专题(十):Spring Data JPA 的 ORM 源码解析
  • 【Spring】AOP
  • 牛商网建站/软件外包公司是什么意思
  • 网站推广都做什么内容/ui设计培训班哪家好
  • 国示建设网站/赣州seo
  • 网站建设相关技术/班级优化大师网页版登录
  • VPS做镜像网站/在线看seo网站
  • 全国建筑人才求职招聘网站/企业邮箱