美文网首页
RobotFramework接口测试分享(二)

RobotFramework接口测试分享(二)

作者: liuxiro | 来源:发表于2020-05-23 14:21 被阅读0次

    进阶问题

    1、接口返回:用户未登录——session处理

    2、接口返回:验签失败——参数签名

    3、接口返回:解密失败——参数加密

            在接口测试框架搭建的时候,这些问题难免会劝退不少人。问题1是需要进行参数传递,将登录成功后的session保存下来,并在后续的业务接口中复用;问题2和3,则需要花时间研究接口脚本,理解签名原理和加密方法,然后编写签名和加密的方法。

    假设:初始化(无加密字段)→登录请求(密码加密)→业务请求

            不难分析出来,首先会遇到的问题是参数签名,然后是参数加密,最后是session

    参数签名

            参数签名需要参考接口文档,但大体还是类似的,只会存在一些小的差异。

    举个例子:

            1、添加请求参数:temp,值为13位的时间戳;

            2、对所有请求的非空参数按key的ascii码排序;

            3、按“key=value”格式并已“&”进行拼接,并在最后拼接上秘钥“key=XXX”;

            4、将拼接好的字符串进行MD5加密并将密文转成大写;

            5、添加请求参数:sign,值为MD5密文。

            所以,我们需要设计一个方法,传入原始的请求参数,返回签名后的参数。

    import time, hashlib

    def Sign_data(dict):

        signKey = "test_key_1234567"  #签名秘钥

        temp ="CS" +str(int(time.time() *1000)) 

        dict["temp"] = temp #拼接时间戳

        dict_temp = dict

        list_temp =sorted(dict_temp.keys())

        for key in list_temp:  #去除值为空的key

            if dict_temp[key] =="":

                del dict_temp[key]

        list_temp =sorted(dict_temp.keys())  #创建key的列表,并排序

        string =""

        for list_temp_key in list_temp:  #拼接待签名字符串

            string = string + list_temp_key +"=" +str(dict_temp[list_temp_key]) +"&"

        string = string +"key=" + signKey  #拼接秘钥

        try:  #进行MD5签名及转换大写,并将签名值并入请求参数

            sign = hashlib.md5(string.encode("utf-8")).hexdigest().upper()

            dict["sign"] = sign

        except:

            print('Sign Error!!')

        return dict

    签名前:{'account': 'admin', 'password': 'a123456'} 

    签名后:{'account': 'admin', 'password': 'a123456', 'temp': 'CS1601346355016', 'sign': '52C0A0CA2F2EA451DEFF011D5F3AA2AA'}

    参数加密

            对于一些重要的信息,如:密码、银行卡账号、手机号码、邮箱等隐私信息。是需要加密后再传输的,以免数据被窃取导致重要信息泄露。尤其是支付密码等重要信息,对加密要求更加重视。

            这里举个简单的例子,对隐私信息,需要进行3DES加密后,再签名。

    import base64

    from Crypto.Cipher import DES3

    BS = DES3.block_size

    def _pad(value): 

        return value + (BS - len(value) % BS) * chr(BS - len(value) % BS)

    def _3DES(value):

        signKey = "test_key_1234567"

        value = _pad(value)

        crypto_des3 = DES3.new(signKey, DES3.MODE_ECB)

        x = len(value) % 8

        if x != 0:

            value = value + '\0' * (8 - x)

        ciphervalue = crypto_des3.encrypt(value)

    return base64.standard_b64encode(ciphervalue).decode("utf-8")

    加密前:a123456

    加密后:elnNMd0ac4M=


    封装方法

            在编译器已经将加密和签名的方法都已经编写完成,方法需要在RobotFramework里使用,需要进行封装处理。

    创建Python Package,命名为SignMethord,文件夹内创建Python文件,命名signMethord.py。

    1、signMethod.py    定义一个类SignMethod,并将前面的加密函数添加进入类

    import time, hashlib, base64

    from Crypto.Cipherimport DES3

    BS = DES3.block_size

    class SignMethod(object):

        def _pad(self, s):

            return s + (BS -len(s) % BS) *chr(BS -len(s) % BS)

        def _3DES(self, value):

            signKey ="test_key_1234567"  # 签名秘钥

            value = SignMethod()._pad(value)

            crypto_des3 = DES3.new(signKey, DES3.MODE_ECB)

            x =len(value) %8

                if x !=0:

            value = value +'\0' * (8 - x)

            ciphervalue = crypto_des3.encrypt(value)

        return base64.standard_b64encode(ciphervalue).decode("utf-8")

        def Sign_data(self, dict):

            signKey ="test_key_1234567"  # 签名秘钥

            temp ="CS" +str(int(time.time() *1000))

            dict["temp"] = temp# 拼接时间戳

            dict_temp = dict

            list_temp =sorted(dict_temp.keys())

            for key in list_temp:# 去除值为空的key

                if dict_temp[key] =="":

                    del dict_temp[key]

            list_temp_key =list(set(dict_temp.keys()).intersection({'password','phone','cardId'})) #获取请求参数中需要加密的key

            if len(list_temp_key) !=0:

                for temp_keyin list_temp_key:

                    dict_temp[temp_key] = SignMethod()._3DES(dict_temp[temp_key])

            list_temp =sorted(dict_temp.keys())# 创建key的列表,并排序

            string =""

            for list_temp_key in list_temp:# 拼接待签名字符串

                string = string + list_temp_key +"=" +str(dict_temp[list_temp_key]) +"&"

            string = string +"key=" + signKey# 拼接秘钥

            try:# 进行MD5签名及转换大写,并将签名值并入请求参数

                sign = hashlib.md5(string.encode("utf-8")).hexdigest().upper()

                dict["sign"] = sign

            except:

                print('Sign Error!!')

        return dict

    #主函数,调试

    if __name__ =="__main__":

    Sign = SignMethod()

    data = {"account":"admin",

                "password":"a123456"}

    print(data)

    print(Sign.Sign_data(data))

    处理前:{'account': 'admin', 'password': 'a123456'}

    处理后:{'account': 'admin', 'password': 'elnNMd0ac4M=', 'temp': 'CS1601351366732', 'sign': 'BB94E448E5A3848A547332EBB643CB11'}

    2、__init__.py

    from .signMethod import SignMethod

    class SignMethod(SignMethod): 

        ROBOT_LIBRARY_SCOPE = 'GLOBAL' 

    文件编辑完成后,将文件夹移动到python目录下的/site-package目录内,即可在RobotFramework内调用该方法

    加入SignMethod 参数加密签名

    运行结果如下:

    Starting test: Rf test.Rf mian.test

    20200929 14:01:38.920 : INFO : &{data} = { account=admin | password=a123456 } 

    20200929 14:01:38.921 : INFO : &{data} = { account=admin | password=elnNMd0ac4M= | temp=CS1601359298919 | sign=D469F8D02FDBF95B0D4116BC38826551 } 

    Ending test: Rf test.Rf mian.test

            到这一步,就完成了接口请求参数的加密和签名。各项目的加密方法会不一样,签名方式也存在一定的区别,这个需要自己花点时间去研究。甚至,在做加密集成的时候,还会踩出不少坑。例如,在3DES加密的时候,需要用到Crypto的第三方库,这个库在windows上安装是需要C++的基础环境的依赖,需要另外安装,这个就是其中一个采坑的经历。然而,在linux安装则可以直接使用pip安装即可。当然也有另外的库可以取代:pycryptodome

    Session处理

    1、初始化后,获取返回的session值并存入headers

    2、使用新的headers进行登录

    2、使用带session的headers进行登录

    3、登录成功后,即可使用该session进行后续业务接口的访问

    3、使用已登录的session,进行修改用户昵称操作

    注意:session存在有效期

    到此为止,就可以开始真正意义上的接口测试了!

    相关文章

      网友评论

          本文标题:RobotFramework接口测试分享(二)

          本文链接:https://www.haomeiwen.com/subject/tqzcohtx.html