Skip to content

第38讲:接口测试框架

必备能力

今天我们开始进入接口测试框架的学习,首先看下一个基本的测试框架应该具备什么能力:

  • 项目管理能力,需要管理项目中的组件,比如关键的依赖,语言自身的环境等;
  • 用例编写与管理能力,可以使用一些成熟的测试框架,来编写和维护 case;
  • 领域测试能力,需要完成具体领域里(App、Web、HTTP,以及硬件)的测试;
  • 执行调度能力,可以使用一些工具(Pytest、PyCharm、Shell、Jenkins)对测试用例进行调度或执行。
  • 生成报告,最后还需要生成一个非常好的测试报告,比如使用 allure2。

想要完成对 HTTP 的测试,首先要完成接口测试,常见的接口测试有模拟 HTTP 的各种请求方法(get、post、put、delete、head 等);还有请求体的构造,比如 form 表单、JSON 与 XML 数据、还包括 binary 文件上传等;最后是响应结果,比如状态码,头消息、响应体,以及深层的数据结构来进行数据的提取。

综上所提到的能力,我为大家推荐目前行业里知名度最高的http请求框架 requests,requests 可以非常完备地进行 HTTP 的接口测试,它对 HTTP、HTTPS 的支持非常全面,使用也非常简单,不需要关心底层的细节,系统已经做了很好的封装,同时它的定制性也非常强,可以提供各种进阶功能,帮你完成一些通用的流程处理,接下来我们看下这个框架应该如何使用。

首先,我们来看下 requests 给我们提供了哪些常见方法,requests 库通过 requests 类给我们提供了测试 HTTP 的常见的 get、post、put、delete、head 方法,我们接下来做一个演练。

实战演练

这里为你提供了一个测试用的网站叫 http://httpbin.testing.studio.com,你可以打开这个网址了解演练环境,并且可以用它做一个入门级的练习, 我们打开网址看下。

打开之后你可以看到它是在我们自己学院服务器上搭建的测试环境,在这个演练环境里你可以看到它底层提供的一些 API,借助这些 API 你可以完成基础的 put、get 等请求的测试。

有了演练环境以后,我们从零开始创建一个项目,首先我们使用原有的 PyCharm 去创建一个项目。

然后在项目里添加一个叫作 requests 的依赖

添加完依赖之后,我们尝试使用官方提供的 API,来编写第一个接口测试用例,我们首先创建一个 test_http 的项目,接下来在项目内创建一个叫作 test_http 的测试用例。接下来发起一个最简单的请求,代码如下

返回的内容是一个 JSON 的结构体,我们简单的打印并断言内容。执行后,测试用例通过。

接下来我们了解它到底怎么去发送各种各样的请求,从而完成对目标接口的测试。

首先发送的 URL 可以通过下面这个办法找到目标网址:

通过 requests 里面的方法对它发起各种各样的请求,方法名是http请求方法,第一个参数是 URL 地址。

常见的请求有这样两大类型,一个是 get 请求的时候,我们发送的一些动态化内容会通过 get 请求附带出去。 以 get 请求为例,常见的附带请求类型有路径参数和 query 参数,其中最常见的是 query 参数。

那么第 2 大类是 post 请求类,当我们发起一个 post 请求时,也可以带一些常见请求,比如 form 表单。当登录一个网站输入用户名和密码时,其实就是一个典型的 post 请求。还有一种是结构化请求,比如我发送 Json.xml 这个结构体给服务端,有的时候还需要用到文件上传,这是一种二进制的格式。

刚才我们已经简单发了一个请求,但是还没有带具体的 query 参数,现在我们可以试着去追加一个参数。以 Get Query 为例,你可以看到它有一个 params,你可以给它一个词典,它会把词典内的格式拼装成 query 格式, query 格式是 URL 地址问号后面的变化内容,它是一个 k/v 结构,中间由一个&符号连接起来的请求体。

我们把路径复制出来,在 URL 后面输入一个get,其中 a 等于 1,b 等于 2,执行之后发现就可以发送出去了。

如果想要模拟这样的一个请求,发送一个 a 等于 1,b 等于 2 的变化内容给 r,我应该怎么做呢?我们可以在 URL 后面加一个 params,在里面你可以直接写对应结构的词典。

这时我们再发起一次请求,这是一个带参数的 get 请求,我们看一下它访问的内容,访问内容打印首先有个args参数,它帮你解析出了 HTTP 框架带的query参数,当发现里面有个 a=1,b=2 的参数就会帮你打印到这个地方。你发送的请求其实就是这种 a=1,b=2 的格式。

那如果是中文怎么办?其实也是一样的,比如说我们称之为霍格沃兹学院,然后再次发送一次请求,打印看一下。中文其实会被进行 URL 编码,那么编码完成后就可以发出去,这个时候服务器其实已经收到你的 unicode 编码,

接下来我们再看第 2 种 post,通常适用于一些登录场景,比如需要完成某一个页面的登录,或提交一次发帖的请求,这时它其实是以 post 发送。post的form表单请求 跟 get 很像,它们发送格式都是一种 k/v 结构,但 post 发送的时候是放在请求的 body 字段里面,在请求头之后,把你的内容附加到尾部。

接下来我们看怎么去发送一些 post,回到演练环境,我们再来看一下 form 表单。form 表单下面是 form 结构,form 结构里有一些各种各样的输入,比如电话号码,我们随便写一个,然后点击 Submit order,这时你可以点开浏览器然后点击发送。

点击 network,发现它其实发起了一次 post 请求。你可以点开 view source 查看 post 请求体原始内容,如果你没填内容,它就为空。

当我们要完成 post 请求的时候,可以编写一个新的叫作 test_post 的 case,可以使用 requests.post发送post请求。post 里面要填的第一个参数是 URL,接下来要填写请求的内容,可以使用一个 data参数,在里面写上你的数据。在这个例子中请求后会有一个响应内容,你可以在 Response 里看到这样一个结构体,它会告诉你 form 表单里提交的内容

除了标准的请求体,其他的header、cookie、以及文件上传,也都可以通过对应的参数来构造。

响应内容

我们刚才其实已经用到了响应内容,它有什么区别呢?首先 r.text 用的是比较多的, r.text 其实是 r.content +r.encoding,如果说系统知道这是个 utf8 编码,就会自动进行解码,解码之后的内容都会存到 r.text,通常我们会使用 r.text 来表示最后解析出来的内容。

除此之外,如果说返回的内容里面有一个 JSON 结构体,其实你也可以使用 r.json 方法,来读取最原始的和最真实的对象。通过这个办法,就可以对结果做调研了。

我们来看一个案例,比如发起一个 post 请求,返还的内容其实是一个 JSON,因为有 JSON,我们可以通过 .json 方法返回一个 JSON 对象,接下来就可以使用词典的方法,直接读取。

我们回到这个例子,看一下怎么去编写。仍然以 get 为例,你可以看到当我发起请求时,系统会自动帮我们打印一个 text,这个 text 里面有一个 form 内容,字段等于 15600534706,剩下的是 URL。

我们可以利用这个办法,去加一个断言,使用 r.json,它就会取出来里面的 JSON 对象,对 JSON 对象的具体结构进行访问。我们可以使用类似词典的方法,使用 k 去访问它,比如要判断 URL 是否等于我们上面用到的 URL,接下来令 r.json 里 form 的 cusstel 等于我们的手机号码。

通过编写 post 方法,我们已经完成了第 2 个测试用例。有了这些基础之后,再往后你就可以进行更深一步的探索。比如对jsonpath、json schema、数据模板等技术的使用。