接口测试 聊一聊接口自动化测试框架需要具备什么功能

sen · 2018年01月15日 · 最后由 黄多多 回复于 2018年07月27日 · 2162 次阅读

当你准备使用一个接口自动化测试框架或者自造轮子的时候,或许你需要先了解下一个接口自动化测试框架必须具备什么功能。

1、校验

这个很好了解,如果没有校验,单纯的执行接口的话,那就谈不上测试了。所以支持对返回值校验是一个必须的功能。

2、数据隔离

数据隔离就是指具体的请求接口、参数、校验等数据做到与代码相隔离,便于维护,一旦需要调整接口用例、新增接口用例时可很快速的找到位置,隔离的另一个好处就是可复用,框架可以推广给其他团队,使用者可以使用相同的代码,只需要根据要求填写各自用例即可测试起来。

3、数据传递

做到数据隔离可维护后,数据传递是另外一个更重要的需求。
数据传递是指接口用例之间可以做到向下传参,例如我们通过创建订单接口创建一个订单,该接口会返回一个订单号,接下来我们要进行调用查询订单的接口,从返回的数据中与创建订单用例中的数据进行校验,此时第二个接口的请求数据是需要从第一个接口用例中的返回中提取的。这样的例子比比皆是,所以支持数据传递是又一个必不可少的功能。

4、动态函数

实际用例场景中我们可能会有随机生成一个手机号、字符串加密等需求,在数据与代码隔离之后,此时我们就需要代码可以支持做到识别对应关键字时可以执行对应的函数进行填充。例如在数据中填写 phone() 时,具体执行时会被替换成 137XXXXXXXX,填写 random(5) 时,会被替换成一个五位的随机数。等等。

5、可配置

有时,我们的需求是用例不单单只能在一个环境上执行,可能需要同一份接口用例可以在 QA、预发、线上等多个环境都可以执行。所以框架需要做到可配置,便于切换,调用不同的配置文件可以在不同的环境执行。

6、日志

日志包含执行的具体执行接口、请求方式、请求参数、返回值、校验接口、请求时间、耗时等关键信息,日志的好处一来是可以便于在新增用例有问题时快速定位出哪里填写有问题,二来是发现 bug 时方便向开发反馈提供数据,开发可以从触发时间以及参数等信息快速定位到问题所在。

7、可视化报告

用例执行后,就是到了向团队展示结果的时候了,一个可视化的报告可以便于团队成员了解到每次自动化接口用例执行的成功数、失败数等数据。

你觉得呢?一起来讨论讨论。

共收到 9 条回复 时间 点赞

我能想到的。。大概是
1.用例的驱动模式,涉及到怎么存放测试数据,怎么描述用例,又如何复用;
2.考虑到效率的话还要支持并发;
3.当然测试报告不能光记录成功和失败,还有用例执行耗时,接口调用耗时,、场景的通过率等各项数值的统计。

sen #3 · 2018年01月15日 Author
杨腾 回复

1,用例是否能复用应该跟用例的设计有关系,跟框架关系不是很大。

2,并发的话在接口自动化方面倒不是必须的,当然有是更完美的。

3,报告确实是越强大越好,有老板关心的数据,有开发关心的数据是最好不过了。

多线程,模拟多设备

集成性… 往往通用但是每个方面不是那么优秀的东西成为了人们最后的选择。Simple 几乎是人类的本能

那么 基本满足这些需求的框架有哪些?eolinker?doclever?postman?swagger?luckyframe?jmeter?soapui?自研的?大家说说看咯

—— 来自 TesterHome 官方 安卓客户端

数据库和缓存的读写操作

我们的接口自动化是使用的 Rest-Assured,跟服务端接口的交互方法是根据接口定义好的,这个层面的东西是很少去改动的,如下为登录接口的封装:

/**
 * @Description: 登录
 */
public Response login(String mobile, String password, String mac){
    TestStep ts = new TestStep();

    Map<String, Object> params = new HashMap<>();
    Map<String, Object> sign = new HashMap<>();

    params.put("mobile", mobile);
    params.put("password", password);
    params.put("mac", mac);

    sign.put("sign", OldJHJUtils.getJWTSigner(params));

    ts.setType(GlobalVar.HttpType.POST);
    ts.setPath(Path.LOGIN.getValue());
    ts.setParams(sign);

    logger.info(Path.LOGIN.toString());
    return hu.sendHttpRequest(ts);
}

而具体到某个接口的测试用例上,我们没有使用大家普遍讨论的数据驱动什么的,平时怎么测试就怎么在测试用例中写测试点罢了。所以,为了增加自动化的数据稳定性,我们加了数据库和缓存的读写操作,这样对于测试数据的维护就不需要太多,如下为两个登录接口的测试用例(测试用例中包含多个测试点):

/**
 * @Description: 登录接口测试
 */
@Test
public void testLogin() throws Exception {
    MemberPo memberPo = memberPoMapper.selectMemberByMobile(mobile);

    // 登录成功
    res = oldJHJUser.login(mobile, memberPo.getLoginPasswd(), mac);

    // 验证登录密码是否设置,密码为空则未设置密码
    // 验证用户是否禁用,getIsDisable()==1则用户被禁用
    res.then().body(
            "data.mobile", equalTo(mobile),
            "data.existPassord", equalTo(!memberPo.getLoginPasswd().isEmpty()),
            "data.isDisable", equalTo(memberPo.getIsDisable()==1));


    // 登录失败-密码错误
    res = oldJHJUser.login(mobile, memberPo.getLoginPasswd()+"123", mac);
    res.then().body("msg", equalTo("密码错误"));


    // 登录失败-未注册用户登录
    res = oldJHJUser.login(noRegisterMobile, "password", mac);
    res.then().body("msg", equalTo("用户不存在"));
}
/**
 * @Description: 验证码登录接口测试
 */
@Test
public void testLoginByCode() throws Exception {
    MemberPo memberPo = memberPoMapper.selectMemberByMobile(mobile);

    // 向Redis中插入验证码
    jhjRedisService.setSecurityCode(SmsModeEnum.LOGIN_VERIFY_CODE.getValue(), mobile);
    String code = jhjRedisService.getSecurityCode(SmsModeEnum.LOGIN_VERIFY_CODE.getValue(), mobile);


    // 用户未注册
    res = oldJHJUser.loginByCode(noRegisterMobile, code, mac);
    res.then().body("msg", equalTo("用户不存在"));


    // 验证码错误
    res = oldJHJUser.loginByCode(mobile, "000000", mac);
    res.then().body("msg", equalTo("短信验证码不正确"));


    // 验证码正确
    res = oldJHJUser.loginByCode(mobile, code, mac);
    // 验证登录密码是否设置,密码为空则未设置密码
    // 验证用户是否禁用,getIsDisable()==1则用户被禁用
    res.then().body(
            "data.mobile", equalTo(mobile),
            "data.existPassord", equalTo(!memberPo.getLoginPasswd().isEmpty()),
            "data.isDisable", equalTo(memberPo.getIsDisable()==1));

    // 验证码过期
    jhjRedisService.deleteSecurityCode(SmsModeEnum.LOGIN_VERIFY_CODE.getValue(), mobile);
    res = oldJHJUser.loginByCode(mobile, code, mac);
    res.then().body("msg", equalTo("短信验证码已过期"));
}

doclever 无代码模式,UI 界面编写测试用例

王华林 回复

跟我们目前的做法一致,自动化的参数和返回结果的校验都是动态的,这样减少了用例的维护成本,只是在前期写的过程中可能会比较耗时

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册