前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >单元测试之setUp,全局变量,反射和数据参数化

单元测试之setUp,全局变量,反射和数据参数化

作者头像
清菡
发布2020-12-02 16:44:53
8320
发布2020-12-02 16:44:53
举报
文章被收录于专栏:清菡软件测试清菡软件测试

文章总览图

1.后面的用例需要用到第一条用例的返回结果里的某些值,怎么去处理这种依赖关系?

方法一: 第1条用例写在setUp里面,每次请求的时候,在setUp里面重新请求第一条用例。 缺点就是关联性比较强,一步错,步步错。

方法二: 全局变量 缺点就是关联性比较强,一步错,步步错。

外面的是全局变量,函数里面的是局部变量。 如果要修改全局变量的值,怎么去改? 先global声明全局变量,才能去修改局部变量的值。

方法三: 反射---不强调 这种方法更简单。

setattr(GetData,"Cookie","小白")

代码语言:javascript
复制
            #  类名     属性名   新值

可以直接把类里面的属性值做修改,进行更新。缺点就是关联性比较强,一步错,步步错。

数据参数化: 可以解决用例的关联性强,一步错,步步错的问题。

Http请求:创建实例.方法(参数)

下面操作需要先在Python里面安装requests库,pip install requests

2.代码如下

单元测试思路:第1个地址是登录的接口地址,第2个地址是登录进去后进行充值的接口地址。两个接口地址是同一个网站的。

由于清菡没有找到这样的接口,所以用的别的接口地址,学的是思路。

先创建一个http_request.py文件,调用requests库,对get和post请求成功封装。

代码语言:javascript
复制
#来自文件http_request.py

import requests
class HttpRequest:
    '''利用request封装get请求和post请求'''

    def http_request(self,url,data,method,cookie=None):
        '''url:请求的地址 http://xxx:port
               param:传递的参数  非必填参数  字典的格式传递参数
               method:请求方式支持get以及post  字符串形式的参数
               cookie:请求的时候传递的cookie值'''
        if method.lower()=='get':
            res = requests.get(url, data, cookies=cookie)
        else:
            res=requests.post(url,data,cookies=cookie)#响应结果的消息实体 http response包含响应头,响应状态码,响应正文,Cookie
        return res#返回一个消息实体
if  __name__ =='__main__':
    url = 'http://v.juhe.cn/xhzd/query'
    data = {"key": "e0dd844ff0669814b529da934a094a83", "word": '聚'}
    res=HttpRequest().http_request(url,data,'post')
    print("登录结果是:", res.json())

#充值
    recharge_url='http://v.juhe.cn/xhzd/query'
    recharge_data={"key":"e0dd844ff0669814b529da934a094a83","word":'聚'}
    recharges_res=HttpRequest().http_request(recharge_url,recharge_data,'get',res.cookies)
    print("充值结果是:",recharges_res.json())

方法一:setUp

写在setUp里面,每次请求的时候在setUp里面重新请求第一条用例。

代码语言:javascript
复制
#来自文件test_http.py

#输入错误的密码和充值为负数没有加断言,所以结果全部通过。
import unittest
from test_demo.http_request import HttpRequest

class TestHttp(unittest.TestCase):
    def setUp(self):
        #登录
        self.login_url='http://v.juhe.cn/xhzd/query'
        self.login_data={"key": "e0dd844ff0669814b529da934a094a83", "word": '聚'}
        #充值的URL
        self.recharge_url= 'http://v.juhe.cn/xhzd/query'
        #获取登录后的cookies
        self.cookies=HttpRequest().http_request(self.login_url,self.login_data,'get').cookies
        print("setUp函数里面登录后产生的cookies是:{}".format(self.cookies))

    def test_login_normal(self):#正常登录
        data={"key": "e0dd844ff0669814b529da934a094a83", "word": '聚'}
        res=HttpRequest().http_request(self.login_url,data,'get')
        try:
            self.assertEqual('返回成功',res.json()['reason'])
        except AssertionError as e:
            print("test_login_normal's error is{}".format(e))
            raise e
        print(res.json())

    def test_login_wrong_pwd(self):#输入错误的密码
        data={"key": "e0dd844ff0669814b529da934a094a83", "word": ''}
        res=HttpRequest().http_request(self.login_url,data,'get')
        print(res.json())

    def test_recharge_normal(self):#正常充值
        recharge_data = {"key": "e0dd844ff0669814b529da934a094a83", "word": '聚'}
        res=HttpRequest().http_request(self.recharge_url,recharge_data,'post',self.cookies)#加了一个cookies
        try:
            self.assertEqual('返回成功', res.json()['reason'])
        except AssertionError as e:
            print("test_recharge_normal's error is{}".format(e))
            raise e
        print(res.json())

    def test_recharge_negative(self):#充值为负数
        recharge_data = {"key": "e0dd844ff0669814b529da934a094a83", "word": ''}
        res=HttpRequest().http_request(self.recharge_url,recharge_data,'post',self.cookies)#加了一个cookies
        print(res.json())


    def tearDown(self):
        pass


