python接口测试-项目实践(八)

脱敏后脚本

projectapi.py: 项目接口类

# -*- coding:utf-8 -*-
"""
xx项目接口类
2018-11
dinghanhua
"""

import requests
import re
import pymssql

#region 工具类函数
def findinfo_from_apiquerystockdetailinfo(str1,str2):
    """
    从str1中找第一个"str2":...后面的值
    :param str1:
    :param str2:
    :return: str2对应的值
    """
    pattern1 = ‘"‘+str2 + ‘":(.*?),"‘ #左右边界
    result = re.search(pattern1, str1) #正则匹配
    if result:
        result = result.group(1).replace(‘"‘,‘‘)
    return result

def get_last_value_of_key(resultlist,key):
    ‘‘‘
    从二维数组取第一行的元素对应的最后一行的值
    :param resultlist:
    :param key:
    :return: value
    ‘‘‘
    for i in range(0,len(resultlist[0])):
        if key == resultlist[0][i]:   #第一行中找到对应字段名的索引
            result = resultlist[-1][i]
            return result #返回数组最后一行对应的值

def round_test(data,i=0):
    ‘‘‘
    四舍五入,解决round(7.35)=7.3的问题
    :param data:
    :param i: 保留的位数,默认保留一位小数
    :return:
    ‘‘‘
    if isinstance(i,int): #i是整数
        raise Exception(‘the second param must be int‘)
    else:
        mi = 10**i
        f = data*mi - int(data*mi)
        if f >=0.5:
            res = (int(data*mi)+1)/mi
        elif f <=-0.5:
            res = (int(data*mi-1))/mi
        else:
            res = int(data*mi)/mi
        if i<=0:
            res = int(res)
    return res
# endregion

class ProjectApi:
    def api_querystockdetailinfo(self,stockcode):
        """
        请求并提取股票基本信息接口数据
        :param stockcode:
        :return: 截取信息dict
        """
        api = ‘http://testdomain/querystockdetailinfo?stockcode={stockcode}‘.format(stockcode = stockcode)
        response = requests.get(api)
        result = response.text.replace(r‘\n‘,‘‘).replace(‘\\‘, ‘‘)  # 去掉特殊字符\n,\
        result_dict = {‘stockcode‘: stockcode}

        #股票名称
        result_dict[‘StockName‘] = findinfo_from_apiquerystockdetailinfo(result, ‘StockName‘)

        if result_dict[‘StockName‘]: #股票名称存在继续处理其他字段,否则报错并返回

            # 公司概要 #剔除公司概要中“公司”“公司是”、“公司是一家”高度重复的内容
            overviewvalue = result_dict[‘OverviewValue‘] = findinfo_from_apiquerystockdetailinfo(result, ‘OverviewValue‘)

            if overviewvalue.startswith(‘公司是一家‘):
                result_dict[‘OverviewValue‘] = overviewvalue[5:]
            elif overviewvalue.startswith(‘公司是‘):
                result_dict[‘OverviewValue‘] = overviewvalue[3:]
            elif overviewvalue.startswith(‘公司‘):
                result_dict[‘OverviewValue‘] = overviewvalue[2:]

            if not overviewvalue.endswith(‘。‘): #判断最后是否有句号,没有加一个
                result_dict[‘OverviewValue‘] += ‘。‘

            # 市值
            typecap = findinfo_from_apiquerystockdetailinfo(result, ‘TypeCap‘)
            dictcap = {‘1‘: ‘巨盘‘, ‘2‘: ‘大盘‘, ‘3‘: ‘中盘‘, ‘4‘: ‘小盘‘, ‘5‘: ‘微盘‘}
            result_dict[‘TypeCap‘] = dictcap[typecap]

            # 风格
            TypeStyle = result_dict[‘TypeStyle‘] = findinfo_from_apiquerystockdetailinfo(result, ‘TypeStyle‘)
            dictstyle = {‘1‘: ‘成长‘, ‘2‘: ‘价值‘, ‘3‘: ‘周期‘, ‘4‘: ‘题材‘, ‘5‘: ‘高价值‘}
            if len(TypeStyle) == 1:
                result_dict[‘TypeStyle‘] = dictstyle[TypeStyle]
            elif len(TypeStyle) >1:
                typestylelist = TypeStyle.split(‘,‘)  #风格可能有多个
                for t in range(len(typestylelist)):
                        typestylelist[t] = dictstyle[typestylelist[t]]
                result_dict[‘TypeStyle‘] = ‘、‘.join(typestylelist)

            # 生命周期 LifecycleValue 生命周期(单选,例:1);(1初创期、2成长期、3成熟期、4衰退期)")
            LifecycleValue = findinfo_from_apiquerystockdetailinfo(result, ‘LifecycleValue‘)
            dictlifecycle = {‘1‘: ‘初创期‘, ‘2‘: ‘成长期‘, ‘3‘: ‘成熟期‘, ‘4‘: ‘衰退期‘, ‘5‘: ‘周期底部‘, ‘6‘: ‘周期顶部‘, ‘7‘: ‘周期向下‘, ‘8‘: ‘周期向上‘}
            if LifecycleValue:
                result_dict[‘LifecycleValue‘] = dictlifecycle[LifecycleValue]

            # 估值 ScoreTTM 估值(分值1~5,>=4 偏低, <=2 偏高,其他适中)")
            ScoreTTM = findinfo_from_apiquerystockdetailinfo(result, ‘ScoreTTM‘)
            if ScoreTTM:
                if float(ScoreTTM) >= 4:
                    result_dict[‘ScoreTTM‘] = ‘偏低‘
                elif ScoreTTM and float(ScoreTTM) <= 2:
                    result_dict[‘ScoreTTM‘] = ‘偏高‘
                else:
                    result_dict[‘ScoreTTM‘] = ‘适中‘

            # 成长指数 ScoreGrowing  成长指数(分值1~5,>=4 高, <=2 低,其他中)‘)
            ScoreGrowing = findinfo_from_apiquerystockdetailinfo(result, ‘ScoreGrowing‘)
            if ScoreGrowing:
                if float(ScoreGrowing) >= 4:
                    result_dict[‘ScoreGrowing‘] = ‘高‘
                elif float(ScoreGrowing) <= 2:
                    result_dict[‘ScoreGrowing‘] = ‘低‘
                else:
                    result_dict[‘ScoreGrowing‘] = ‘中‘
            else:
                result_dict[‘ScoreGrowing‘]=‘‘

            # 盈利能力
            ScoreProfit = findinfo_from_apiquerystockdetailinfo(result, ‘ScoreProfit‘)  # ‘   ScoreProfit  盈利能力(分值1~5,>=4 高, <=2 低,其他中)‘ )
            if ScoreProfit:
                if float(ScoreProfit) >= 4:
                    result_dict[‘ScoreProfit‘] = ‘高‘
                elif float(ScoreProfit) <= 2:
                    result_dict[‘ScoreProfit‘] = ‘低‘
                else:
                    result_dict[‘ScoreProfit‘] = ‘中‘
            else:
                result_dict[‘ScoreProfit‘]=‘‘

        return result_dict

    def api_finance(self,stockcode):
        """
        请求并提取财务数据
        :param stockcode:
        :return: dict
        """
        api = ‘http://testdomain/finance?stockcode={stockcode}‘.format(stockcode = stockcode)
        response = requests.get(api)
        response.encoding = ‘utf-8-sig‘
        result = response.json()[‘data‘][0][‘result‘]  # 转化为二位数组
        result_dict = {‘stockcode‘: stockcode} #存储返回结果

        if len(result) <3: #说明股票没数据
            return result_dict

        # 当期报告期
        result_dict[‘EndDate‘] = get_last_value_of_key(result, ‘EndDate‘)
        # 预测收益报告期
        ReportPeriod = get_last_value_of_key(result, ‘ReportPeriod‘)
        dictreportperoid = {‘03/31‘: ‘一季度‘, ‘06/30‘: ‘上半年‘, ‘09/30‘: ‘前三季度‘, ‘12/31‘: ‘本年度‘}
        if ReportPeriod and ReportPeriod != result_dict[‘EndDate‘]: #预测收益报告期不等于当期报告期
            ReportPeriod = get_last_value_of_key(result, ‘ReportPeriod‘)[5:10]
            result_dict[‘ReportPeriod‘] = dictreportperoid[ReportPeriod]
        else:
            result_dict[‘ReportPeriod‘] = ‘‘
        # 预测业绩情况
        PerformanceType = get_last_value_of_key(result, ‘PerformanceType‘)
        result_dict[‘PerformanceType‘] = PerformanceType
        # 预测业绩比例
        result_dict[‘PerformanceTypeRange‘] = get_last_value_of_key(result, ‘PerformanceTypeRange‘)
        # 营业收入增长率
        result_dict[‘OperatingRevenueYoY‘] = get_last_value_of_key(result, ‘OperatingRevenueYoY‘)
        # 营业利润增长率
        result_dict[‘NetProfitYoY‘] = get_last_value_of_key(result, ‘NetProfitYoY‘)
        # 净资产收益率
        result_dict[‘ROE‘] = get_last_value_of_key(result, ‘ROE‘)
        # 毛利率
        result_dict[‘SalesGrossMargin‘] =  get_last_value_of_key(result, ‘SalesGrossMargin‘)

        return result_dict

    def api_quote(self,stockcode):
        """
        请求并提取PETTM
        :param stockcode:
        :return: dict
        """

        api = ‘http://testdomain/quote?stockcode={stockcode}‘.format(stockcode=stockcode)
        response = requests.get(api)
        response.encoding = ‘utf-8-sig‘
        result = response.json()[‘data‘][0][‘result‘]  # 转化为二位数组
        result_dict = {‘stockcode‘:stockcode}
        if len(result) <3: #说明股票没数据
            return result_dict
        result_dict[‘PETTM‘] = get_last_value_of_key(result, ‘PE1‘)
        return result_dict

    def result_of_3sourceapi(self,stockcode):
        """
        拼接3个接口取出的字串
        :param stockcode:
        :return:
        """
        result_stockdetailinfo = self.api_querystockdetailinfo(stockcode)
        if result_stockdetailinfo[‘StockName‘]: #如果股票名称存在,执行后续步骤
            result_finance = self.api_finance(stockcode)
            result_quote = self.api_quote(stockcode)

            #显示三个接口结果
            #print(result_stockdetailinfo)
            #print(result_finance)
            #print(result_quote)

            #空值、精度处理
            OperatingRevenueYoY = round_test(float(result_finance[‘OperatingRevenueYoY‘]),1)
            NetProfitYoY = round_test(float(result_finance[‘NetProfitYoY‘]),1)

            if result_finance[‘ReportPeriod‘] ==‘‘                    or result_finance[‘PerformanceType‘] == ‘‘                    or result_finance[‘PerformanceTypeRange‘] == ‘‘:
                ReportPeriod  = PerformanceType = PerformanceTypeRange = ‘‘
            else:
                ReportPeriod = ‘,预计‘ + result_finance[‘ReportPeriod‘]
                PerformanceType = ‘业绩‘ + result_finance[‘PerformanceType‘]
                PerformanceTypeRange = result_finance[‘PerformanceTypeRange‘]

            if result_finance[‘ROE‘]:
                ROE = ‘,净资产收益率:{0}%‘.format(round_test(float(result_finance[‘ROE‘]),1))
            else:
                ROE = ‘‘

            if result_finance[‘SalesGrossMargin‘]:
                SalesGrossMargin = ‘,毛利率:{0}%‘.format(round_test(float(result_finance[‘SalesGrossMargin‘]),1))
            else:
                SalesGrossMargin = ‘‘

            result = ‘{OverviewValue} {TypeCap}{TypeStyle}股,处于{LifecycleValue}。‘                      ‘估值{ScoreTTM},PE(TTM):{PETTM};‘                      ‘成长性{ScoreGrowing},当期营收增长:{OperatingRevenueYoY}%,当期利润增长:{NetProfitYoY}%;‘                      ‘盈利能力{ScoreProfit}{ROE}{SalesGrossMargin}{ReportPeriod}{PerformanceType}{PerformanceTypeRange}。‘                .format(OverviewValue = result_stockdetailinfo[‘OverviewValue‘],
                        TypeCap = result_stockdetailinfo[‘TypeCap‘],
                        TypeStyle = result_stockdetailinfo[‘TypeStyle‘],
                        LifecycleValue = result_stockdetailinfo[‘LifecycleValue‘],
                        ScoreTTM = result_stockdetailinfo[‘ScoreTTM‘],
                        PETTM = round_test(float(result_quote[‘PETTM‘])),
                        ScoreGrowing = result_stockdetailinfo[‘ScoreGrowing‘],
                        OperatingRevenueYoY = OperatingRevenueYoY,
                        NetProfitYoY = NetProfitYoY,
                        ScoreProfit = result_stockdetailinfo[‘ScoreProfit‘],
                        ROE = ROE,
                        SalesGrossMargin=SalesGrossMargin,
                        ReportPeriod = ReportPeriod,
                        PerformanceType = PerformanceType,
                        PerformanceTypeRange = PerformanceTypeRange)

            return result
        else:
            return  ‘不存在该股票数据‘

    def api_of_dev(self,stockcodelist,cookie,page=0,domain=‘testdomain.cn‘):
        """
        获取开发接口数据
        :param 股票列表;cookie;domain默认线上
        :return: 股票代码及数据
        """
        headers = {‘Cookie‘:cookie}
        url = ‘http://{domain}/getstockbypage?StockCodeList={stockcodelist}&PageIndex={page}&PageSize=10‘.format(stockcodelist = stockcodelist,domain = domain,page=page)

        response = requests.get(url, headers=headers)
        jsonstr = response.json()# 转成json,取出message
        message = jsonstr[‘Message‘]
        dict_result = {}

        if message:
            for ele in message:
                 stockcode = ele[‘StockCode‘]
                 content = ele[‘Content‘]  # 实际结果
                 nickname = ele[‘NickName‘] #发布者
                 if nickname == ‘project000‘:
                    dict_result[stockcode] = content

        return dict_result

    def compare_vs_devapi(self,stockcodelist,cookie,page=0,domain=‘testdomain.cn‘):
        """
        开发接口数据与接口拼接数据对比
        :return: bool
        """
        diff_list = []  # 存储不一致的股票代码

        resultofdev = self.api_of_dev(stockcodelist,cookie,page,domain) #请求开发接口
        if resultofdev: #如果开发结果不为空
            for stock,actual in resultofdev.items():
                expected = self.result_of_3sourceapi(stock) #数据源拼接结果

                ‘‘‘去掉pe(ttm)对比‘‘‘
                beginindex = actual.find(‘PE(TTM)‘)
                endindex = actual.find(‘;‘, beginindex)
                actual_result = actual[:beginindex] + actual[endindex:]

                beginindex = expected.find(‘PE(TTM)‘)
                endindex = expected.find(‘;‘, beginindex)
                expected_result = expected[:beginindex] + expected[endindex:]

                if actual_result != expected_result: #预期实际对比
                    print(stock)
                    print(‘开发:‘,actual_result)
                    print(‘预期:‘,expected_result)
                    diff_list.append(stock)
                else:
                    print(stock,‘一致(不含PETTM)‘)

            if diff_list: #异常股票列表不为空则输出;空则提示全部一致
                print(‘不一致的股票列表:‘, diff_list)
                return False
            else:
                print(‘对比结果:数据一致‘)
                return True
        else:
            print(‘接口没有数据‘)
            return True

    def compare_vs_database(self,count=10):
        """
        比较数据库数据与数据源拼接字串
        :param count:对比股票数量,default=10
        :return:True 一致;False 不一致
        """

        diff_list = []  # 存储不一致的股票代码

        with pymssql.connect(server=‘192.168.1.1‘, user=‘sa‘, password=‘sa‘,
                             database=‘test_db‘) as myconnect:
            with  myconnect.cursor(as_dict=True) as cursor:
                cursor.execute("""SELECT top {count} StockCode,StockName,content
                FROM [test_db].[dbo].[table]
                where NickName =‘project000‘ and isvalid = 1 and IsDeleted =0 order by createtime desc""".format(count=count))
                for row in cursor:
                    stockcode = row[‘StockCode‘]
                    actual = row[‘content‘]
                    expected = self.result_of_3sourceapi(stockcode)  # 数据源拼接结果

                    ‘‘‘去掉pe(ttm)对比‘‘‘
                    beginindex = actual.find(‘PE(TTM)‘)
                    endindex = actual.find(‘;‘, beginindex)
                    actual_result = actual[:beginindex] + actual[endindex:]
                    beginindex = expected.find(‘PE(TTM)‘)
                    endindex = expected.find(‘;‘, beginindex)
                    expected_result = expected[:beginindex] + expected[endindex:]

                    if actual_result != expected_result:  # 预期实际对比
                        print(stockcode)
                        print(‘开发:‘, actual_result)
                        print(‘预期:‘, expected_result)
                        diff_list.append(stockcode)
                    else:
                        print(stockcode, ‘一致(不含PETTM)‘)

        if diff_list:
            print(‘不一致的股票列表:‘, diff_list)
            return False
        else:
            print(‘对比结果:数据全部一致‘)
            return True

run_test.py 执行脚本:

# coding:utf-8
"""
接口测试执行脚本
"""

import projectapi
import unittest

class ApiTest(unittest.TestCase):

    def setUp(self):
        self.projectapi1 = projectapi.ProjectApi() # 创建接口对象

    def testcase1(self):
        """与开发接口比对"""
        stockcodelist = ‘600000%2C600128%2C600146%2C600165%2C600186‘
        #通过抓包获取cookie
        cookie = ‘globalid=24A85DEC-AF25-36DD-C774-ED092F705767‘

        testresult = self.projectapi1.compare_vs_devapi(stockcodelist,cookie)
        self.assertTrue(testresult)

    def testcase2(self):
        # 与数据库对比
        testresult = self.projectapi1.compare_vs_database(count=10)
        self.assertTrue(testresult)

    def testcase3(self):
        """手工查询原数据和拼接字串"""
        while True:
            stockcode = input(‘输入股票代码: ‘)
            if stockcode.isdigit() and len(stockcode)==6 and stockcode[:2] in (‘00‘,‘60‘,‘30‘):
                print(‘数据请求中.....‘)
                print(self.projectapi1.api_quote(stockcode))
                print(self.projectapi1.api_finance(stockcode))
                print(self.projectapi1.api_querystockdetailinfo(stockcode))
                print(self.projectapi1.result_of_3sourceapi(stockcode))
            else:
                print(‘股票代码有误‘)

原文地址:https://www.cnblogs.com/dinghanhua/p/10376705.html

时间: 2024-10-06 20:09:53

python接口测试-项目实践(八)的相关文章

python计算机视觉项目实践 答案

有问题的找我哈,转载标明出处http://blog.csdn.net/ikerpeng/article/details/25027567 里面具体的图没有贴了,原理还是比较好理解的.需要的找我! 基于朴素贝叶斯的图片分类 摘要 图片分类问题是计算机视觉中比较常见的问题.图片分类在日常的生活中,以及图片搜索中等方面都有很多很实际的用途.如何准确快速有效的进行图片分类,提高图片分类的准确率和召回率是现在主要要解决的问题.因此一个好的分类学习的算法以及一个好的特征提取的方式是非常重要的.本文所采取的学

python计算机视觉项目实践

这是一个贝叶斯模型的计算机视觉小项目.希望大家通过这个简单的项目知道一般的计算机视觉项目是怎样操作的. 我先讲题目放在这里希望有兴趣的童鞋花一周的时间思考并用python实现.一周以后我来发布我的详细操作细节和代码. 希望大家能够通过这个简单的项目将自己学到的机器学习以及计算机视觉的知识应用到实践其中. 基于OpenCV编写一个基于朴素贝叶斯的图片分类分类程序 要求: [1] 在google的图片搜索引擎中输入"flower"和"airplane",分别下载m(&g

用 Vim 写 Python 的最佳实践

先来晒个图: 对于一些 Python 的小项目,使用 vim 是一个不错的选择.本文内容整理自我在知乎的回答 用用 Vim 写 Python 的最佳实践是什么?,下面的内容是对知乎旧有回答的一个补充,尤其有一些主要针对 vim8. 如果想要更多内容,可以查看知乎对于该问题的一些回答. 语法检查 如果用 vim8, 那么可以用异步检测的 w0rp/ale 代替 syntastic 了,再也不用羡慕 flycheck, 也不用因为语法检查而卡顿了. 关于 ale 这部分的个性化配置,其实有点 "吹毛

LVS (Linux Virtual Server)集群项目实践

LVS (LinuxVirtual Server)集群项目实践 实验目的:通过实验可以熟练规划和配置集群项目 实验环境:Red Hat Enterprise Linux Server release 6.4 实验前提:请确保实验前看过 LVS 中文站点 实验说明:本实验只是以实现负载均衡为目标,并没有考虑如共享存储等,这方面问题在以后的实验中 会添加. 实验步骤: 一.LVS 系统模型 二.LVS 调度算法 三.负载平衡方法 四.常用术语介绍 五.NAT 方式架设 六.DR方式架设 一.LVS

MVC项目实践,在三层架构下实现SportsStore-08,部署到IIS服务器

SportsStore是<精通ASP.NET MVC3框架(第三版)>中演示的MVC项目,在该项目中涵盖了MVC的众多方面,包括:使用DI容器.URL优化.导航.分页.购物车.订单.产品管理.图像上传......是不错的MVC实践项目,但该项目不是放在多层框架下开发的,离真实项目还有一段距离.本系列将尝试在多层框架下实现SportsStore项目,并用自己的方式实现一些功能. 本篇为系列第八篇,包括: ■ 10.部署到IIS服务器    □ 10.1 使用Visual Studio发布   

《Python机器学习及实践:从零开始通往Kaggle竞赛之路》

<Python 机器学习及实践–从零开始通往kaggle竞赛之路>很基础 主要介绍了Scikit-learn,顺带介绍了pandas.numpy.matplotlib.scipy. 本书代码基于python2.x.不过大部分可以通过修改print()来适应python3.5.x. 提供的代码默认使用 Jupyter Notebook,建议安装Anaconda3. 最好是到https://www.kaggle.com注册账号后,运行下第四章的代码,感受下. 监督学习: 2.1.1分类学习(Cla

Django项目实践4 - Django网站管理(后台管理员)

http://blog.csdn.net/pipisorry/article/details/45079751 上篇:Django项目实践3 - Django模型 Introduction 对于某一类站点, 管理界面 是基础设施中很重要的一部分. 这是以网页和有限的可信任管理者为基础的界面,它能够让你加入,编辑和删除站点内容. 常见的样例: 你能够用这个界面公布博客,后台的站点管理者用它来润色读者提交的内容,你的客户用你给他们建立的界面工具更新新闻并公布在站点上.这些都是使用管理界面的样例. 创

Django项目实践2 - Django模板

http://blog.csdn.net/pipisorry/article/details/45061511 上篇:Django项目实践1 - 创建Django项目 Django模板 {视图和模板对逻辑和显示进行了分隔} 上面是使用 django.http.HttpResponse() 来输出"Hello World!".该方式将数据与视图混合在一起,不符合Django的MVC思想.或者HTML被直接硬编码在 Python 代码之中. html = "<html>

Django项目实践3 - Django模型

http://blog.csdn.net/pipisorry/article/details/45061579 上篇:Django项目实践2 - Django模板 Django 模型 {数据和逻辑能够彻底地分开} Django 对各种数据库提供了很好的支持,包括:PostgreSQL.MySQL.SQLite.Oracle.Django 为这些数据库提供了统一的调用API. 1.在 Django 中使用 MySQL MySQL 是 Web 应用中最常用的数据库.下面将以 Mysql 作为实例进行