美文网首页
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