接口测试 python 代码优化,反射。

徐旻 · February 20, 2017 · Last by 大桥 replied at May 02, 2017 · 1477 hits

本人今天学到一个知识点,作为一个给菜鸟的科普,老鸟们不要见笑。

#coding=utf-8
import requests
import json

class op_request(object):
    def __init__(self, request, request_body):
        self.request_url = request["host"] + request["url"]
        self.method = request["method"]
        self.protocol = request["protocol"]
        self.headers = request["headers"]
        self.request_body = request_body

    def send_request(self):
        if self.method == "post" and self.protocol == "http":
            re_dict = self.http_request_post()
        return re_dict

    def http_request_post(self):
        url = self.request_url
        request_body = self.request_body
        headers = self.headers
        session = requests.session()
        session.headers.update(headers)
        response = session.post(url, request_body)
        data = json.loads(response.content)
        re_dict ={}
        re_dict["data"] = data
        re_dict["status_code"] = response.status_code
        return re_dict

这个是一个封装了 request 操作的模块。当初始化好 op_request 这个类以后,我们去执行 send_request 拿到一个返回值。
一开始我在这里做了一个判断,当请求方法是 post,请求协议是 http 的时候,那么执行 http_request_post 这个函数(基于 http 的 post 请求。)
那么以后要增加模块的时候,很简单的就会写成。
if self.method == "post" and self.protocol == "https":
re_dict = self.https_request_post()
然后在下面写一个 def https_request_post(self)的方法。

如果有 10 种请求方法,我就会很呆萌的写 10 个 if。
其实关于反射这个概念,我 1 个月以前就听说过,一直没有静下心来看,在写代码的时候虽然知道可以用反射做,不过为了快点交货,就先用这套代码应付下。
现在有时间了,就仔细看了下反射。发现,好东西很多,学不完的。

根据我自己的理解反射机制就是把你的函数名当做你的函数来调用。

#coding=utf-8
import requests
import json


class op_request(object):

    def __init__(self, request, request_body):
        self.request_url = request["host"] + request["url"]
        self.method = request["method"]
        self.protocol = request["protocol"]
        self.headers = request["headers"]
        self.request_body = request_body

    def send_request(self):
        func_name = self.protocol + "_" + self.method
        try:
            func = getattr(op_request, func_name)
            re_dict = func(self)
        except Exception,e:
            print " no func_name"
        return re_dict

    def http_post(self):
        url = self.request_url
        request_body = self.request_body
        headers = self.headers

        session = requests.session()
        session.headers.update(headers)
        response = session.post(url, request_body)
        data = json.loads(response.content)
        re_dict ={}
        re_dict["data"] = data
        re_dict["status_code"] = response.status_code

        return re_dict

还是关注 send_request()
这里我把初始化类的时候拿到协议和方法进行了一次拼接:func_name = self.protocol + "_" + self.method
然后用我拼接出来的函数名去定义一个方法,func = getattr(op_request, func_name)
然后执行这个方法:re_dict = func(self)
仔细的分解
self.protocol = http
self.method = post
那么 func_name 就是 http_post
然后让程序去找 http_post 这个方法,如果存在就调用它。

本来要写不知道多少个的 if 判断,现在只要用这几行代码就搞定了了。
马上让代码有点高大上的感觉有没有。
难怪很多地方都需要开发转测试,这种对他们来说可能就是基本功。

关于 getattr 的用法我现在就想到这个,和他一起的还有 hasattr,delattr,setattr。有新区的同学可以自己去用一下。

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 6 条回复 时间 点赞
匿名 #1 · February 22, 2017

同样 10 个 if 的飘过😂 😂 😂 尝试用下~

这段代码里,你根本不需要用到getattr
request.post(url, *args, **kwargs)实际是在requests.request(method, url, *args, **kwargs)上再封装了一层

#2 楼 @jacexh 十分感谢~! 又涨知识了。

基础的东西,多分享哈,加油↖(ω)↗

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

啥反射,这里用继承就好。一个父类定义 send_request 方法,在子类里分别实现不同协议的 send,用的时候直接多态。

用 eval 似乎也可以达到楼主的目的,但这个函数是不安全的,要慎重哈

需要 Sign In 后方可回复, 如果你还没有账号请点击这里 Sign Up