微服务契约测试框架Pact-Python实战

Pact是一个契约测试框架,有多种语言实现,本文以基于pact-python探究契约测试到底是什么?以及如何实现

官网:自述文件 |契约文档 (pact.io)

契约测试步骤

1、为消费者写一个单元测试,让它通过,并生成契约文件。

2、在生产者服务执行该契约文件,验证测试是否通过。

 安装pact-Python

官方介绍的是直接使用pip下载,但是国内下载有问题。

下载方法参考:契约测试第一步--pact-python安装_51CTO博客_pact 契约测试

下载安装包:

https://pypi.org/project/pact-python/0.19.0/#modal-close

 点击下载后手动解压:

入主目录,与setup.py同级,进入命令行执行:

python setup.py build      

python setup.py install

 消费者测试

新建项目,创建contract_miku.py文件

 代码

# -*- coding: utf-8 -*-
"""
@author dongfangbubai
@date 2023年07月27日 18:08:14
@packageName 
@className contract_miku
@describe 模拟消费者去请求真实的生产者
"""
import atexit
import unittest
# from query import get_cartoon_characters
import requests

from pact import Consumer,Provider
#构造pact对象,定义消费者服务的名字并给他绑定一个生产者服务
pact = Consumer('consumer').has_pact_with(Provider('provider'))
pact.start_service()#start mock service
# # #注册推出的时候关闭pact服务
atexit.register(pact.stop_service)

class GetMikuInfoContract(unittest.TestCase):
    def test_miku(self):

        #定义期望的结果
        expected={
            "salary":20000,
            "name":"miku",
            "national":"Chinese",
            "contract":{
                "Email":"dongfangbubai@163.com",
                "Phone":"13265523433"
            }

        }
        #定义expected响应头
        headers={
            "Content-Type":"application/json"
        }
        #定义预期请求以及响应的方式(consumer will request in this way and expected to get the repsponed from the procide)
        (
            pact
                .upon_receiving("a request for UserA")#请求的名字
                .with_request(
                method="GET",
                path='/information',
                query={"name":"miku"}) #期望的请求方法,请求url
                .will_respond_with(200,headers, expected)#期望请求的返回
        )
        #定义消费者服务向模拟生产者发生请求,并获得响应
        #the url and port is the mockservice not real provider 
        with pact:#定义pact
            result=requests.get('http://127.0.0.1:1234/information',{"name":"miku"})
            print(result)
            print(result.headers)
            print(result.json())
        #做最后的断言
        self.assertEqual(result.json(),expected)
if __name__ == '__main__':
    unittest.main()

可以看到首先构造一个pact,并使用pact启动mock服务。

在具体的测试类和方法中采用了unittest测试框架,采用什么测试框架可以根据所使用的语言,这里也可以用pytest。js语言就可以用mocha框架。

在test_miku函数中定义了expected,headers,在pact中定义消费者预期的请求方式和响应结果。后续会根据这些生成契约。

在with pact里定义向mock服务的请求,最后断言请求的结果与预期是否一致。

需要注意的是,with pact里的url是pact带的mock服务对应的1234端口,而不是真实的服务,也不能填写真实服务。

运行结果

使用python方式运行contract_miku.py

在窗口输出了一些关于ruby编码的提示,对结果好像没有影响。

在result.json的打印中可以看到打印的内容与我们的expected内容一致。

测试用例为通过状态。其实消费者端的单元测试代码无论expected怎么写,测试用例都是通过的,因为我们的目的就是写一个单元测试让测试用例通过。

契约文件

代码运行后,会生成consumer-provider.json文件,这就是契约文件。

契约文件里定义了consumer,provider的名称,和交互。

交互包括request,response,请求body。

契约文件就是消费者的需求,而生产者应该满足这些需求。

 生产者测试

这里采用flask框架生成了一个接口

api_server.py

