如何实现基于场景的接口自动化测试用例?

🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快

自动化本身是为了提高工作效率,不论选择何种框架,何种开发语言,我们最终想实现的效果,就是让大家用最少的代码,最小的投入,完成自动化测试的工作。

基于这个想法,我们的接口自动化测试思路如下:

1.不变的内容全部通过配置化来实现,比如:脚本执行的环境、请求的 HOST、URL 路径、测试数据等;

2.环境和数据关联变更:依据不同的环境,选择不同的配置及对应的测试数据;

3.抽取公共方法,避免冗余代码

4.场景化的用例,实现可配置化;

5.数据驱动。

一、问题

在做自动化的过程中,不能只考虑单接口的脚本,也要考虑场景化的用例。场景化的用例 不需要每个步骤都去校验所有的数据,可能 更多看重串联后的最终效果。

那什么是场景用例?

其实就是多个接口组成的业务场景,常规写代码的做法是,先调用接口1,验证结果, 再调用接口2,再继续接口3,... 等等;在测试场景中,可能只是各个接口的入参不一样,或者是调用的接口不一样。这样代码写起来就会冗余。

比如:

复制代码
def test_01(self):
    # step 01
    result1 = PackDemo().getTest()
    assert result1 == 4

    # step02
    result2 = PackDemo2().getTest2("name")
    assert result2 == 'name'
    
    # step03
    result3 = DemoApi().getTest()
    assert result3 == 2

这样的用例,对于简单的接口没什么问题,但是对于复杂的接口,校验逻辑比较多,或者入参比较多,实现的方式就过于单一了。且不同场景的话,每个都要更改调用的步骤和返回值,场景越多冗余越多。

如果使用配置化的方式,每次从配置文件中动态加载配置的场景用例, 而且能够做到加载后做对应的断言,那该多好。

怎么做呢?咱们看看一些核心的实现。

二、方案

2.1 项目结构

项目结构如下:

img

采用当前比较流行的 Python + Pytest + Allure 来实现,具体结构不做展开。

2.2 场景用例的配置数据

复制代码
 test_scenario.json
{
  "test_01": {
    "step_1": {  ---- 步骤节点名称,可自定义
      "packagePath": "api", --- 这个步骤要运行的方法所属类的包路径
      "class": "DemoApi", --- 这个步骤要运行的方法所属类名称
      "method": "getTest", --- 这个步骤要运行的方法名称
      "request": null,  ---这个步骤运行的方法入参
      "response": 2, ---这个步骤运行的结果,可以是一个值,或者对象
      "verify": { --- 数据校验的节点
        "type": 1, ---数据校验的类型
        "keys": null  ---如果是校验的特定字段,这里需要输入部分校验的字段
      }
    },
    "step_2": {
      "packagePath": "api.demo",
      "class": "PackDemo",
      "method": "getTest2",
      "request": "request -> name",
      "response": 6,
      "verify": {
        "type": 1,
        "keys": null
      }
    },
    "step_3": {
      "packagePath": "api.demo",
      "class": "PackDemo2",
      "method": "getTest3",
      "request": {
        "name": "param-name",
        "num_list": ["a", "b", "c"]
      },
      "response": 8,
      "verify": {
        "type": 1,
        "keys": null
      }
    }
  }
}

2.3 动态加载类

在我们配置了以上的测试场景的数据后,我们希望在用例执行的过程中,通过获取我们的配置,能够动态的加载数据文件中提到的方法,并执行对应的方法,那这个过程的实现我们主要通过如下的动态加载类来实现。

复制代码
# DynamicLoad.py 
# 部分主要的摘录如下
 def __load_module(self):
        """
        加载对应路径下的模块
        :param package_path: 包路径
        :param class_name: 类名称
        :return:
        """
        return importlib.import_module("." + self.class_name, package=self.package_path)

def __getClassInstance(self):
    """
    加载对应的模块下的类,并返回对应类的实例 
    :param module_name: 对应的模块
    :param class_name:
    :return:
    """
    self.my_module = self.__load_module()
    self.my_class = getattr(self.my_module, self.class_name)()
    return self.my_class