写断言的时候,需要把响应结果里面的值填写进去。

代码语言:javascript
复制
#来自文件test_suite.py

#用的不是登录-充值的接口,测试的时候最好找到能登录进去并进行充值的接口。

import unittest
import HTMLTestRunner
from test_demo import test_http#模块名
suite=unittest.TestSuite()
#通过loader方式来加载用例,其它的方式也可以尝试。
loader=unittest.TestLoader()
suite.addTest(loader.loadTestsFromModule(test_http))


#执行
with open("test_summer.html",'wb')as file:
    runner=HTMLTestRunner.HTMLTestRunner(stream=file, verbosity=2,title="单元测试",description=None,tester="清菡")
    runner.run(suite)

文件夹下已创建文件http_request.py,文件test_http.py和文件test_suite.py,运行文件test_suite.py。

输出结果如下:

输入错误的密码和充值为负数没有加断言,所以结果全部通过。

输入错误的密码和充值为负数的用例中增加了断言

代码语言:javascript
复制
#来自文件test_http_Assert.py

import unittest
from test_demo.http_request import HttpRequest

class TestHttp(unittest.TestCase):
    def setUp(self):
        #登录
        self.login_url='http://v.juhe.cn/laohuangli/d'
        self.login_data={"key": "abf91475fc19f66c2f1fe567edd75257", "date": '2014-09-09'}
        #充值的URL
        self.recharge_url= 'http://v.juhe.cn/laohuangli/d'
        #获取登录后的cookies
        self.cookies=HttpRequest().http_request(self.login_url,self.login_data,'get').cookies
        print("setUp函数里面登录后产生的cookies是:{}".format(self.cookies))

    def test_login_normal(self):#正常登录
        data={"key": "abf91475fc19f66c2f1fe567edd75257", "date": '2014-09-09'}
        res=HttpRequest().http_request(self.login_url,data,'get')
        try:
            self.assertEqual('超过每日可允许请求次数!',res.json()['reason'])
        except AssertionError as e:
            print("test_login_normal's error is{}".format(e))
            raise e
        print(res.json())

    def test_login_wrong_pwd(self):#输入错误的密码
        data={"key": "abf91475fc19f66c2f1fe567edd75257", "date": ''}
        res=HttpRequest().http_request(self.login_url,data,'get')
        try:
            self.assertEqual('超过每日可允许请求次数!',res.json()['reason'])
        except AssertionError as e:
            print("test_login_wrong_pwd's error is{}".format(e))
            raise e
        print(res.json())

    def test_recharge_normal(self):#正常充值
        recharge_data = {"key": "abf91475fc19f66c2f1fe567edd75257", "date": '2014-09-09'}
        res=HttpRequest().http_request(self.recharge_url,recharge_data,'post',self.cookies)#加了一个cookies
        try:
            self.assertEqual('超过每日可允许请求次数!', res.json()['reason'])
        except AssertionError as e:
            print("test_recharge_normal's error is{}".format(e))
            raise e
        print(res.json())

    def test_recharge_negative(self):#充值为负数
        recharge_data ={"key": "abf91475fc19f66c2f1fe567edd75257", "date": ''}
        res=HttpRequest().http_request(self.recharge_url,recharge_data,'post',self.cookies)#加了一个cookies
        try:
            self.assertEqual('超过每日可允许请求次数!',res.json()['reason'])
                             #预期结果
        except AssertionError as e:
            print("test_recharge_negative's error is{}".format(e))
            raise e#注意:实际结果与预期结果不符合的情况下没加raise e 通过,加了raise e 用例才抛出错误。
    #如果实际结果和预期结果是一致的,加raise e 和不加raise e,用例都是通过的。
        print(res.json())


    def tearDown(self):
        pass

前1次代码,因为输入错误的密码和充值为负数没有加断言,所以结果全部通过。可以在上次的结果中取这块的值放进断言中,为错误的密码和充值为负数的用例中增加断言。

图片中仅供参考,根据实际的接口情况,取值。

代码语言:javascript
复制
#来自文件test_suite.py

