设置一个全局变量解决套件的初始化里面变量没办法存下来的问题

测试套件目录 执行结束后,要和执行前一致
测试套件文件 执行结束后,要和执行前一致
测试套件用例 执行结束后,要和执行前一致

核心就是为了设置一个全局变量,解决了棘手的问题:套件的初始化话,变量没办法存下来的问题
还有就是初始化里面创建的数据要留给后面用,动态产生的东西,就这样保存下来给后面用

  • set_global_variable 全局有效
  • set_suite_variable
    当前的套件有效,就像d-7年级1班里面的所有的子套件,子用例都有效。通常要限制范围就用set_suite_variable
  • set_test_variable 只对当前的用例有效。通常是在用例里面,用的不对。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

代码:
在这里插入图片描述

import requests
from cfg import g_vcode
from pprint import pprint
from robot.api import logger
from robot.libraries.BuiltIn import BuiltIn


class  SchoolClassLib:                      #通常用类实现关键字库,类名和文件名相同
    URL = "http://ci.ytesting.com/api/3school/school_classes"               #可以写在类的静态属性里面,也可以写在cfg的变量文件里面

    def __init__(self):                 #定义一个初始化方法
        self.vcode = g_vcode                #也可以直接用全局的变量g_vcode

    def set_vcode(self,vcode):
        self.vcode = vcode



    def delete_school_class(self,classid):                  #删除班级
        payload = {
            'vcode'  : self.vcode,
        }

        url = '{}/{}'.format(self.URL,classid)                  #url加上id,这里是这样构建一下
        response = requests.delete(url,data=payload)

        return response.json()


    def list_school_class(self,gradeid=None):                   #列出班级
        if gradeid != None:                         #gradeid是可填可不填的,缺省是none
            params = {                                  #如果传gradeid
                'vcode':self.vcode,
                'action':'list_classes_by_schoolgrade',
                'gradeid':int(gradeid)
            }
        else:
            params = {
                'vcode':self.vcode,                                     #如果不传
                'action':'list_classes_by_schoolgrade'
            }

        response = requests.get(self.URL,params=params)                 #params就是url请求的参数

        bodyDict = response.json()              #文档里规定响应是json格式的消息体。.json可以把json字符串转化为py中的对象。得到的是一个字典
        # pprint (bodyDict,indent=2)              #indent参数就是指定pprint打印出来的参数是两个
        logger.debug(f"ret:\n{bodyDict}")          #通常的执行就不显示了,报错的时候显示所有
        return bodyDict


    def add_school_class(self,gradeid,name,studentlimit,idSavedName=None):               #添加班级
        #最后一个参数就是给添加班级返回的id赋值的变量取一个名字
        #这个参数只有一个场景有用(初始化清除),大部分场景都没有用。这是应该用缺省参数
        payload = {
            'vcode'  : self.vcode,
            'action' : 'add',
            'grade'  : int(gradeid),
            'name'   : name,
            'studentlimit'  : int(studentlimit),
        }
        response = requests.post(self.URL,data=payload)

        bodyDict = response.json()
        pprint (bodyDict,indent=2)
        #logger.debug(f"ret:\n{bodyDict}")              #通常的执行就不显示了,报错的时候显示所有
        if idSavedName:             #如果传这个参数
            BuiltIn().set_global_variable("${%s}"%idSavedName,bodyDict['id'])
        #设置全局变量
        return bodyDict


    #修改班级接口
    def modify_school_class(self,classid,newname,newstudentlimit):
        url = f'{self.URL}/{classid}'           #字符串拼接url
        payload = {
            'vcode': self.vcode,
            'action': 'modify',
            'name': newname,
            'studentlimit': int(newstudentlimit),
        }
        response = requests.put(url,data=payload)
        bodyDict = response.json()
        pprint(bodyDict,indent=2)
        return bodyDict






    def delete_all_school_classes(self):                            #初始化清除,要删除所有的用例
        # 先列出所有班级
        rd =  self.list_school_class()
        pprint(rd, indent=2)

        # 删除列出的所有班级
        for one in rd['retlist']:                           #文档里面“retlist”:[{},{}]  {}里面是一个个班级,id也在里面
            self.delete_school_class(one['id'])                 #获取到id,传给delete

        #再列出所有班级
        rd =  self.list_school_class()
        pprint (rd,indent=2)

        # 如果没有删除干净,通过异常报错给RF
        # 参考http://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#reporting-keyword-status
        if rd['retlist'] != []:
            raise  Exception("cannot delete all school classes!!")


    # def classlist_should_contain(self,
    #                              classlist,
    #                              classname,
    #                              gradename,
    #                              invitecode,
    #                              studentlimit,
    #                              studentnumber,
    #                              classid):
    #     item = {
    #         "name":classname,
    #         "grade__name":gradename,
    #         "invitecode":invitecode,
    #         "studentlimit":int(studentlimit),
    #         "studentnumber":int(studentnumber),
    #         "id":classid,
    #         "teacherlist":[]
    #     }
    #     if item not in classlist:
    #         #在rf里面如果要实现一个检查点关键字,怎么表示检查点不通过???就是抛出异常。
    #         raise Exception("class list dose not contain your class info")
    #         #里面的东西随便写的
    



	#classlist_should_contain增强版:可能会添加一门课程,多了两条课程,为了解决这种情况。可以加一个参数指定它包含多少次
    def classlist_should_contain(self,
                                 classlist,
                                 classname,
                                 gradename,
                                 invitecode,
                                 studentlimit,
                                 studentnumber,
                                 classid,
                                 expectedtimes=1):           #可以设置一个缺省值,不写的话只应该包含一次
        item = {
            "name":classname,
            "grade__name":gradename,
            "invitecode":invitecode,
            "studentlimit":int(studentlimit),
            "studentnumber":int(studentnumber),
            "id":classid,
            "teacherlist":[]
        }
        
        occurTimes = classlist.count(item)          #看occurTimes在列表里面出现多少次
        if occurTimes != expectedtimes:            #实际出现的次数和预期的次数是否相等
            #在rf里面如果要实现一个检查点关键字,怎么表示检查点不通过???就是抛出异常。
            raise Exception(f"班级列表包含了{occurTimes}次指定信息,期望包含{expectedtimes}!!")
            #里面的东西随便写的


    def classlist_should_not_contain(self,
                                 classlist,
                                 classname,
                                 gradename,
                                 invitecode,
                                 studentlimit,
                                 studentnumber,
                                 classid):
        item = {
            "name":classname,
            "grade__name":gradename,
            "invitecode":invitecode,
            "studentlimit":int(studentlimit),
            "studentnumber":int(studentnumber),
            "id":classid,
            "teacherlist":[]
        }
        if item  in classlist:      #如果在里面的话就会抛出异常
            #在rf里面如果要实现一个检查点关键字,怎么表示检查点不通过???就是抛出异常。
            raise Exception("class list  contain your class info")
            #里面的东西随便写的















