三十九、【扩展工具篇】Allpairspy 组合用例生成器:智能设计高效测试集

发布于:2025-08-02 ⋅ 阅读:(14) ⋅ 点赞:(0)

前言

假设我们有一个功能,它有 3 个参数,每个参数有 3 个取值。如果进行全组合(笛卡尔积)测试,需要 3 * 3 * 3 = 27 个测试用例。而大多数由参数组合引发的缺陷,都是由两个参数的特定组合导致的。

All-Pairs 测试的核心思想就是:用最少的测试用
例,覆盖任意两个参数的所有取值组合。

例如,对于以下参数:

  • 浏览器: Chrome, Firefox
  • 操作系统: Windows, MacOS
  • 用户状态: LoggedIn, Guest

全组合是 8 个用例,而 All-Pairs 算法只需要 4 个用例就能覆盖所有“两两组合”:
在这里插入图片描述

准备工作

  1. 前端项目就绪: test-platform/frontend 项目可以正常运行 (npm run dev)。
  2. 后端 API 运行中: Django 后端服务运行。
  3. Element Plus 集成完毕。
  4. 安装 allpairspy 库 (后端):
    在你的 Django 项目的虚拟环境中运行:
    pip install allpairspy
    
    在这里插入图片描述

第一部分:后端实现 - allpairspy API

1. 创建 allpairspy 服务

a. 创建 api/services/allpairs_generator.py 文件:
在这里插入图片描述

b. 编写 allpairs_generator.py
在这里插入图片描述

# test-platform/api/services/allpairs_generator.py
from allpairspy import AllPairs
from typing import List, Any

def generate_allpairs_cases(parameters: List[List[Any]]) -> List[List[Any]]:
    """
    使用 allpairspy 库生成组合测试用例。
    
    :param parameters: 二维列表,每个子列表是一个参数的所有取值。
                       例如: [["Chrome", "Firefox"], ["Windows", "MacOS"]]
    :return: 一个包含所有组合用例的二维列表。
    """
    if not parameters or not all(isinstance(p, list) and p for p in parameters):
        raise ValueError("输入参数必须是一个非空的二维列表,且每个子列表不能为空。")

    # AllPairs 是一个生成器,我们需要将其转换为列表
    return [list(case) for case in AllPairs(parameters)]
2. 创建 allpairspy API 视图

打开 test-platform/api/views.py,添加一个新的 APIView

# test-platform/api/views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import permissions, status as http_status
from .services.allpairs_generator import generate_allpairs_cases # 导入服务函数
import logging # 导入 logging

logger = logging.getLogger(__name__)

# ... (其他 ViewSet) ...

class AllpairsGenerateView(APIView):
    """
    Allpairspy 组合用例生成 API
    POST /api/tools/generate-allpairs/
    """
    permission_classes = [permissions.IsAuthenticated] # 只有登录用户才能使用

    def post(self, request, *args, **kwargs):
        parameters_data = request.data.get('parameters', [])
        
        if not isinstance(parameters_data, list) or not parameters_data:
            return Response({
   
   "detail": "parameters 字段必须是一个非空列表。"}, status=http_status.HTTP_400_BAD_REQUEST)
        
        headers = []
        values_list = []
        
        for param in parameters_data:
            if not isinstance(param,