#此接口不是登录-充值的接口

import unittest
import HTMLTestRunner
from test_demo import test_http_Assert#模块名
suite=unittest.TestSuite()
#通过loader方式来加载用例,其它的方式也可以尝试。
loader=unittest.TestLoader()
suite.addTest(loader.loadTestsFromModule(test_http_Assert))


#执行
with open("test_summer.html",'wb')as file:
    runner=HTMLTestRunner.HTMLTestRunner(stream=file, verbosity=2,title="单元测试",description=None,tester="清菡")
    runner.run(suite)

文件夹下已创建文件http_request.py,文件test_http_Assert.py和文件test_suite.py,运行文件test_suite.py。

输出结果如下:

注意:实际结果与预期结果不符合的情况下,没加raise e 通过,加了raise e 用例才抛出错误。如果实际结果和预期结果是一致的,加raise e和不加raise e,用例都是通过的。

实际结果与预期结果不符合的情况下,加了raise e 用例抛出错误。

方法二:全局变量

代码语言:javascript
复制
#文件来自quanjubianliang.py

import unittest
from test_demo.http_request import HttpRequest
COOKIE=None#全局变量

class TestHttp(unittest.TestCase):
    def setUp(self):
        #登录
        self.login_url='http://v.juhe.cn/xhzd/query'
        #充值的URL
        self.recharge_url= 'http://v.juhe.cn/xhzd/query'
        #获取登录后的cookies
        # self.cookies=Httprequest().http_request(self.login_url,self.login_data,'get').cookies
        # print("setUp函数里面登录后产生的cookies是:{}".format(self.cookies))

    def test_login_normal(self):#正常登录
        global COOKIE#声明全局变量
        data={"key":"e0dd844ff0669814b529da934a094a83","word":'聚'}
        res=HttpRequest().http_request(self.login_url,data,'get')
    #if条件语句,后面为空就是False,不为空就是True。res.cookies不为空就是有cookie,有cookie的时候再去做替换。
        if res.cookies:#如果cookie有的话,就更新COOKIE
            COOKIE=res.cookies
        try:
            self.assertEqual('超过每日可允许请求次数!',res.json()['reason'])
        except AssertionError as e:
            print("test_login_normal's error is{}".format(e))
            raise e
        print(res.json())

    def test_login_wrong_pwd(self):#输入错误的密码登录
        data={"key":"e0dd844ff0669814b529da934a094a83","word":''}
        res=HttpRequest().http_request(self.login_url,data,'get')
        try:
            self.assertEqual('超过每日可允许请求次数!',res.json()['reason'])
        except AssertionError as e:
            print("test_login_normal's error is{}".format(e))
            raise e
        print(res.json())

    def test_recharge_normal(self):#登录后正常充值
        global COOKIE#加了global才能修改它的值,局部变量要修改全局变量的值,就要声明它是个全局变量。
        recharge_data = data={"key":"e0dd844ff0669814b529da934a094a83","word":'聚'}
        res=HttpRequest().http_request(self.recharge_url,recharge_data,'post',COOKIE)#加了一个全局变量cookie
        try:
            self.assertEqual('超过每日可允许请求次数!',res.json()['reason'])
        except AssertionError as e:
            print("test_recharge_normal's error is{}".format(e))
            raise e
        print(res.json())

    def test_recharge_negative(self):#登录后充值为负数
        global COOKIE
        recharge_data =data={"key":"e0dd844ff0669814b529da934a094a83","word":''}
        res=HttpRequest().http_request(self.recharge_url,recharge_data,'post',COOKIE)#加了一个全局变量cookie
        try:
            self.assertEqual('超过每日可允许请求次数!',res.json()['reason'])
        except AssertionError as e:
            print("test_recharge_negative's error is{}".format(e))
            raise e#注意:实际结果与预期结果不符合的情况下没加raise e 通过,加了raise e 用例才抛出错误。
    #如果实际结果和预期结果是一致的,加raise e 和不加raise e,用例都是通过的。
        print(res.json())


    def tearDown(self):
        pass
代码语言:javascript
复制
#来自文件test_suite.py
#不是登录-充值的接口

import unittest
import HTMLTestRunner
from test_demo import quanjubianliang#模块名
suite=unittest.TestSuite()
#通过loader方式来加载用例,其它的方式也可以尝试。
loader=unittest.TestLoader()
suite.addTest(loader.loadTestsFromModule(quanjubianliang))


#执行
with open("test_summer.html",'wb')as file:
    runner=HTMLTestRunner.HTMLTestRunner(stream=file, verbosity=2,title="单元测试",description=None,tester="清菡")
    runner.run(suite)

