集成测试的实践与思考

2023-11-30 12:25:09 浏览数 (2)

前面的文章聊过测试过程效率提升和演变,也分享了我对于单元测试的一些实践和思考。这篇文章接着上篇单元测试的内容,聊聊集成测试的特点,要解决什么问题,以及实践的注意事项。

下图是软件从需求出现到最后的线上发布,大致要经历的几个阶段。

狭义上的测试活动开展,指的是研发提测到线上发布中间的这一阶段。在该阶段,按照测试范围、测试目的和测试手段的不同,通常分为四个小阶段,即:集成测试(接口测试&执行用例)、系统测试(业务链路测试&组合场景测试)、回归测试(全业务链路测试)、验收测试(产品业务方介入,评估是否符合需求要求和预期)。

其中,集成测试的主要目的是验证单一业务模块的数据交互逻辑和功能实现符合预期

集成测试要解决什么问题

问题:假设你所在的企业是电商业务,系统是微服务架构,你负责订单相关功能的质量保障工作,此时本次迭代订单相关需求已经提测,你该如何开展测试?

首先我们要明白的是,微服务架构下,每个服务甚至每个请求之间的调用关系是及其复杂的,且之间的交互和依赖关系,可能是一次请求,要和上下游依赖之间产生多次调用。下面是一个创建订单接口的代码demo:

代码语言:javascript复制
from flask import Flask, request, jsonify

app = Flask(__name__)

# 假设这些函数已经实现了调用用户、库存和优惠券接口的逻辑
def get_user_info(user_id):
    pass

def get_product_info(product_id):
    pass

def apply_coupon(coupon_code, price):
    pass

@app.route('/api/orders', methods=['POST'])
def create_order():
    data = request.get_json()
    user_id = data['user_id']
    product_id = data['product_id']
    coupon_code = data.get('coupon_code', None)

    # 获取用户和产品信息
    user_info = get_user_info(user_id)
    product_info = get_product_info(product_id)

    # 计算订单价格
    price = product_info['price']

    # 如果使用了优惠券,则应用优惠
    if coupon_code:
        discount = apply_coupon(coupon_code, price)
    else:
        discount = 0

    # 创建订单
    order_id = create_order_in_database(user_id, product_id, price, discount, coupon_code)

    # 返回订单信息
    return jsonify({
        "order_id": order_id,
        "user_id": user_id,
        "product_id": product_id,
        "price": price,
        "discount": discount,
        "coupon_code": coupon_code
    })

def create_order_in_database(user_id, product_id, price, discount, coupon_code):
    # 在这里实现将订单信息存储到数据库的逻辑
    pass

if __name__ == '__main__':
    app.run()

其中,创建订单时首先要获取用户信息进行验签,其次获取商品信息和库存数据,接着要计算价格(如果包含优惠券信息还要调用优惠券服务),最后将订单相关数据写入数据库,然后返回对应的response body,这个下单功能才算完整实现了。

你会发现你只负责订单模块,但在开展测试时要考虑到上游依赖(用户)和下游调用(商品/库存/优惠券/数据库)各自是否可用才能开展测试。当然,假设上游依赖和下游调用暂时不可用,你可以通过mock的方式来继续测试,但这样的话你仅仅能保证自己的实现没有问题,但不代表整体没有问题。

集成测试的目的,是要保证自己负责的单元模块/服务和上下游依赖调用模块/服务之间交互结果是否符合预期,为了保证不同模块和服务之间的依赖调用正常进行,在设计阶段就应该考虑到交互部分的统一约定,即多方达成一种契约关系。

这种契约关系主要包括数据库的字段设计、应用和数据库之间是直接连接还是通过DAL组件的连接池统一提供服务,以及不同接口之间请求响应的Key和Value约定,是否加解密以及采用的算法等。

集成测试要解决的问题,就是验证契约关系是否符合预期,以及在契约关系之上的业务需求实现是否如要求所实现

接口测试只是验证契约实现的手段,这种手段并不是唯一(比如技术方案设计阶段测试参与评审并且评估是否合理)。

集成测试的实践注意事项

现在回到上面的问题,此时该如何开展测试呢?下面是一些实践经验和注意事项:

  • 测试计划:最好有集成测试方案,不一定要写详细的文档,但最好是形成一种流程规范;
  • 测试方法:除了接口测试,还应该考虑到异常场景、故障注入以及性能测试(基准性能摸底);
  • 测试数据:上下游依赖调用和可能的mock所需数据,以及数据库中的铺底数据(用户/商品/库存/优惠券);
  • 测试用例:除了正向场景,还应该考虑逆向场景(退款/取消订单)、数据边界(商品限购/优惠券仅可使用一张);
  • 安全验证:比如未登录、未授权场景和跨域权限(普通用户享受VIP会员的折扣);
  • 持续集成:将接口测试纳入CICD流水线中,确保每次变更后都能及时得到验证;

以上观点和实践注意事项仅供参考,在测试执行中,建议根据具体情况制定方案,采用合理的方法进行验证。

0 人点赞