接口自动化

接口自动化

  • 背景:

如果通过手工测试人员进行手动测试,不仅会浪费大量的人力、物力、资源等信息,而且对产品的测试程度相对来说比较低。因此,测试用例的自动化,即接口自动化(俗称:冒烟测试)显得尤为重要。

  • 什么是接口自动化?

接口自动化,其基本原理就是:模拟前端向后台发送http请求,得到响应的请求数据,对数据进行分析,从而判断接口是否正常。

 

  • 目前所做的接口自动化的解决方案的总结概述:

整体使用python框架实现,最底层对post、get、put、delete等请求做了一层封装;对传入的参数和返回的参数做了一层处理;最上层编写测试用例,逻辑实现不需要关心请求是怎样发送过去的。这样进行三层结构的封装,使得测试用例和接口实现最大化的解耦,不必因开发接口的改动而大量修改测试用例。

  • 主要使用的技术:

  1. pytest 框架
  2. allure 报告生成库
  3. 断言库 except
  4. 超时重试库 tenacity
  • pytest的主要特性 —— fixture:

依赖注入的思想

fixture  scope:提供了多级缓存,每级缓存对应着不同的有效领域 。[ session,  moudle,  class,  function ]即:

  1. session 对全局生效,即该 fixture 每次执行测试只会运行一次,用来生成全局的资源。(例如:添加集群或可用区等)
  2. moudle 对模块生效,每个模块执行一次
  3. class 对类生效,每个类执行一次
  4. function 对方法生效,每个用例执行一次
  • 代码层次结构:

  1. 项目C - (主要功能:构造一个请求,将该请求发送到后台接口,并将响应的数据返回。通常情况下,我们不会修改其中的方法,除非开发修改了接口。该项目是和开发的接口一一对应的,承载了所有系统暴露出的接口。是与开发代码之间的唯一接口)
  2. 项目B - (因为项目D的功能很单一,仅仅是实现发送请求和接收数据,因此在项目C中需要做很多的数据处理、超时重试、案例步骤关联等操作机制,这样做的目的是:使得测试用例开发起来相对来说比较简单,公共的方法都抽取出来,便于维护)
  3. 项目A - 这个一个测试用例的实现模块,这里还细分为测试用例和配置层。测试用例都写在 xxx_test 文件中,包含用例的各个步骤;此外还有一类文件叫conftest,一些公共的fixture写在里面。
  4. 项目D - 是一个公用的工具库,一些对系统后台的操作和对数据库的操作工具都在这里面。该项目D是独立的,不依赖于其他的工程。同时,它可以供其他多个工程使用,如果没有满足的工具,可以自己添加到项目D里面。
  • 以小见大:

  1. 写用例首先要将用例的前置条件执行过程期望结果写到注释中;allure会根据注释直接在页面中生成报告,方便用例和错误的查找。同时在写用例的过程中也省去了来回切换,查看用例的过程,提高了工作的效率。
  2. 拿到一个用例之后进行分析,分解出一个个步骤,这里的步骤正对应着allure.step,写的过程结构清晰,可读性好,而且报告中也会根据step来生成。
  3. 有的时候多个用例会用到同一个方法,这种情况我们最好把公用的写到fixture中,fixture功能是非常强大的,这样可以大大节省了时间,提高效率。

番外——api代码常见问题总结【注意事项】:

  • 可调试性
  1. 日志或者调试信息不清晰,无法告知问题原因;
  2. 该记录日志的地方不记录日志,或者有日志但不打印异常,出问题不好查;
  3. 断言不添加描述信息,不利于查问题和后期维护
  • 维护性
  1. 函数参数、返回值无类型描述;
  2. 或者类型描述不具体,没多少意义,例如:字典的类型描述应该要说明key和value的类型;
  3. 易调整的、有测试需要的常量应该要提取为运行参数,例如:像外部配置的路径应该要作为运行参数,以方便打桩测试或者环境迁移;
  4. 函数抽象与重用,例如:有时候需要某个接口里的一部分功能或者逻辑,有些人会倾向于把代码拷贝过来改改,这样久了就会有很多相似的代码。一般比较好的做法应该是把旧接口进行抽象,或者从旧接口里提取功能子集做为新接口
  • 协程
  1. 网络IO需要协程化,避免阻塞主线程;
  2. 磁盘IO需要协程化,避免阻塞主线程;
  3. 内部用多线程、多进程实现的协程接口,要通过锁或者信号量限制并发
  • 异常
  1. 异常考虑缺失 [json.dumps接口会抛出TypeError异常;json.loads接口会抛出JSONDecodeError异常];
  2. 异常捕获范围太粗,容易掩盖问题;异常导致的资源泄露
  • 其他
  1. 异常分支要考虑好对全局的影响,必要时要填充默认值来防止错误扩散;
  2. 对变量为None的可能没判断好就直接使用;内部实现暴露给用户

ps:感谢过程中小伙伴的指导,如果从菜鸟到老鸟是一段必经之路,我希望能够一直刻骨铭心。

原文地址:https://www.cnblogs.com/sunshine-blog/p/9601301.html