文件夹下已创建文件http_request.py,文件quanjubianliang.py和文件test_suite.py,运行文件test_suite.py。

输出结果如下:

方法三:反射

代码语言:javascript
复制
#来自文件get_data.py

class GetData:
    Cookie=None#存储cookie,初始值为None
代码语言:javascript
复制
#文件来自fanshe.py

import unittest
from test_demo.http_request import HttpRequest
from test_demo.get_data import GetData

class TestHttp(unittest.TestCase):
    def setUp(self):
        #登录
        self.login_url='http://v.juhe.cn/laohuangli/d'
        #充值的URL
        self.recharge_url= 'http://v.juhe.cn/laohuangli/d'

    def test_login_normal(self):#正常登录
        data={"key": "abf91475fc19f66c2f1fe567edd75257", "date": '2014-09-09'}
        res=HttpRequest().http_request(self.login_url,data,'get')
    #if条件语句,后面为空就是False,不为空就是True。res.cookies不为空就是有cookie,有cookie的时候再去做替换。
        if res.cookies:#如果cookie有的话,就更新COOKIE
              setattr(GetData,'Cookie',res.cookies)
        try:
            self.assertEqual('超过每日可允许请求次数!',res.json()['reason'])
        except AssertionError as e:
            print("test_login_normal's error is{}".format(e))
            raise e
        print(res.json())

    def test_login_wrong_pwd(self):#输入错误的密码登录
        data={"key": "abf91475fc19f66c2f1fe567edd75257", "date": '2014-09-11'}
        res=HttpRequest().http_request(self.login_url,data,'get')
        try:
            self.assertEqual('超过每日可允许请求次数!',res.json()['reason'])
        except AssertionError as e:
            print("test_login_normal's error is{}".format(e))
            raise e
        print(res.json())

    def test_recharge_normal(self):#登录后正常充值
        recharge_data = {"key": "abf91475fc19f66c2f1fe567edd75257", "date": '2014-09-09'}
        res=HttpRequest().http_request(self.recharge_url,recharge_data,'post',getattr(GetData,"Cookie"))
        try:
            self.assertEqual('超过每日可允许请求次数!', res.json()['reason'])
        except AssertionError as e:
            print("test_recharge_normal's error is{}".format(e))
            raise e
        print(res.json())

    def test_recharge_negative(self):#登录后充值为负数
        recharge_data = {"key": "abf91475fc19f66c2f1fe567edd75257", "date": '-2014-09-09'}
        res=HttpRequest().http_request(self.recharge_url,recharge_data,'post',getattr(GetData,"Cookie"))
        try:
            self.assertEqual('超过每日可允许请求次数!',res.json()['reason'])
        except AssertionError as e:
            print("test_recharge_negative's error is{}".format(e))
            raise e
        print(res.json())


    def tearDown(self):
        pass
代码语言:javascript
复制
#文件来自test_suite.py
#不是登录-充值的接口

import unittest
import HTMLTestRunner
from test_demo import fanshe#模块名
suite=unittest.TestSuite()
#通过loader方式来加载用例,其它的方式也可以尝试。
loader=unittest.TestLoader()
suite.addTest(loader.loadTestsFromModule(fanshe))


#执行
with open("test_summer.html",'wb')as file:
    runner=HTMLTestRunner.HTMLTestRunner(stream=file, verbosity=2,title="单元测试",description=None,tester="清菡")
    runner.run(suite)

文件夹下已创建文件http_request.py,get_data.py文件,fanshe.py和文件test_suite.py,运行文件test_suite.py。

输出结果如下:

介绍反射的原理

代码语言:javascript
复制
#介绍反射的原理
class GetData:
        Cookie=None
        # Cookie='小郭'

if __name__ == '__main__':

    print(GetData.Cookie)
    setattr(GetData,"Cookie","小白")#1 可以直接把类里面的属性值做修改
          #  类名     属性名   新值
    print(hasattr(GetData,"Cookie"))#2 判断是否有这个属性值
    print(getattr(GetData,"Cookie"))#3  attribute 属性 获取这个属性值
    delattr(GetData,"Cookie")#4 把这个属性删掉
    # print(GetData.Cookie)
    print(hasattr(GetData,"Cookie"))#判断是否有这个属性值

直接运行代码就可以。

参数化

地址不一样,测试数据不同,断言的期望结果不同,除了这几个不同,其它的都是高度相似的,80%相似,可以用参数化。

参数化 url data expected

