[
  {
    "path": ".gitignore",
    "content": ".idea"
  },
  {
    "path": "Base/BaseElementEnmu.py",
    "content": "import os\n\nPATH = lambda p: os.path.abspath(\n    os.path.join(os.path.dirname(__file__), p)\n)\n\n\nclass Element(object):\n    INFO_FILE = PATH(\"../Log/info.pickle\") # 记录结果\n    REPORT_FILE = PATH(\"../Report/Report.xlsx\") # 测试报告\n    API_FILE = PATH(\"../Report/api.xlsx\") # 用例文件\n    PICT_PARAM = PATH(\"../Log/param.txt\") # 写入pict需要的参数\n    PICT_PARAM_RESULT = PATH(\"../Log/param_result.txt\") # pict生成后的数据\n    OPEN_PICT = PATH(\"../Setting/Config.ini\") # 打开pict配置器\n\n    ERROR_EMPTY = \"error_empty\"\n    ERROR_VALUE = \"error_value\""
  },
  {
    "path": "Base/BaseEmail.py",
    "content": "# -*- coding: utf-8 -*-\nfrom email.header import Header\nfrom email.mime.text import MIMEText\nfrom email.utils import parseaddr, formataddr\nfrom email.mime.multipart import MIMEMultipart\nfrom email.mime.application import MIMEApplication\nimport smtplib\nimport os\nPATH = lambda p: os.path.abspath(\n    os.path.join(os.path.dirname(__file__), p)\n)\ndef _format_addr(s):\n    name, addr = parseaddr(s)\n    return formataddr((Header(name, 'utf-8').encode(), addr))\ndef send_mail(**kwargs):\n    '''\n    :param f: 附件路径\n    :param to_addr:发给的人 []\n    :return:\n    '''\n    from_addr = kwargs[\"mail_user\"]\n    password = kwargs[\"mail_pass\"]\n    # to_addr = \"ashikun@126.com\"\n    smtp_server = kwargs[\"mail_host\"]\n\n    msg = MIMEMultipart()\n\n    # msg = MIMEText('hello, send by Python...', 'plain', 'utf-8')\n    msg['From'] = _format_addr('来自<%s>接口测试' % from_addr)\n    msg['To'] = _format_addr(' <%s>' % kwargs[\"to_addr\"])\n    msg['Subject'] = Header(kwargs[\"header_msg\"], 'utf-8').encode()\n    msg.attach(MIMEText(kwargs[\"attach\"], 'plain', 'utf-8'))\n\n    if kwargs.get(\"report\", \"0\") != \"0\":\n        part = MIMEApplication(open(kwargs[\"report\"], 'rb').read())\n        part.add_header('Content-Disposition', 'attachment', filename=('gb2312', '', kwargs[\"report_name\"]))\n        msg.attach(part)\n\n    server = smtplib.SMTP_SSL(smtp_server, kwargs[\"port\"])\n    server.set_debuglevel(1)\n    server.login(from_addr, password)\n    server.sendmail(from_addr, kwargs[\"to_addr\"], msg.as_string())\n    server.quit()\nif __name__ == '__main__':\n    to_addr = [\"284772894@qq.com\"]\n    mail_host = \"smtp.qq.com\"\n    mail_user = \"284772894@qq.com\"\n    mail_pass = \"oftllbhnknegbjhb\"\n    port = \"465\"\n    header_msg = \"接口测试\"\n    attach = \"接口测试\"\n    report = PATH(\"../Log/report.xlsx\")\n    send_mail(to_addr = to_addr, mail_host = mail_host, mail_user=mail_user, port=port, mail_pass=mail_pass, header_msg=header_msg, report=report, attach=attach, report_name=\"接口测试报告\")\n"
  },
  {
    "path": "Base/BaseExcel.py",
    "content": "__author__ = 'shikun'\nimport xlsxwriter\nimport os\n\nPATH = lambda p: os.path.abspath(\n    os.path.join(os.path.dirname(__file__), p)\n)\n\n\nclass OperateReport:\n    def __init__(self, wd):\n        self.wd = wd\n\n    def detail(self, worksheet, info):\n        # 设置列行的宽高\n        worksheet.set_column(\"A:A\", 30)\n        worksheet.set_column(\"B:B\", 20)\n        worksheet.set_column(\"C:C\", 20)\n        worksheet.set_column(\"D:D\", 20)\n        worksheet.set_column(\"E:E\", 20)\n        worksheet.set_column(\"F:F\", 20)\n        worksheet.set_column(\"G:G\", 20)\n        worksheet.set_column(\"H:H\", 20)\n\n        worksheet.set_row(1, 30)\n        worksheet.set_row(2, 30)\n        worksheet.set_row(3, 30)\n        worksheet.set_row(4, 30)\n        worksheet.set_row(5, 30)\n        worksheet.set_row(6, 30)\n        worksheet.set_row(7, 30)\n        worksheet.set_row(8, 30)\n\n        worksheet.merge_range('A1:H1', '测试详情', get_format(self.wd, {'bold': True, 'font_size': 18, 'align': 'center',\n                                                                    'valign': 'vcenter', 'bg_color': 'blue',\n                                                                    'font_color': '#ffffff'}))\n        _write_center(worksheet, \"A2\", '请求', self.wd)\n        _write_center(worksheet, \"B2\", '方法', self.wd)\n        _write_center(worksheet, \"C2\", '请求参数', self.wd)\n        _write_center(worksheet, \"D2\", '请求说明', self.wd)\n        _write_center(worksheet, \"E2\", '期望值', self.wd)\n        _write_center(worksheet, \"F2\", '响应码 ', self.wd)\n        _write_center(worksheet, \"G2\", '实际结果 ', self.wd)\n        _write_center(worksheet, \"H2\", '是否通过 ', self.wd)\n\n        temp = 3\n        for item in info:\n            # print(item)\n            _write_center(worksheet, \"A\" + str(temp), item[\"url\"], self.wd)\n            _write_center(worksheet, \"B\" + str(temp), item[\"method\"], self.wd)\n            _write_center(worksheet, \"C\" + str(temp), item[\"params\"], self.wd)\n            _write_center(worksheet, \"D\" + str(temp), item[\"msg\"], self.wd)\n            _write_center(worksheet, \"E\" + str(temp), item[\"hope\"], self.wd)\n            _write_center(worksheet, \"F\" + str(temp), item[\"code\"], self.wd)\n            _write_center(worksheet, \"G\" + str(temp), item[\"res\"], self.wd)\n            _write_center(worksheet, \"H\" + str(temp), item[\"result\"], self.wd)\n\n            temp += 1\n\n    def close(self):\n        self.wd.close()\n\n\ndef get_format(wd, option={}):\n    return wd.add_format(option)\n\n\n# def link_format(wd):\n#     red_format = wd.add_format({\n#         'font_color': 'red',\n#         'bold': 1,\n#         'underline': 1,\n#         'font_size': 12,\n#     })\ndef get_format_center(wd, num=1):\n    return wd.add_format({'align': 'center', 'valign': 'vcenter', 'border': num})\n\n\ndef set_border_(wd, num=1):\n    return wd.add_format({}).set_border(num)\n\n\ndef _write_center(worksheet, cl, data, wd):\n    return worksheet.write(cl, data, get_format_center(wd))\n\n\ndef set_row(worksheet, num, height):\n    worksheet.set_row(num, height)\n\n    # 生成饼形图\n\n\ndef pie(workbook, worksheet):\n    chart1 = workbook.add_chart({'type': 'pie'})\n    chart1.add_series({\n        'name': '自动化测试统计',\n        'categories': '=测试总况!$C$4:$C$5',\n        'values': '=测试总况!$D$4:$D$5',\n    })\n    chart1.set_title({'name': '测试统计'})\n    chart1.set_style(10)\n    worksheet.insert_chart('A9', chart1, {'x_offset': 25, 'y_offset': 10})\n\n\nif __name__ == '__main__':\n    sum = {'testSumDate': '25秒', 'sum': 10, 'pass': 5, 'testDate': '2017-06-05 15:26:49', 'fail': 5,\n           'appVersion': '17051515', 'appSize': '14M', 'appName': \"'简书'\"}\n    info = [{\"id\": 1, \"title\": \"第一次打开\", \"caseName\": \"testf01\", \"result\": \"通过\", \"phoneName\": \"三星\"},\n            {\"id\": 1, \"title\": \"第一次打开\",\n             \"caseName\": \"testf01\", \"result\": \"通过\", \"img\": \"d:\\\\1.PNG\", \"phoneName\": \"华为\"}]\n    workbook = xlsxwriter.Workbook('Report.xlsx')\n    worksheet = workbook.add_worksheet(\"测试总况\")\n    worksheet2 = workbook.add_worksheet(\"测试详情\")\n    bc = OperateReport(wd=workbook)\n    bc.init(worksheet, sum)\n    bc.detail(worksheet2, info)\n    bc.close()\n    #\n"
  },
  {
    "path": "Base/BaseFile.py",
    "content": "import os\nimport time\n\nPATH = lambda p: os.path.abspath(\n    os.path.join(os.path.dirname(__file__), p)\n)\n'''\n操作文件\n'''\n\n\nclass BaseFile(object):\n    def __init__(self):\n        pass\n\n    def check_file(self, path):\n        if not os.path.isfile(path):\n            # sys.exit()\n            return False\n        else:\n            return True\n\n    def mk_file(self, path):\n        with open(path, 'w', encoding=\"utf-8\") as f:\n            print(\"创建文件成功\")\n            pass\n\n    def write(self, path, line):\n        time.sleep(1)\n        with open(path, 'a') as fileHandle:\n            fileHandle.write(line + \"\\n\")\n\n    def read(self, path):\n        result = []\n        with open(path, 'r', encoding=\"utf-8\") as fileHandle:\n            file_list = fileHandle.readlines()\n            for i in file_list:\n                temp = [i.replace(\"\\t\", \",\").strip(\"\\n\")]\n                result.append(temp)\n        return result\n\n    def remove_file(self, path):\n        if self.check_file(path):\n            os.remove(path)\n\n\nif __name__ == '__main__':\n    pass\n"
  },
  {
    "path": "Base/BaseGetExcel.py",
    "content": "import xlrd\nimport xlsxwriter\nfrom Base.BaseElementEnmu import Element\nfrom Base.BaseExcel import *\nfrom Base.BaseStatistics import readInfo\n\n\ndef read_excel(file='c:/test.xls'):\n    data = xlrd.open_workbook(file)\n    table = data.sheet_by_index(0)\n    nrows = table.nrows\n    ncols = table.ncols\n    colnames = table.row_values(0)  # one rows data\n    list = []\n    for rownum in range(1, nrows):\n        row = table.row_values(rownum)\n        if row:\n            app = {}\n            for i in range(len(colnames)):\n                # row[i] = colnames[i] + row[i]\n                app[colnames[i]] = row[i]\n            list.append(app)\n    return list\n\n\ndef write_excel():\n    workbook = xlsxwriter.Workbook(Element.REPORT_FILE)\n    worksheet2 = workbook.add_worksheet(\"测试详情\")\n    operateReport = OperateReport(workbook)\n    operateReport.detail(worksheet2, readInfo(Element.INFO_FILE))\n    operateReport.close()\n\nif __name__ == \"__main__\":\n    t = read_excel(Element.API_FILE)\n    print(t)"
  },
  {
    "path": "Base/BaseIni.py",
    "content": "import configparser\n\n'''\n对ini文件的读写改\n'''\n\n\nclass BaseIni(object):\n    def __init__(self, path):\n        self.cfg = configparser.ConfigParser()\n        self.cfg.read(path)\n\n    def read_ini(self):\n        _pict = self.cfg.get(\"default\", \"pict\")\n        return True if _pict.lower() == 'true' else False\n\n    def __write_ini(self):\n        self.cfg.add_section(\"default1\")\n        self.cfg.set(\"default1\", \"title\", \"test msg\")\n        self.cfg.set(\"default1\", \"id\", \"test msg\")\n        self.cfg.add_section(\"ematter\")\n        self.cfg.set(\"ematter\", \"pages\", 250)\n        self.cfg.write(open('1.ini', \"w\"))\n\n    def __edit_ini(self):\n        self.cfg.set(\"default\", \"pict\", \"True\")\n        self.cfg.write(open('1.ini', \"r+\"))\n\nif __name__ == \"__main__\":\n    from Base.BaseElementEnmu import Element\n    t = BaseIni(Element.OPEN_PICT).read_ini()\n    print(t)"
  },
  {
    "path": "Base/BaseInit.py",
    "content": "from Base.BaseFile import BaseFile\nfrom Base.BaseElementEnmu import Element\n\n\nclass BaseInit(object):\n    def __init__(self):\n        self.bf = BaseFile()\n\n    def mk_file(self):\n        self.__destroy()\n        self.bf.mk_file(Element.INFO_FILE)\n\n    def __destroy(self):\n        self.bf.remove_file(Element.INFO_FILE)\n"
  },
  {
    "path": "Base/BaseParams.py",
    "content": "import uuid\nfrom allpairspy import AllPairs\n# pip install allpairspy\n\nfrom collections import OrderedDict\n\n\nclass BaseFuzzParams(object):\n    \"\"\" 设置接口的逆向参数\n        自动生成模糊接口参数第一步，提前准备逆向场景\n        Args:\n            d: dict类型，正向接口参数\n        Returns:\n           dict\n        Raises:\n           无\n        \"\"\"\n\n    def __get_data(self, d):\n        data = {}\n        for i in d:\n            data[i] = []\n            #  加入一般规则\n            data[i].append({\"info\": \"正确的值\", \"code\": 1, \"value\": d[i], \"key\": i})\n            data[i].append({\"info\": \"为空\", \"code\": -1, \"value\": \"\", \"key\": i})\n            data[i].append({\"info\": \"错误的值\", \"code\": -2, \"value\": self.__param_format(type(d[i])), \"key\": i})\n            data[i].append({\"info\": \"删除\", \"code\": -3, \"key\": i})\n        # 加入其它规则：如路径遍历，xss，注入\n        return data\n\n    '''\n    生成逆向场景参数\n    '''\n\n    def __param_format(self, key):\n        if key == str:\n            return str(uuid.uuid1())\n        elif key == int:\n            return 963852 # 也可以使用随机整数的方式\n        elif key == list:\n            return [str(uuid.uuid1())]\n        elif key == dict:\n            return {}\n        elif key == \"inject\":\n            return \"t'exec master..xp_cmdshell 'nslookup www.google.com'--\"\n        # 路径遍历\n        elif key == \"path_traversal\":\n            pass\n        else:\n            return \"null\"\n\n    '''\n    得到逆向场景参数后，用AllPairs生成全对偶参数\n    '''\n\n    def __set_fuzz(self, d):\n        data = []\n        for i, par in enumerate(AllPairs(OrderedDict(d))):\n            app = []\n            for j in par:\n                app.append(j)\n            data.append(app)\n\n        dd = []\n        for i in data:\n            d = []\n            for j in range(len(i)):\n                d.append(i[j])\n            dd.append(d)\n\n        d2 = []\n        for i in dd:\n            d1 = []\n            for j in i:\n                app = {}\n                if j.get(\"code\", -9) == -1:\n                    app[j[\"key\"]] = \"\"\n                elif j.get(\"code\", -9) == -3:\n                    pass\n                else:\n                    app[j[\"key\"]] = j[\"value\"]\n                app[\"info\"] = j[\"key\"] + j[\"info\"]\n                d1.append(app)\n            d2.append(d1)\n        return d2\n    '''\n    对外的函数，处理生成的对偶场景接口参数\n     Returns:\n           [{},{}]\n    '''\n    def param_fi(self, d):\n        g_data = self.__get_data(d)\n        s_fuzz = self.__set_fuzz(g_data)\n        data = []\n        for i in s_fuzz:\n            for j in range(len(i)):\n                _info = \"\"\n                for k in range(len(i)):\n                    _info = _info + \",\" + i[k][\"info\"]\n                    i[0].update(i[k])\n                i[0][\"info\"] = _info.strip(\",\")\n                data.append(i[0])\n                break\n        return data\nif __name__ == \"__main__\":\n    fz = BaseFuzzParams().param_fi({\"user\": \"name\", \"id\": 1001, \"pwd\": \"!@#$^&*\", \"data\": {\"test\": \"hello\"}, \"my_list\":[\"1\", \"2\"]})\n    print(fz)"
  },
  {
    "path": "Base/BaseReq.py",
    "content": "import requests\nimport json\nimport ast\nfrom Base.BaseElementEnmu import Element\nfrom Base.BaseParams import  BaseFuzzParams\nfrom Base.BaseStatistics import writeInfo\n\nclass Config(object):\n    def __init__(self):\n        pass\n\n    def config_req(self, kw):\n        app = {}\n        header = {\"Accept\": \"*/*\", \"Content-Type\": \"application/json;charset=utf-8\"}\n        for item in kw:\n            url = \"%s://%s\" % (item[\"protocol\"], item[\"url\"])\n            print(\"==请求url:%s\" % url)\n            print(\"==请求参数:%s\" % item[\"params\"])\n            params = \"{}\"\n            if item.get(\"params\"):\n                params = item[\"params\"]\n            if item[\"method\"] == \"get\":\n                res = requests.get(url, data=json.dumps(ast.literal_eval(params)), headers=header, verify=False)\n            elif item[\"method\"] == \"post\":\n                res = requests.post(url, data=json.dumps(ast.literal_eval(params)), headers=header, verify=False)\n            else:\n                print(\"现在只针post和ge方法进行了测试，其他方法请自行扩展\")\n            app[\"url\"] = item[\"url\"]\n            app[\"method\"] = item[\"method\"]\n            app[\"params\"] = item[\"params\"]\n            app[\"code\"] = str(res.status_code)\n            app[\"msg\"] = item[\"mark\"]\n            app[\"hope\"] = item.get(\"hope\", \"\")\n            app[\"res\"] = str(res.text)\n            print(\"==响应结果=:%s=\" % app[\"res\"])\n            app[\"ress\"] = res  # 传给检查函数进行解析\n\n            app[\"result\"] = self.__check(app[\"hope\"], app[\"ress\"])\n            print(\"==响应码=:%s=\" % app[\"code\"])\n\n            writeInfo(app, Element.INFO_FILE)\n\n    def config_req_pict(self, kw, req=None):\n        app = {}\n        header = {\"Accept\": \"*/*\", \"Content-Type\": \"application/json;charset=utf-8\"}\n        for item in kw:\n            url = \"%s://%s\" % (item[\"protocol\"], item[\"url\"])\n            # 如果有参数才做模糊测试，没有做正向场景测试\n            if item.get(\"params\"):\n                print(\"进行逆向场景测试\")\n                params = BaseFuzzParams().param_fi(ast.literal_eval(item[\"params\"]))\n                for i in params:\n                    _info = \"\"\n                    if i.get(\"info\", \"null\") != \"null\":\n                        _info = i.get(\"info\", \"参数正确\")\n                        i.pop(\"info\")\n                    if item[\"method\"] == \"get\":\n                        res = requests.get(url, data=json.dumps(i), headers=header)\n                    else:\n                        res = requests.post(url, data=json.dumps(i), headers=header)\n                    app[\"url\"] = item[\"url\"]\n                    app[\"method\"] = item[\"method\"]\n                    app[\"params\"] = str(i)\n                    app[\"code\"] = str(res.status_code)\n                    app[\"msg\"] = item[\"mark\"] + \"_\" + _info\n                    # app[\"hope\"] = item.get(\"hope\", \"\")\n                    app[\"hope\"] = \"\"\n                    app[\"res\"] = str(res.text)\n                    app[\"result\"] = \"\"\n                    print(\"请求url:%s\" % url)\n                    print(\"请求参数:%s\" % app[\"params\"])\n                    print(\"响应码:%s\" % app[\"code\"])\n                    print(\"响应结果:%s\" % app[\"res\"])\n                    writeInfo(app, Element.INFO_FILE)\n                else:\n\n                    self.config_req(kw)\n    def __check(self, hope, res):\n        resp = json.dumps(json.loads(res.text), separators=(',', ':'))\n        is_check = 0  # 0表示期望值不存在，没有进行检查;1成功;-1失败\n        hopes = hope.split(\"|\")\n        if len(hopes) and len(hope):\n            is_check = 1\n            # 循环检查期望值是否在实际值中能找到\n            for j in hopes:\n                if resp.find(j) == -1:\n                    is_check = -1\n                    break\n        if is_check == 0:\n            return \"未检查\"\n        elif is_check == 1:\n            return \"成功\"\n        else:\n            return \"失败\"\n"
  },
  {
    "path": "Base/BaseReq1.py",
    "content": "import requests\nimport json\nimport ast\nfrom Base.BaseElementEnmu import Element\nfrom Base.BaseParams import BaseFuzzParams\nfrom Base.BaseStatistics import writeInfo\n\nclass Config(object):\n    def __init__(self, sessions):\n        self.sessions = sessions\n\n    def config_req(self, kw):\n        app = {}\n        header = {\"Accept\": \"*/*\", \"Content-Type\": \"application/json;charset=utf-8\"}\n        for item in kw:\n            url = \"%s://%s\" % (item[\"protocol\"], item[\"url\"])\n            print(\"==请求url:%s\" % url)\n            print(\"==请求参数:%s\" % item[\"params\"])\n            params = \"{}\"\n            if item.get(\"params\"):\n                params = item.get(\"params\")\n            if item[\"method\"] == \"get\":\n                res = self.sessions.get(url, data=json.dumps(ast.literal_eval(params)), headers=header, verify=False)\n            elif item[\"method\"] == \"post\":\n                res = self.sessions.post(url, data=json.dumps(ast.literal_eval(params)), headers=header, verify=False)\n            else:\n                print(\"现在只针post和ge方法进行了测试，其他方法请自行扩展\")\n            app[\"url\"] = item[\"url\"]\n            app[\"method\"] = item[\"method\"]\n            app[\"params\"] = item[\"params\"]\n            app[\"code\"] = str(res.status_code)\n            app[\"msg\"] = item[\"mark\"]\n            app[\"hope\"] = item.get(\"hope\", \"\")\n            app[\"res\"] = str(res.text)\n            app[\"ress\"] = res # 传给检查函数进行解析\n            print(\"==响应结果:%s=\" % app[\"res\"])\n\n            app[\"result\"] = self.__check(app[\"hope\"], app[\"ress\"])\n            print(\"==响应码:%s=\" % app[\"code\"])\n\n            writeInfo(app, Element.INFO_FILE)\n\n    def config_req_pict(self, kw, req=None):\n        app = {}\n        header = {\"Accept\": \"*/*\", \"Content-Type\": \"application/json;charset=utf-8\"}\n        for item in kw:\n            url = \"%s://%s\" % (item[\"protocol\"], item[\"url\"])\n            # 如果有参数才做模糊测试，没有做正向场景测试\n            if item.get(\"params\"):\n                print(\"进行逆向场景测试\")\n                params = BaseFuzzParams().param_fi(ast.literal_eval(item[\"params\"]))\n                for i in params:\n                    _info = \"\"\n                    if i.get(\"info\", \"null\") != \"null\":\n                        _info = i.get(\"info\", \"参数正确\")\n                        i.pop(\"info\")\n                    if item[\"method\"] == \"get\":\n                        res = self.sessions.get(url, data=json.dumps(i), headers=header)\n                    else:\n                        res = self.sessions.post(url, data=json.dumps(i), headers=header)\n                    app[\"url\"] = item[\"url\"]\n                    app[\"method\"] = item[\"method\"]\n                    app[\"params\"] = str(i)\n                    app[\"code\"] = str(res.status_code)\n                    app[\"msg\"] = item[\"mark\"] + \"_\" + _info\n                    # app[\"hope\"] = item.get(\"hope\", \"\")\n                    app[\"hope\"] = \"\"\n                    app[\"res\"] = str(res.text)\n                    app[\"result\"] = \"\"\n                    print(\"请求url:%s\" % url)\n                    print(\"请求参数:%s\" % app[\"params\"])\n                    print(\"响应码:%s\" % app[\"code\"])\n                    print(\"响应结果:%s\" % app[\"res\"])\n                    writeInfo(app, Element.INFO_FILE)\n                else:\n\n                    self.config_req(kw)\n\n    def __check(self, hope, res):\n        resp = json.dumps(json.loads(res.text), separators=(',', ':'))\n        is_check = 0  # 0表示期望值不存在，没有进行检查;1成功;-1失败\n        hopes = hope.split(\"|\")\n        if len(hopes) and len(hope):\n            is_check = 1\n            # 循环检查期望值是否在实际值中能找到\n            for j in hopes:\n                if resp.find(j) == -1:\n                    is_check = -1\n                    break\n        if is_check == 0:\n            return \"未检查\"\n        elif is_check == 1:\n            return \"成功\"\n        else:\n            return \"失败\"\n"
  },
  {
    "path": "Base/BaseRunner.py",
    "content": "# -*- coding: utf-8 -*-\nimport unittest\n\nimport requests\n\n\n# 登录\ndef get_session():\n    req = requests.session()\n    url = \"\"\n    data = {}\n    req.post(url, data, verify=False)\n    return req\n\n\nclass ParametrizedTestCase(unittest.TestCase):\n    \"\"\" TestCase classes that want to be parametrized should  \n        inherit from this class.  \n    \"\"\"\n\n    def __init__(self, methodName='runTest', param=None):\n        super(ParametrizedTestCase, self).__init__(methodName)\n\n    @classmethod\n    def setUpClass(cls):\n        # cls.rq = get_session() # 登录后的session\n        pass\n\n    @classmethod\n    def tearDownClass(cls):\n        pass\n\n    @staticmethod\n    def parametrize(testcase_klass, param=None):\n        testloader = unittest.TestLoader()\n        testnames = testloader.getTestCaseNames(testcase_klass)\n        suite = unittest.TestSuite()\n        for name in testnames:\n            suite.addTest(testcase_klass(name, param=param))\n        return suite\n"
  },
  {
    "path": "Base/BaseRunner1.py",
    "content": "# -*- coding: utf-8 -*-\nimport unittest\n\nimport requests\n\n\n# 登录\ndef get_session():\n    req = requests.session()\n    url = \"http://127.0.0.1:8000/myapi/login/\"\n    data = {\"username\": \"test1\", \"pwd\": \"1234567\"}\n    req.post(url, data, verify=False)\n    return req\n\n\nclass ParametrizedTestCase(unittest.TestCase):\n    \"\"\" TestCase classes that want to be parametrized should  \n        inherit from this class.  \n    \"\"\"\n\n    def __init__(self, methodName='runTest', param=None):\n        super(ParametrizedTestCase, self).__init__(methodName)\n\n    @classmethod\n    def setUpClass(cls):\n        cls.sessions = get_session() # 登录后的session\n\n    @classmethod\n    def tearDownClass(cls):\n        pass\n\n    @staticmethod\n    def parametrize(testcase_klass, param=None):\n        testloader = unittest.TestLoader()\n        testnames = testloader.getTestCaseNames(testcase_klass)\n        suite = unittest.TestSuite()\n        for name in testnames:\n            suite.addTest(testcase_klass(name, param=param))\n        return suite\n"
  },
  {
    "path": "Base/BaseStatistics.py",
    "content": "import pickle\n\n\ndef readInfo(path):\n    data = []\n    with open(path, 'rb') as f:\n        try:\n            data = pickle.load(f)\n            print(data)\n        except EOFError:\n            data = []\n            # print(\"读取文件错误\")\n    # print(\"------read-------\")\n    # print(data)\n    return data\n\n\ndef writeInfo(kw, path=\"data.pickle\"):\n    \"\"\"\n    :type data: dict\n    \"\"\"\n    data = {\"result\": kw[\"result\"], \"hope\": kw[\"hope\"], \"msg\": kw[\"msg\"], \"url\": kw[\"url\"], \"params\": kw[\"params\"]\n             ,\"code\": kw[\"code\"], \"method\": kw[\"method\"], \"res\": kw['res']}\n    _read = readInfo(path)\n    result = []\n    if _read:\n        _read.append(data)\n        result = _read\n    else:\n        result.append(data)\n    with open(path, 'wb') as f:\n        pickle.dump(result, f)\n"
  },
  {
    "path": "Base/__init__.py",
    "content": ""
  },
  {
    "path": "Log/param.txt",
    "content": ""
  },
  {
    "path": "Log/param_result.txt",
    "content": ""
  },
  {
    "path": "README.md",
    "content": "# Ŀ\npython3Զӿڲ\n\n## \n* Win7 64python 3Pycharm. unittest\n* excel\n* ʼͲԽ\n* pictģ\n\n## ÷\n### ʹģ\n* ȵҪpython3+Ļ\n* άReportĿ¼µapi.xlsxдӿڲ\n* Runner.pystart.bat,python runner.py\n* 鿴ԱReportĿ¼µreport.xlsx\n### ʹģ\n* SettingĿ¼µConfig.iniΪTrue\n* ģֶֻ֧ÿĴɾĳչ\n* ģݲּ֧\n\n\n## \n\n![](img/api.jpg \"api.jpg\")\n\n![ʹģԺĲԱ](img/pict.jpg \"pict.jpg\")\n\n![ûʹģԵĲԱ](img/no_pict.jpg \"no_pict.jpg\")\n\n## \n\n* [˵](channel_log.md)\n"
  },
  {
    "path": "Runner/__init__.py",
    "content": ""
  },
  {
    "path": "Runner/runner.py",
    "content": "# -*- coding:utf-8 -*-\nimport sys\nsys.path.append(\"..\")\nimport unittest\nfrom TestCases.Api import ApiTest\nfrom Base.BaseRunner import ParametrizedTestCase\nfrom Base.BaseGetExcel import write_excel\nfrom Base.BaseInit import BaseInit\n\n\ndef runner_case():\n    BaseInit().mk_file()\n    suite = unittest.TestSuite()\n    suite.addTest(ParametrizedTestCase.parametrize(ApiTest))\n    unittest.TextTestRunner(verbosity=2).run(suite)\n\n\nif __name__ == '__main__':\n    runner_case()\n    write_excel()\n"
  },
  {
    "path": "Runner/runner1.py",
    "content": "# -*- coding:utf-8 -*-\nimport sys\nsys.path.append(\"..\")\nimport unittest\nfrom TestCases.Api1 import ApiTest\nfrom Base.BaseRunner1 import ParametrizedTestCase\nfrom Base.BaseGetExcel import write_excel\nfrom Base.BaseInit import BaseInit\n\n\ndef runner_case():\n    BaseInit().mk_file()\n    suite = unittest.TestSuite()\n    suite.addTest(ParametrizedTestCase.parametrize(ApiTest))\n    unittest.TextTestRunner(verbosity=2).run(suite)\n\n\nif __name__ == '__main__':\n    runner_case()\n    write_excel()\n"
  },
  {
    "path": "Runner/start_test.bat",
    "content": "@ECHO OFF\npython runner.py\nECHO.[ EXIT ] press any key...\n\nPAUSE>nul"
  },
  {
    "path": "Setting/Config.ini",
    "content": "[default]\npict = False"
  },
  {
    "path": "TestCases/Api.py",
    "content": "from Base.BaseRunner import ParametrizedTestCase\nfrom Base.BaseGetExcel import read_excel\nfrom Base.BaseReq import Config\nfrom Base.BaseElementEnmu import Element\nfrom Base.BaseIni import BaseIni\n\n\nclass ApiTest(ParametrizedTestCase):\n    def test_api(self):\n        ls = read_excel(Element.API_FILE)\n        if BaseIni(Element.OPEN_PICT).read_ini():\n            Config().config_req_pict(ls)\n        else:\n            Config().config_req(ls)\n\n    @classmethod\n    def setUpClass(cls):\n        super(ApiTest, cls).setUpClass()\n        # cls.req\n"
  },
  {
    "path": "TestCases/Api1.py",
    "content": "from Base.BaseRunner1 import ParametrizedTestCase\nfrom Base.BaseGetExcel import read_excel\nfrom Base.BaseReq1 import Config\nfrom Base.BaseElementEnmu import Element\nfrom Base.BaseIni import BaseIni\n\n\nclass ApiTest(ParametrizedTestCase):\n    def test_api(self):\n        ls = read_excel(Element.API_FILE)\n        if BaseIni(Element.OPEN_PICT).read_ini():\n            Config(self.sessions).config_req_pict(ls)\n        else:\n            Config(self.sessions).config_req(ls)\n\n    @classmethod\n    def setUpClass(cls):\n        super(ApiTest, cls).setUpClass()\n"
  },
  {
    "path": "TestCases/__init__.py",
    "content": ""
  },
  {
    "path": "channel_log.md",
    "content": "# 2021-3-16\n* ģȥpict\n* ½Ľӿʹsession󣬴Ϊrunner1.py\n* api.xlsxļеļ޸ĸʽΪ\n    - ```\"msg\":\"success\"```\n    - ```\"code\":1|\"msg\":\"success\"```\n\n# 2018-6-9\n* ӿڲȫع\n* excel\n* pictģ"
  },
  {
    "path": "requirements.txt",
    "content": "requests==2.24.0\nXlsxWriter==1.3.7\nxlrd==1.2.0\nallpairspy==2.5.0\n"
  }
]