if __name__ == '__main__':                  #调试用
    scm = SchoolClassLib()
    #ret = scm.list_school_class(2)

    # ret = scm.add_school_class(1,'新测试',77)
    # print(json.dumps(ret, indent=2))
    #
    
    
    #ret = scm.delete_school_class(63630)
    # pprint(ret)
    
    # print(json.dumps(ret, indent=2))
    #
    # ret = scm.list_school_class(1)
    # print(json.dumps(ret, indent=2))
    # #
    #scm.delete_all_school_classes()
    #scm.classlist_should_contain()



"""
实现一些个关键字

"""

在这里插入图片描述

#第一种方法,相当于手动设置一个全局变量
*** keywords ***
suite setup action
    ${ret}=   add_school_class       1      1班      60
    set global variable   ${suitesetclassid}    &{ret}[id]

*** Settings ***
Library    pylib.SchoolClassLib
Suite Setup       suite setup action
Suite Teardown        delete_school_class     ${suitesetclassid}


#解释
#设置一个全局变量,添加的课程的响应返回值里面的id
# set global variable是设置的全局的
# set suit variable是设置的这个套件的








#第二种方法,因为升级了add_school_class这个关键字,关键字内部可以直接生成一个全局变量。一旦add_school_class的传值有suite_g7c1_classid,就会有一个全局变量suite_g7c1_classid



