当前位置: 首页 > 后端技术 > Python

python装饰器在接口自动化测试中的应用

时间:2023-03-25 23:33:25 Python

在讲解装饰器在接口自动化测试项目中的应用之前,我们先介绍一下什么是python装饰器。说到装饰器,就不得不提到函数。坐等市民,python中的函数有几个特点。我们先来了解一下函数的一些特点。函数也是对象。在Python中,函数也是对象。您可以将函数分配给变量,例如:deffunc(message):print("Printamessage:{}".format(message))send_message=funcsend_message("123")我们将函数func分配给变量send_message,这样你调用send_message之后,就相当于调用函数func(),把函数作为参数function可以作为参数传递给另一个函数,例如:deffunc(message):print("打印一条消息:{}".format(message))defcall_func(func,message):func(message)函数的嵌套函数的嵌套就是在函数中定义另外一个函数,例如:defcall_func(message):deffunc(message):print("printamessage:{}".format(message))returnfunc(message)上面call_func内部定义了一个函数func,在call_func中调用了这个内部函数。调用后作为call_func的返回值返回的函数的返回值也可以是函数对象。让我们修改上面的例子。如下:defcall_func():deffunc(message):print("Printamessage:{}".format(message))returnfuncresult=call_func()result("helloworld")函数call_func的返回值()是函数对象func本身,之后我们将其赋值给变量result,然后调用result('helloworld'),最后输出'printamessage:helloworld'。简单装饰器defmy_decorator(func):defwrapper():print('wrapperofdecorator')func()returnwrapperdefgreet():print('helloworld')greet=my_decorator(greet)greet()#outputwrapperofdecoratorhelloworld变量greet指向内部函数wrapper(),内部函数wrapper()会调用原函数greet()。因此,最后调用greet()时,会先打印'wrapperofdecorator',然后输出'helloworld'。这里的函数my_decorator()是一个装饰器,把真正需要执行的函数greet()包装起来,改变了它的行为,但是原来的函数greet()保持不变。语法糖@defmy_decorator(func):defwrapper():print('wrapperofdecorator')func()returnwrapper@my_decoratordefgreet():print('helloworld')greet()这里的@,我们调用它是语法糖,@my_decorator相当于前面的greet=my_decorator(greet)语句,只是更简洁而已。因此,如果你的程序中还有其他函数需要进行类似的装饰,只需要在它们上面加上@decorator即可,这样大大提高了函数的复用性和程序的可读性。带参数的装饰器如果原来的函数greet()需要接收参数,因为被装饰的函数是在装饰器中执行的,那么函数接收到的参数需要传递给装饰器,怎么办?很简单,给装饰器的嵌套函数加上参数就可以了,比如defmy_decorator(func):defwrapper(message):print('wrapperofdecorator')func(message)returnwrapper@my_decoratordefgreet(message):print(message)greet('helloworld')#decoratorhelloworld的输出wrapper但是一般不要一一写,麻烦,就这样写:defmy_decorator(func):defwrapper(*args,**kwargs):print('wrapperofdecorator')func(*args,**kwargs)returnwrapper装饰器也是可以接收参数的装饰器,具有更大的灵活性。它可以接受自己定义的参数,也可以给装饰器本身传递参数defrepeat(num):defmy_decorator(func):defwrapper(*args,**kwargs):foriinrange(num):print('wrapperofdecorator')func(*args,**kwargs)returnwrapperreturnmy_decorator@repeat(4)defgreet(message):print(message)greet('helloworld')装饰器类也可以用作装饰器.类装饰器主要依赖函数__call__(),每次调用类的实例时都会执行该函数。类请求:def__init__(self,func):self.func=funcself.num_calls=0def__call__(self,*args,**kwargs):self.num_calls+=1print('numofcallsis:{}'.format(self.num_calls))returnself.func(*args,**kwargs)@Requestdefexample():print("helloworld")example()#outputnumofcallsis:1helloworldexample()#outputnumofcallsis:2helloworld...该类装饰器暂不支持接收参数,后续可以在实际装饰器中支持结束参数。装饰器在接口自动化测试项目中的应用至此我们介绍了装饰器,下面我们就根据前面的理论进行实战。需求是通过装饰器实现接口的请求,可以自定义请求方式、请求根路径、公共参数、headers设置等功能。classRequest:def__init__(self,url='',method='get'):''''''self.url=url#请求路径self.method=method#请求方法self.func_return=None#装饰的装饰器标记的方法的返回参数self.func_im_self=None#装饰器标记的方法类的实例self.session=None#当前使用的会话对象def__call__(self,func):self.func=funcself.is_class=Falsetry:ifinspect.getfullargspec(self.func).args[0]=='self':self.is_class=TrueexceptIndexError:passdeffun_wrapper(*args,**kwargs):#调用修饰标记的方法,该方法会返回请求接口需要的返回值self.func_return=self.func(*args,**kwargs)or{}self.func_im_self=args[0]ifself.is_classelseobjectself.create_url()self.create_session()self.session.headers.update(getattr(self.func_im_self,'headers',{}))self.decorator_args.update(getattr(self.func_im_self,'common_params',{}))self.decorator_args.update(self.func_return)returnRequest(self.method,self.url,self.session)returnfun_wrapperdefcreate_url(self):"""生成http请求的url,并与路径拼接接口路由"""base_url=getattr(self.func_im_self,'base_url','')self.url=self.func_return.pop('url',None)orself.urlself.url=''.join([base_url,self.当使用url])时,需要定义一个类,比如如下:classAdvertService:def__init__(self):self.common_params={}#定义接口请求的公共参数self.headers={}#定义请求头self.base_url=self._config.AD_ADMIN_ROOT_URL@Request(url="/v3/advert/create",method='post')def_create_ad(self,advert:Advert):returndict(json=advert)上面的header会自动生成在添加的session的header中,还会在参数中添加common_params,base_url和装饰器中传入的url拼接成一个完整的url来请求接口上面实战的具体代码,当然,这只是一部分,不是完整的,我会在后面尝试写系列文章,从整体上介绍这个接口自动化测试项目。欢迎大家多多关注和交流!欢迎到我的博客看看,还有更多实测内容!!