# -*- coding: utf-8 -*-
"""
@author 
@date 2023年07月28日 09:31:25
@packageName 
@className api_server
@describe TODO
"""
import json

from flask import Flask, request, jsonify

app = Flask(__name__)

rsp_body=[{
            "salary":20000,
            "name":"miku",
            "national":"Chinese",
            "contract":{
                "Email":"dongfangbubai@163.com",
                "Phone":"13265523433"
            }

        }]
@app.route('/information')
def test():
    get_name=request.args.get("name","").lower()
    print(get_name)
    if get_name=='miku':
        rsp=jsonify(rsp_body[0])
    elif get_name=='nanpha':
        rsp = jsonify(rsp_body[1])
    else:
        rsp=jsonify({'status':'404 not found'})
    return rsp


if __name__ == '__main__':
    app.run(host='0.0.0.0',port=8080)

运行api_server.py,使用postman请求接口

 测试生产者服务只需要在命令行执行

pact-verifier --provider-base-url=http://localhost:8080 --pact-url=consumer-provider.json

 这里指定了生产者服务的url和契约文件即消费者测试生成的文件

运行结果显示没有失败,说明执行成功。

可以看到生产者服务返回的状态码,响应体和响应头都与契约文件匹配,所以验证成功。

契约测试与接口测试和集成测试的区别

 

 

 参考

【软件测试课程中——微服务架构测试中的契约测试。】 https://www.bilibili.com/video/BV1Qf4y1F76L/?p=4&share_source=copy_web&vd_source=1aab39b433529f6f488e61847b342350