*** Settings ***
Library    pylib.SchoolClassLib
Suite Setup       add school class      1       1班      60      suite_g7c1_classid
Suite Teardown        delete_school_class     ${suite_g7c1_classid}









#测试套件目录  执行结束后,要和执行前一致
#测试套件文件  执行结束后,要和执行前一致
#测试套件用例  执行结束后,要和执行前一致



#这个文件里面是实现添加一个7年级1班的初始化
#实现的用例是创建一个班级,系统中不存在同年级的同名班级
#1是代表7年级,1班,上限不超过60人






#核心就是为了设置一个全局变量,解决了棘手的问题:套件的初始化话,变量没办法存下来的问题
#还有就是初始化里面创建的数据要留给后面用,动态产生的东西,就这样保存下来给后面用
#set_global_variable      全局有效
#set_suite_variable         当前的套件有效,就像d-7年级1班里面的所有的子套件,子用例都有效。通常要限制范围就用set_suite_variable
#set_test_variable        只对当前的用例有效。通常是在用例里面,用的不对。

在这里插入图片描述

*** Settings ***
Library    pylib.SchoolClassLib


*** Test Cases ***
#添加班级2 - tc000002
#    ${ret1}=    add school class    1     2班     60
#    should be true     $ret1['retcode']==0
#
##列出班级,和添加的班级检验一下,id一致,邀请码一致
#    ${ret2}=    list school class    1
#    should be true       {'name': '2班', 'grade__name': '七年级', 'invitecode': $ret1['invitecode'], 'studentlimit': 60, 'studentnumber': 0, 'id': $ret1['id'], 'teacherlist': []}in $ret2['retlist']
##列出班级的响应是这样的:(见图文档规定)
##rf的写法实在不是容易的事情,rf不擅长处理复杂的数据,不能换行。
##最好是通过其他的方法来实现
#    [Teardown]    delete_school_class   &{ret1}[id]
##&{ret1}是添加课程产生的字典,取出id删掉




#第二种简单,方便,基于py的写法,用关键字实现。

添加班级2 - tc000002
    ${ret1}=    add school class    1     2班     60
    should be true     $ret1['retcode']==0
    #验证状态码是不是0

#列出班级,检验一下
    ${ret2}=    list school class    1
    ${retlist}=   evaluate      $ret2['retlist']
    #把响应里面的retlist取出来,赋值到变量里面


    classlist should contain    ${retlist}
    ...      2班     七年级      &{ret1}[invitecode]     60      0       &{ret1}[id]
    #...是换行,后面传的都是参数,$ret1['invitecode']不是py表达式,所以里面不能加引号,从字典里面取数据用&
    #实现一个关键字,判断${retlist}里面是否包含2班,七年级。。。这些内容。


    [Teardown]    delete_school_class   &{ret1}[id]
    #&{ret1}是添加课程产生的字典,取出id删掉




添加班级3 - tc000003
    ${ret1}=    add school class    1     1班     60
    #这里创建的和数据环境里面的是一样的,满足创建一个已有的同名的课程
    #should be true     $ret1=={"retcode":1,"reason":"duplicated class name"}
    #根据文档判断返回值,可以向上面一样写,不能有两个以上的空行,安全起见,也可以分开写
    should be true     $ret1["retcode"]==1
    should be true     $ret1["reason"]=="duplicated class name"

#列出班级,检验一下
    ${ret2}=    list school class    1
    ${retlist}=   evaluate      $ret2['retlist']

    #实现关键字classlist should not contain ,列出的列表里面不包含下面的信息(就是添加的信息)
    classlist should not contain    ${retlist}
    ...      1班     七年级      &{ret1}[invitecode]     60      0       &{ret1}[id]

    #[Teardown]清除的操作就不要了,应该是添加不成功的。也没法根据id来删除



修改班级1 - tc000051
#添加7年级2班
    ${ret1}=    add school class    1     2班     60
    should be true     $ret1['retcode']==0
    ${classid}=     evaluate    $ret1["id"]

