zoukankan      html  css  js  c++  java
  • 接口自动化框框具体文件讲解 2

    封装request请求的类脚本,不是json请求就会返回字符串

    import requests
    import traceback
    from common.log import Log
    from common.utlis import create_sign
    from common.custom_class import NbDict
    class Request:#
    def __init__(self,url,params=None,data=None,headers=None,json=None,files=None):
    self.url = url
    self.params = params
    self.data = data
    self.headers = headers
    self.json = json
    self.files = files
    def __get_response(self):
    try:
    result = self.req.json()
    except Exception as e:
    return self.req.text
    else:
    result = NbDict(result)
    return result
    def get(self):
    Log.info("开始发送get请求")
    Log.info("url:【 {} 】,params : 【 {} 】headers:{}",self.url,self.params,self.headers)
    try:
    self.req = requests.get(self.url,params=self.params,headers=self.headers,verify=False)
    except Exception as e:
    Log.error("http请求发送出错,错误信息:{}",traceback.format_exc())
    raise Exception("接口请求不通")
    else:
    #
    return self.__get_response()
    def post(self):
    Log.info("开始发送post请求")
    Log.info("url:【 {} 】,params : 【 {} 】headers:{},data:{},json:{},files:{}",
    self.url,self.params,self.headers,self.data,self.json,self.files)
    try:
    self.req = requests.post(self.url,params=self.params,
    data=self.data,json=self.json,
    files=self.files,
    headers=self.headers,verify=False)
    except Exception as e:
    Log.error("http请求发送出错,错误信息:{}",traceback.format_exc())
    raise Exception("接口请求不通")
    else:
    return self.__get_response()
    if __name__ == "__main__":#下发就是调用的方法,发请求的类
    url = "https://oapi.dingtalk.com/robot/send?access_token=74f3028e80a522f28733f3dab9f0d1060f77a5749da637c531bd999f3828ec9b"
    sign = create_sign()
    msg = "hhhhhhhh "
    data = {
    "msgtype": "text",
    "text": {
    "content": msg
    },
    "at": {
    "atMobiles": [
    "15620922243",
    "13011823376",
    "13240224523",
    "15901399089"
    ],
    "isAtAll": False
    }
    }
    r = Request(url,params=sign,json=data)
    result = r.post()
    print(result)
    下面讲解发邮件的方法 ,要先写到ini文件把邮件配置
    import yamail
    from common.http_request import Request
    from common.utlis import parse_ini,create_sign
    ddconfig = parse_ini('dingding') #取钉钉的配置信息
    mail_config = parse_ini('mail') #取邮箱的配置信息
    url = ddconfig.get('url') #钉钉的url
    access_token = ddconfig.get('access_token') #access_token
    at = ddconfig.get('at','').split(',') #钉钉发送消息的时候ai给谁
    def send_dingding(msg):
    data = {
    "msgtype": "text",
    "text": {
    "content": msg
    },
    "at": {
    "atMobiles":at,
    "isAtAll": False
    }
    }
    sign = create_sign()
    sign['access_token'] = access_token
    r = Request(url,params=sign,json=data)
    r.post()
    def send_mail(subject,contents,attachments=None):
    smtp = yamail.SMTP(
    host=mail_config.get("host"), # 改成自己邮箱的邮箱的服务器即可
    user=mail_config.get("user"),
    password=mail_config.get("password") # 如果是163、qq等免费邮箱的话需要授权码,
    # 自己公司的邮箱,一般都使用密码
    )
    smtp.send(to=mail_config.get("to",'').split(','), # 发送给谁
    subject=subject, # 邮件主题
    cc=mail_config.get("cc",'').split(','), # 抄送,如果是多个人写list
    contents=contents, # 邮件正文
    attachments=attachments # 附件,如果是多个附件,写list
    )
    smtp.close()

    if __name__ == "__main__":
    send_dingding("哈哈哈,nhy")
    support目录下的urls专门用来定义Url的防止url变化 ,这里为了写接口的名称 
    from urllib.parse import urljoin
    from common.config_parse import parse_ini
    host = parse_ini('server').get('host')
    class ServerUrl:
    login_url = urljoin(host,'/api/user/login') #登录url join就是拼接的
    register_url = urljoin(host,'/api/user/user_reg') #注册url
    if __name__ == "__main__":
    pass
    flow下面文件是负责写xx相关的接口根据你模块和功能分类
    from common.http_request import Request
    from biz.support.urls import ServerUrl#帮你拼接路径
    class UserRequest:
    @classmethod
    def login(cls,username,password):#这里写你接口要传的参数
    '''
    调用登录接口的
    :param username: 用户名
    :param password: 密码
    :return:
    '''
    data = {
    'username':username,
    'passwd':password
    }
    req = Request(ServerUrl.login_url,data=data)#传url和请求
    return req.post()#发送post请求

    @classmethod
    def register(cls,username,pwd,cpwd):
    '''
    注册
    :param username: 用户名
    :param password: 密码
    :param cpassword: 确认密码
    :return:
    '''
    data = {
    "username":username,
    "pwd":pwd,
    "cpwd":cpwd,
    }
    req = Request(ServerUrl.login_url,data=data)
    return req.post()
    if __name__ == "__main__":
    result = UserRequest.login('niuhanyang','aA123456')#传值
    print(result)
    单元测试在biz/case/test下进行单元测试
    import unittest
    from biz.flow.user import UserRequest
    from common.utlis import get_redis,get_mysql
    from biz.cases.base_case import BaseCase
    class TestLogin(BaseCase):
    '''登录接口测试用例'''
    data_file_name = 'login_data.yaml' #
    @classmethod
    def setUpClass(cls):
    cls.redis = get_redis()
    cls.mysql = get_mysql()
    def test_normal(self):
    '''正常登录'''
    username = self.file_data.get('username')
    password = self.file_data.get('password')
    ret = UserRequest.login(username,password)
    self.assertEqual(0,ret.error_code,'返回的错误码不是0')
    self.assertIsNotNone(ret.login_info.login_time,msg='logintime为空')
    redis_key = 'session:%s' % username
    sessionid = self.redis.get(redis_key)
    sql = 'select id from app_myuser where username = "%s";' % username
    db_result = self.mysql.fetchone(sql)
    user_id = db_result.get('id')
    self.assertEqual(sessionid,ret.login_info.sign,msg="返回的session和redis中的不一致")
    self.assertEqual(user_id,ret.login_info.userId,msg="返回的userId和数据库中的不一致")
    if __name__ == "__main__":
    pass
    在bizcases下base写一个读yaml方法
    import unittest
    from common.config_parse import load_yaml
    class BaseCase(unittest.TestCase):
    data_file_name = None
    @property
    def file_data(self):
    data = load_yaml(self.data_file_name)
    return data
    @classmethod
    def get_token(cls,username):
    pass
    if __name__ == "__main__":
    pass
    bin下封装生成测试报告脚本 test是牛逼方法取.取数据
    import unittest
    import os,time,sys
    BASE_PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    sys.path.index(0,BASE_PATH)
    from conf.settings import CASE_PATH,REPORT_PATH,dd_template,mail_template
    from common import send_msg
    from common.HTMLTestRunner import HTMLTestRunner
    def run():
    test_suite = unittest.defaultTestLoader.discover(CASE_PATH,'test*.py')
    file_name = 'report_%s.html' % time.strftime('%Y%m%d%H%M%S')
    file_abs = os.path.join(REPORT_PATH,file_name )
    with open(file_abs,'wb') as fw:
    runner = HTMLTestRunner(stream=fw,title='测试报告标题',description='描述')
    case_result = runner.run(test_suite)
    all_count = case_result.failure_count + case_result.success_count
    dd_msg = dd_template % (all_count,case_result.success_count,case_result.failure_count)
    mail_msg = mail_template % (all_count,case_result.success_count,case_result.failure_count)
    send_msg.send_dingding(dd_msg)
    subject = '天马座自动化测试报告-%s' % time.strftime('%Y-%m-%d %H:%M:%S')
    send_msg.send_mail(subject,mail_msg,file_abs)
    if __name__ == "__main__":
    run()
    思考
    做自动化时候考虑,适合做自动化吗?技术支撑 ?
    规划 那些场景做自动化?那些场景不可以做自动化?

    比如有些功能银行缺少接口,我就开发Mock平台,这时候,我们调银行需要的连接配置好了,返回的数据是一样的
    我下次测试让开发调用我mock平台的接口,我想测试各种情况我就这样测试



  • 相关阅读:
    ASP.NET实现进度条效果【转】
    删除指定创建日期前的文件夹、文件
    MS SQL SERVER执行大脚本文件时,提示“内存不足”的解决办法
    solr之functionQuery(函数查询)【转】
    解决Jenkins连接git时报错Permission denied (publickey)
    vscode csharp c#开发 自动引入命名空间
    nginx配置后外网无法访问
    jenkins node 版本无法使用最新的版本
    jenkins npm install WARN checkPermissions Missing write access 权限问题
    小程序setData只修改对象中的某个属性的方法
  • 原文地址:https://www.cnblogs.com/weilemeizi/p/14540411.html
Copyright © 2011-2022 走看看