def execMethod(self, method, *args):
    """
    加载对应类下的方法 
    :param instance: 对应的实例
    :param method: 要执行的方法
    :return:
    """
    result = getattr(self.__getClassInstance(), method)(*args)
    return result

有了以上动态加载的方法后,在执行场景用例时,依据上述的方法,就可以执行测试文件中提到的方法。

2.4 场景分析类

在场景用例的测试数据中,除了需要解析需要执行的类、方法外,还要解析文件中涉及到的出入参及数据比对方式,因此,这里还需要一个场景分析类,来解析数据文件中关于具体执行过程的配置。

复制代码
 #ScenariosAnalyze.py
 def analyse_exe_scenario(self, case_data):
        step_result = {}
        summary = True
        for i in case_data:
            instance = DynamicLoad(case_data[i]['packagePath'], case_data[i]['class'])
            if case_data[i]['request'] is not None:
                result = instance.execMethod(case_data[i]['method'], case_data[i]['request'])
            else:
                result = instance.execMethod(case_data[i]['method'])
            if case_data[i]['verify'] is not None:
                compare_type = case_data[i]['verify']['type']
                keys = case_data[i]['verify']['keys']
                step_compare_result = DataCompare().compare_type(compare_type=compare_type, actual=result,
                                                                 expect=case_data[i]['response'], keys=keys)
                if not step_compare_result:
                    summary = False
            step_result[i] = step_compare_result
        step_result['summary'] = summary
        return step_result

2.5 用例实现

复制代码
 @File : test_scenario.py

class TestScenario:

    @allure.story('场景用例01')
    @allure.severity(allure.severity_level.BLOCKER)
    @pytest.mark.smoke
    def test_01(self):
        result = None
        case_data = self.test_data_json['test_01']
        result = self.scenario_analyze.analyse_exe_scenario(case_data)
        assert result['summary'] is True

通过上述简单的脚本调用,就可以完成一个场景用例的测试了。

三、小结

以上就是场景用例配置化的实现思路。

它的优点是:

1.配置化: 一切固定不变的内容全部配置化,最终达到:一个环境配置文件,一套脚本,几套测试数据,依据环境的不同选择不同的测试数据执行对应的测试脚本;

2.门槛低:因为配置化,测试同学只要把测试数据文件中的关键节点配置好,然后在脚本中写下调用方法,就完成用例编写了;

3.好扩展:在后续的实现中,可以将这些配置全部页面化,包括环境、数据、脚本,达到无代码开发的目的;

缺点当然是不够灵活,所以没有完美的方案,只有合适的,以上,仅供大家参考。

最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:

​这些资料,对于做【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!凡事要趁早,特别是技术行业,一定要提升技术功底。

相关推荐
鹏码纵横2 小时前
已解决:java.lang.ClassNotFoundException: com.mysql.jdbc.Driver 异常的正确解决方法,亲测有效!!!
java·python·mysql
仙人掌_lz2 小时前
Qwen-3 微调实战:用 Python 和 Unsloth 打造专属 AI 模型
人工智能·python·ai·lora·llm·微调·qwen3
猎人everest3 小时前
快速搭建运行Django第一个应用—投票
后端·python·django
猎人everest3 小时前
Django的HelloWorld程序
开发语言·python·django
chusheng18403 小时前
2025最新版!Windows Python3 超详细安装图文教程(支持 Python3 全版本)
windows·python·python3下载·python 安装教程·python3 安装教程
别勉.3 小时前
Python Day50
开发语言·python
自由鬼4 小时前
企业架构框架深入解析:TOGAF、Zachman Framework、FEAF与Gartner EA Framework
程序人生·架构
xiaohanbao094 小时前
day54 python对抗生成网络
网络·python·深度学习·学习
爬虫程序猿4 小时前
利用 Python 爬虫按关键字搜索 1688 商品
开发语言·爬虫·python
英杰.王4 小时前
深入 Java 泛型:基础应用与实战技巧
java·windows·python