#修改为7年级222班
    ${modifyRet}=   modify_school_class         ${classid}      222班        60
    should be true     $modifyRet['retcode']==0

#列出班级,检验一下
    ${ret2}=    list school class    1
    ${retlist}=   evaluate      $ret2['retlist']
    #把响应里面的retlist取出来,赋值到变量里面

    classlist should contain    ${retlist}
    ...      222班     七年级      &{ret1}[invitecode]     60      0       &{ret1}[id]


    [Teardown]    delete_school_class   ${classid}




修改班级2 - tc000052
#添加7年级2班
    ${ret1}=    add school class    1     2班     60
    should be true     $ret1['retcode']==0
    ${classid}=     evaluate    $ret1["id"]

#先列出班级
    ${listret1}=    list school class    1



#修改为7年级1班
    ${modifyRet}=   modify_school_class         ${classid}      1班        60
    should be true     $modifyRet['retcode']==1
    should be true     $modifyRet["reason"]=="duplicated class name"

#再列出班级,和之前列出的班级比较下,是一样的话,就说明修改没有成功。就是正确的
    ${listret2}=    list school class    1
    should be equal     ${listret1}     ${listret2}

    [Teardown]    delete_school_class   ${classid}
    #这个用例执行不通过,就是系统的bug,返回的状态码是10000






修改班级3 - tc000053

#修改id号不存在的班级,可以写一个很大的数字
    ${modifyRet}=       modify_school_class         9999      1班        60
    should be true     $modifyRet["retcode"]==404
    should be true     $modifyRet['reason']=='id 为`9999`的班级不存在'
#    log to console      ${modifyRet}   可以打印出来看看,9999上面的符号有点坑




删除班级1 - tc000081

#删除id号不存在的班级,也可以写一个很大的数字
    ${delRet}=       delete school class         9999
    should be true     ${delRet}["retcode"]==404
    should be true     ${delRet}['reason']=='id 为`9999`的班级不存在'
#    log to console      ${modifyRet}   可以打印出来看看,9999上面的符号有点坑





删除班级2 - tc000082
#添加7年级2班
    ${ret1}=    add school class    1     2班     60
    should be true     $ret1['retcode']==0
    ${classid}=     evaluate    $ret1["id"]



#先列出班级
    ${listret1}=    list school class    1
    ${retlist}=     evaluate   $listret1["retlist"]
     classlist should contain    ${retlist}
    ...      2班     七年级      &{ret1}[invitecode]     60      0       &{ret1}[id]



#删除为7年级2班
    ${delRet}=       delete school class         ${classid}
    should be true     $delRet['retcode']==0

#列出班级,检验一下
    ${listret2}=    list school class    1
    ${retlist}=   evaluate      $listret2['retlist']
    #把响应里面的retlist取出来,赋值到变量里面

    classlist_should_not_contain    ${retlist}
    ...      2班     七年级      &{ret1}[invitecode]     60      0       &{ret1}[id]

在这里插入图片描述

*** Settings ***
Library    pylib.SchoolClassLib
Suite Setup        delete all school classe

在这里插入图片描述

*** Settings ***
Library    pylib.SchoolClassLib


*** Test Cases ***
添加班级1 - tc000001
    ${ret1}=    add school class    1     1班     60
    should be true     $ret1['retcode']==0

#列出班级,和添加的班级检验一下,id一致,邀请码一致
    ${ret2}=    list school class    1
    ${fc}=   evaluate   $ret2['retlist'][0]
    should be true    $fc['id']==$ret1['id']
    should be true    $fc['invitecode']==$ret1['invitecode']
#将垃圾数据清除掉,不要破坏空白数据环境
    [Teardown]    delete_school_class   &{ret1}[id]

#&{ret1}是添加课程产生的字典,取出id删掉

在这里插入图片描述

g_vcode = '00000002775300822470'



"""

全局的变量可以g-开头





"""

代码打包:https://pan.baidu.com/s/1DsD98-7lP0bNUai0jVbkyg

猜你喜欢

转载自blog.csdn.net/qq_37615098/article/details/84679788