代码语言:javascript
复制
#来自文件get_data.py

class GetData:
    Cookie=None#存储cookie,初始值为None
代码语言:javascript
复制
#来自文件http_request.py

import requests
class HttpRequest:
    '''利用request封装get请求和post请求'''

    def http_request(self,url,data,method,cookie=None):
        '''url:请求的地址 http://xxx:port
               param:传递的参数  非必填参数  字典的格式传递参数
               method:请求方式支持get以及post  字符串形式的参数
               cookie:请求的时候传递的cookie值'''
        if method.lower()=='get':
            res = requests.get(url, data, cookies=cookie)
        else:
            res=requests.post(url,data,cookies=cookie)#响应结果的消息实体 http response包含响应头,响应状态码,响应正文,Cookie
        return res#返回一个消息实体

if  __name__ =='__main__':
    url = 'http://v.juhe.cn/xhzd/query'
    data = {"key": "e0dd844ff0669814b529da934a094a83", "word": '聚'}
    res=HttpRequest().http_request(url,data,'post')
    print("登录结果是:", res.json())

#充值
    recharge_url='http://v.juhe.cn/xhzd/query'
    recharge_data={"key": "e0dd844ff0669814b529da934a094a83", "word": '聚'}
    recharges_res=HttpRequest().http_request(recharge_url,recharge_data,'get',res.cookies)
    print("充值结果是:",recharges_res.json())
代码语言:javascript
复制
#来自文件test_http.py

#开拓思维必学
import unittest
from class_1101.http_request import HttpRequest
from class_1101.get_data import GetData


class TestHttp(unittest.TestCase):
    def setUp(self):
        pass

    # 数据给它参数化,通过初始化传参,实现参数化
    def __init__(self,methodName,url,data,method,expected):#通过初始化函数来传参数
        super(TestHttp,self).__init__(methodName)#父类的方法要保留,用的超继承。
        self.url=url
        self.data=data
        self.method=method
        self.expected=expected

    def test_api(self):#接口用例
            res=HttpRequest().http_request(self.url,self.data,self.method,getattr(GetData,'Cookie'))
            if res.cookies:#如果cookie有的话,就更新COOKIE
                  setattr(GetData,'Cookie',res.cookies)#反射
            try:
                self.assertEqual(self.expected,res.json()['reason'])
            except AssertionError as e:
                print("test_api's error is{}".format(e))
                raise e
            print(res.json())

    def tearDown(self):
        pass
代码语言:javascript
复制
#来自文件test_suite.py

#不是登录-充值的接口

import unittest
import HTMLTestRunner
from class_1101.test_http import TestHttp#类名

#列表里面嵌套了字典
test_data=[{"url":'http://v.juhe.cn/xhzd/query',                             #期望值
            "data":{"key": "e0dd844ff0669814b529da934a094a83", "word": '聚'},"expected":'超过每日可允许请求次数!','method':'get'},
           {"url":'http://v.juhe.cn/xhzd/query',
            "data":{"key": "e0dd844ff0669814b529da934a094a83", "word": ''},"expected":'超过每日可允许请求次数!','method':'post'},
           {"url":'http://v.juhe.cn/xhzd/query',
            "data": {"key": "e0dd844ff0669814b529da934a094a83", "word": '聚'},"expected":'超过每日可允许请求次数!','method':'get'},
           {"url":'http://v.juhe.cn/xhzd/query',
            "data" :{"key": "e0dd844ff0669814b529da934a094a83", "word": ''},"expected":'超过每日可允许请求次数!','method':'post'}]
suite=unittest.TestSuite()

#遍历数据
for item in  test_data:#创建实例
    suite.addTest(TestHttp("test_api",item['url'],item['data'],item['method'],item['expected']))
#实例的方式去加载用例url,data,method,expected


#执行
with open("test_summer.html",'wb')as file:
    runner=HTMLTestRunner.HTMLTestRunner(stream=file, verbosity=2,title="单元测试",description=None,tester="清菡")
    runner.run(suite)

文件夹下已创建文件http_request.py,get_data.py文件,test_http.py和文件test_suite.py,运行文件test_suite.py。

输出结果如下:


本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-02-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 清菡软件测试 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章总览图
    • 1.后面的用例需要用到第一条用例的返回结果里的某些值,怎么去处理这种依赖关系?
      • 2.代码如下
        • 方法一:setUp
          • 输入错误的密码和充值为负数的用例中增加了断言
            • 方法二:全局变量
              • 方法三:反射
                • 介绍反射的原理
                  • 参数化
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档