<think>好的,用户想了解测试开发由浅入深的学习路线以及思维方式。首先,我需要明确测试开发的核心内容,可能包括测试理论、自动化测试、持续集成、编程能力等。用户可能是刚入门的新手,或者有一定测试经验想转测试开发的人,需要分阶段引导。 先从基础开始,测试理论是必须的,比如测试类型、流程、用例设计方法。然后需要掌握至少一门编程语言,Python或Java比较常见。接着是自动化测试框架,比如Selenium、Appium,还有接口测试工具Postman。 接下来是进阶部分,持续集成/持续部署(CI/CD)工具如Jenkins,容器化技术Docker,以及性能测试工具JMeter。高级阶段可能涉及测试平台开发、质量体系建设、代码覆盖率等。 思维方式方面,用户可能需要培养分层测试、质量左移、数据驱动、风险意识等。另外,实战项目经验很重要,可以推荐一些实战项目比如搭建自动化测试框架,参与开源项目等。 需要确保内容结构清晰,分阶段讲解,每个阶段的关键点和工具都要提到。同时,避免使用过于专业的术语,保持口语化,让用户容易理解。还要考虑用户可能希望了解如何从手动测试过渡到自动化,或者如何提升技术深度,所以需要涵盖不同层次的知识点。最后,提醒学习方法和资源,比如系统学习、动手实践、参与社区等。</think>以下是测试开发(Test Development)由浅入深的学习路线和思维方式的系统性介绍,结合技术深度和行业实践,帮助你逐步成长为一名优秀的测试开发工程师。 --- ### **一、学习路线(由浅入深)** #### **1. 初级阶段:测试基础与编程入门** - **测试理论基础** - 掌握软件测试基本概念(黑盒/白盒测试、功能/性能测试等)。 - 理解测试流程(需求分析→测试计划→用例设计→执行→缺陷管理→报告)。 - 学习测试用例设计方法(等价类、边界值、因果图、场景法等)。 - **编程基础** - 掌握一门脚本语言:**Python**(推荐,语法简单生态丰富)或 **Java**(适合企业级开发)。 - 关键学习点:变量、循环、条件判断、函数、文件操作、异常处理。 - **工具入门** - 接口测试工具:Postman、Swagger。 - 自动化测试框架:Selenium(Web UI自动化)、Appium(移动端自动化)。 #### **2. 中级阶段:自动化与持续集成** - **自动化测试进阶** - 掌握主流测试框架- **Web端**:Selenium + Pytest/TestNG(用例管理)。 - **接口测试**:Requests库(Python) + Postman/Newman(自动化执行)。 - **移动端**:Appium + Android/iOS真机/模拟器调试。 - 学习数据驱动(DDT)、关键字驱动(KDT)等设计模式。 - **持续集成(CI/CD)** - 工具链:Jenkins(流水线搭建)、Git(版本控制)、Docker(环境容器化)。 - 实现自动化测试与CI/CD的集成(如定时执行、代码提交触发测试)。 - **性能测试入门** - 工具:JMeter(接口压测)、Locust(分布式性能测试)。 - 核心指标:TPS、响应时间、错误率、资源利用率。 #### **3. 高级阶段:架构设计与质量体系** - **测试平台开发** - 开发内部测试工具:用例管理平台、Mock服务、自动化调度系统。 - 技术栈:前端(Vue/React) + 后端(Django/Flask/SpringBoot) + 数据库(MySQL/MongoDB)。 - **质量左移与右移** - **左移**:参与需求评审、代码静态分析(SonarQube)、单元测试(JUnit/Pytest)。 - **右移**:线上监控(Prometheus + Grafana)、日志分析(ELK)、A/B测试。 - 工具:Jacoco(Java)、Coverage.py(Python)。 - 结合覆盖率数据优化测试用例,识别冗余测试。 #### **4. 专家阶段:全链路质量保障** - **质量效能提升** - 建立质量度量体系(缺陷密度、逃逸率、自动化覆盖率等)。 - 探索AI在测试中的应用:用例自动生成、图像识别测试(CV)、智能断言。 - **云原生与分布式测试** - 云环境测试:AWS/GCP/Aliyun的云服务集成。 - 微服务架构下的测试策略:契约测试(Pact)、服务虚拟化(WireMock)。 - **团队管理与技术规划** - 制定团队技术路线,平衡短期需求与长期技术沉淀。 --- ### **二、测试开发的思维方式** #### **1. 分层测试思维** - 金字塔模型:底层(单元测试)→中层(接口测试)→顶层(UI测试),减少UI自动化比重,提高测试效率。 #### **2. 工程化思维** - 将测试活动视为工程问题,关注可维护性(代码复用、框架设计)、可扩展性(插件化架构)和效率(并行执行、分布式测试)。 #### **3. 数据驱动思维** - 测试结果依赖数据,需关注: - 测试数据生成(随机数据、脱敏生产数据)。 - 测试结果分析(失败日志归类、根因定位)。 #### **4. 风险导向思维** - 优先覆盖核心业务场景和高风险模块(如支付、订单)。 - 通过风险评估(如FMEA)制定测试策略。 #### **5. 用户场景思维** - 从用户行为反推测试场景(如用户高频操作路径、异常操作边界)。 --- ### **三、实战建议** 1. **项目驱动学习** - 从实际需求出发,例如:用Selenium实现一个电商网站的登录流程自动化。 2. **参与开源项目** - 贡献代码或提交Bug到GitHub上的测试框架(如Pytest、Appium)。 3. **持续输出总结** - 通过技术博客(如掘金、优快云)或内部文档沉淀经验。 --- ### **四、推荐学习资源** - **书籍**:《Google软件测试之道》《测试架构师修炼之道》《持续交付》 - **在线课程**:极客时间《测试开发入门与实战》、Coursera软件测试专项课程。 - **社区**:TesterHome、Stack Overflow、GitHub测试相关仓库。 --- 通过以上学习路线和思维方式的训练,你可以逐步从功能测试转向测试开发,最终成为能主导质量体系建设的资深工程师。**核心逻辑**:技术深度(自动化/工具开发) + 质量广度(全链路质量保障) + 工程思维(效率与ROI)三者结合。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值