Rest请求客户端

329 阅读4分钟
原文链接: zhuanlan.zhihu.com


本文是测试进阶社群的 python 接口测试项目实战部分的第四节,完整教程请加入社群后查看。


首先,我们需要写一个 rest 请求的客户端,我命名为 RestClient。

这个类用于收发我们将要用到的http 请求。


那么为什么要设计这样一个类?

假如我们不用这个类,收发请求一般是直接用 requests 来做。


例1. requests 收发请求的示例:

response = requests.post("http://httpbin.org/post",data={"a":"b"})
print(response,text)

但是这样发送的请求之间没有关联,当我们需要做一些连续调用的请求,比如“先登录再把商品加入购物车“,这样的时候,需要使用 requests 的 session 功能。伪代码示例如下:

例2. requests session 收发请求的伪代码示例:

session = requests.session()

#注意这个是伪代码,不能运行。这一行表示登录
response = session.post("http://xxxxxx/login",data={"username":"aaa","password":"bbb"})
print(response,text)

#这一行表示将商品加入购物车
response = session.post("http://xxxxxx/cart",data={"xxx":"aaa"})
print(response,text)


这里,由于登录和登录后的请求都由同一个reqeusts session对象来发出,两个请求里带了同样的header 信息,包括里面的 cookie 信息。因此可以模拟用户在浏览器上先登录再xxx的操作。


那么是不是使用 session 就足够了呢?

一般来说是够用了,但是我们可以再进一步优化一下,加入这个功能:

给一个网站加一个默认的 URL 地址前缀。


比如我们的测试都是对 http://github.com 这个网站来做的,那么脚本按例2的写法,我们每个请求里都要写一遍完整的 url,"http://github.com/login","http://github.com/xxxxx",这使代码显得有些冗余。因此我们可以建一个类,自动给 所有url 加上前缀。


例3. 增加了URL前缀功能的Rest Client类:

import requests,json


class RestClient():
    def __init__(self,api_root_url):
        self.api_root_url=api_root_url
        self.session = requests.session()

    def get(self,url, **kwargs):
        return self.request(url,"get",**kwargs)

    def post(self,url,data=None,json=None,**kwargs):
        return self.request(url, "post",data,json,**kwargs)

    def options(self, url, **kwargs):
        return self.request(url, "potions", **kwargs)

    def head(self, url, **kwargs):
        return self.request(url, "head", **kwargs)

    def put(self, url, data=None, **kwargs):
        return self.request(url, "put", data,**kwargs)

    def patch(self, url, data=None, **kwargs):
        return self.request(url, "patch", data,**kwargs)

    def delete(self, url, **kwargs):
        return self.request(url, "delete", **kwargs)

    def request(self,url,method_name,data=None,json=None,**kwargs):
        url = self.api_root_url+url
        if method_name == "get":
            return self.session.get(url, **kwargs)
        if method_name == "post":
            return self.session.post(url, data, json, **kwargs)
        if method_name == "options":
            return self.session.options(url, **kwargs)
        if method_name == "head":
            return self.session.head(self, url, **kwargs)
        if method_name == "put":
            return self.session.put(self, url, data, **kwargs)
        if method_name == "patch":
            return self.session.patch(self, url, data, **kwargs)
        if method_name == "delete":
            return self.session.delete(self, url, **kwargs)


这里,这个类里我加了一些方法,包括:

1.init 方法:初始化这个类,初始化的时候需要输入 api_root_url,也就是URL的前缀。另外还在初始化时创建了 self.session 用于保存 requests 的 session。

2.get,post等各种 http方法,用于让用户使用。但这里并没有真正实现这些方法,因为这些方法都是在 requests 里有实现过,我们只要把参数传给 requests 就行了。这个传递我们写在request方法里,所以这里的http方法都是调用requests方法。

3. request 方法:真正调用 self.session 的各种方法,这里同样是把参数传下去,只是在传之前,给所有用户输入的url加了一个前缀。前缀的值是用户在 init 方法里输入的。



例4.运行例3的类的代码:

r=RestClient("http://httpbin.org")
x= r.post("/post",json= {"a":"b"})
print(x.text)


这个例子介绍了怎样使用例3的 RestClient 向 http://httpbin.org/post 这个URL post 一个 json 对象 {"a":"b"},并打印了其返回值。所以我们看到了,一旦RestClient这个类被实例化之后,我们发请求不需要再输入完整的url,这将使未来的测试脚本代码得到重大的简化。


任务1.

通过网络搜索,了解 RestClient类里出现的各种 http方法的含义及区别。包括,get,post, options,head,put,patch,delete这些。


任务2.

仿照例4,写一段脚本,使用RestClient向http://github.com的首页发送的 get 请求。


本小节代码地址:

https://github.com/TestUpCommunity/TUGithubAPI/tree/teach_001



本文首发于测试进阶知识星球,

完整的接口测试教程正在我的知识星球火热更新中,

扫码即可加入。费用为128元/年。

关于项目实战的介绍:张挺:测试进阶社群项目实战启动