提交 79f09f8362595d2980140f2f9b01ab7fca8ccbf3

作者 Shishutong
0 个父辈

1.0.0

首次提交
  1 +<component name="InspectionProjectProfileManager">
  2 + <profile version="1.0">
  3 + <option name="myName" value="Project Default" />
  4 + <inspection_tool class="DuplicatedCode" enabled="true" level="WEAK WARNING" enabled_by_default="true">
  5 + <Languages>
  6 + <language minSize="71" name="Python" />
  7 + </Languages>
  8 + </inspection_tool>
  9 + <inspection_tool class="PyPackageRequirementsInspection" enabled="true" level="WARNING" enabled_by_default="true">
  10 + <option name="ignoredPackages">
  11 + <value>
  12 + <list size="3">
  13 + <item index="0" class="java.lang.String" itemvalue="greenlet" />
  14 + <item index="1" class="java.lang.String" itemvalue="gevent" />
  15 + <item index="2" class="java.lang.String" itemvalue="grpcio" />
  16 + </list>
  17 + </value>
  18 + </option>
  19 + </inspection_tool>
  20 + <inspection_tool class="PyPep8Inspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
  21 + <option name="ignoredErrors">
  22 + <list>
  23 + <option value="E722" />
  24 + <option value="E401" />
  25 + </list>
  26 + </option>
  27 + </inspection_tool>
  28 + <inspection_tool class="PyPep8NamingInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
  29 + <option name="ignoredErrors">
  30 + <list>
  31 + <option value="N801" />
  32 + <option value="N812" />
  33 + <option value="N802" />
  34 + </list>
  35 + </option>
  36 + </inspection_tool>
  37 + <inspection_tool class="SqlNoDataSourceInspection" enabled="false" level="WARNING" enabled_by_default="false" />
  38 + </profile>
  39 +</component>
  1 +<component name="InspectionProjectProfileManager">
  2 + <settings>
  3 + <option name="USE_PROJECT_PROFILE" value="false" />
  4 + <version value="1.0" />
  5 + </settings>
  6 +</component>
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<project version="4">
  3 + <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.7" project-jdk-type="Python SDK" />
  4 +</project>
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<project version="4">
  3 + <component name="ProjectModuleManager">
  4 + <modules>
  5 + <module fileurl="file://$PROJECT_DIR$/.idea/yxly2.iml" filepath="$PROJECT_DIR$/.idea/yxly2.iml" />
  6 + </modules>
  7 + </component>
  8 +</project>
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<project version="4">
  3 + <component name="VcsDirectoryMappings">
  4 + <mapping directory="$PROJECT_DIR$" vcs="Git" />
  5 + </component>
  6 +</project>
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<project version="4">
  3 + <component name="ChangeListManager">
  4 + <list default="true" id="129454fc-5415-4c7e-9855-d0293355ede5" name="Default Changelist" comment="" />
  5 + <option name="SHOW_DIALOG" value="false" />
  6 + <option name="HIGHLIGHT_CONFLICTS" value="true" />
  7 + <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
  8 + <option name="LAST_RESOLUTION" value="IGNORE" />
  9 + </component>
  10 + <component name="Git.Settings">
  11 + <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
  12 + </component>
  13 + <component name="ProjectId" id="2JBEfy52aMOyfW2DArYYq85RkdC" />
  14 + <component name="ProjectLevelVcsManager" settingsEditedManually="true" />
  15 + <component name="ProjectViewState">
  16 + <option name="hideEmptyMiddlePackages" value="true" />
  17 + <option name="showLibraryContents" value="true" />
  18 + </component>
  19 + <component name="PropertiesComponent">
  20 + <property name="RunOnceActivity.OpenProjectViewOnStart" value="true" />
  21 + <property name="RunOnceActivity.ShowReadmeOnStart" value="true" />
  22 + <property name="WebServerToolWindowFactoryState" value="false" />
  23 + <property name="last_opened_file_path" value="$PROJECT_DIR$" />
  24 + </component>
  25 + <component name="RunManager">
  26 + <configuration name="run" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
  27 + <module name="yxly2" />
  28 + <option name="INTERPRETER_OPTIONS" value="" />
  29 + <option name="PARENT_ENVS" value="true" />
  30 + <envs>
  31 + <env name="PYTHONUNBUFFERED" value="1" />
  32 + </envs>
  33 + <option name="SDK_HOME" value="" />
  34 + <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
  35 + <option name="IS_MODULE_SDK" value="true" />
  36 + <option name="ADD_CONTENT_ROOTS" value="true" />
  37 + <option name="ADD_SOURCE_ROOTS" value="true" />
  38 + <EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
  39 + <option name="SCRIPT_NAME" value="$PROJECT_DIR$/run.py" />
  40 + <option name="PARAMETERS" value="" />
  41 + <option name="SHOW_COMMAND_LINE" value="false" />
  42 + <option name="EMULATE_TERMINAL" value="false" />
  43 + <option name="MODULE_MODE" value="false" />
  44 + <option name="REDIRECT_INPUT" value="false" />
  45 + <option name="INPUT_FILE" value="" />
  46 + <method v="2" />
  47 + </configuration>
  48 + <recent_temporary>
  49 + <list>
  50 + <item itemvalue="Python.run" />
  51 + </list>
  52 + </recent_temporary>
  53 + </component>
  54 + <component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
  55 + <component name="TaskManager">
  56 + <task active="true" id="Default" summary="Default task">
  57 + <changelist id="129454fc-5415-4c7e-9855-d0293355ede5" name="Default Changelist" comment="" />
  58 + <created>1671543182779</created>
  59 + <option name="number" value="Default" />
  60 + <option name="presentableId" value="Default" />
  61 + <updated>1671543182779</updated>
  62 + <workItem from="1671543183922" duration="14000" />
  63 + <workItem from="1671543239346" duration="706000" />
  64 + </task>
  65 + <servers />
  66 + </component>
  67 + <component name="TypeScriptGeneratedFilesManager">
  68 + <option name="version" value="3" />
  69 + </component>
  70 + <component name="Vcs.Log.Tabs.Properties">
  71 + <option name="TAB_STATES">
  72 + <map>
  73 + <entry key="MAIN">
  74 + <value>
  75 + <State />
  76 + </value>
  77 + </entry>
  78 + </map>
  79 + </option>
  80 + </component>
  81 + <component name="com.intellij.coverage.CoverageDataManagerImpl">
  82 + <SUITE FILE_PATH="coverage/yxly$run.coverage" NAME="run Coverage Results" MODIFIED="1671543312825" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
  83 + </component>
  84 +</project>
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<module type="PYTHON_MODULE" version="4">
  3 + <component name="NewModuleRootManager">
  4 + <content url="file://$MODULE_DIR$" />
  5 + <orderEntry type="inheritedJdk" />
  6 + <orderEntry type="sourceFolder" forTests="false" />
  7 + </component>
  8 + <component name="PyDocumentationSettings">
  9 + <option name="format" value="PLAIN" />
  10 + <option name="myDocStringFormat" value="Plain" />
  11 + </component>
  12 + <component name="TestRunnerService">
  13 + <option name="PROJECT_TEST_RUNNER" value="pytest" />
  14 + </component>
  15 +</module>
  1 +#!/usr/bin/env python3
  2 +# -*- coding: utf-8 -*-
  3 +# @Time : 2022/12/9 00:30
  4 +# @Author : Shitou
  5 +# @FileName: handle_config.py
  6 +# @Software: PyCharm
  7 +"""
  8 +封装读取ini文件
  9 +"""
  10 +import os
  11 +from configparser import ConfigParser
  12 +from common.handle_path import Config_Path
  13 +
  14 +
  15 +class Config(ConfigParser):
  16 +
  17 + def __init__(self, filename, encoding='utf-8'):
  18 + super().__init__()
  19 + self.read(filename, encoding=encoding)
  20 +
  21 +
  22 +# 创建一个配置文件解析器
  23 +conf = Config(os.path.join(Config_Path, "config.ini"))
  1 +#!/usr/bin/env python3
  2 +# -*- coding: utf-8 -*-
  3 +# @Time : 2022/12/12 12:05
  4 +# @Author : Shitou
  5 +# @FileName: handle_db.py
  6 +# @Software: PyCharm
  7 +"""
  8 +封装数据库
  9 +"""
  10 +import pymysql
  11 +from common.handle_config import conf
  12 +
  13 +
  14 +class DB:
  15 + def __init__(self, host, port, password, user):
  16 + self.con = pymysql.connect(host=host,
  17 + port=port,
  18 + user=user,
  19 + password=password,
  20 + charset="utf8",
  21 + cursorclass=pymysql.cursors.DictCursor
  22 + )
  23 + # 第二步:创建一个游标对象
  24 + self.cur = self.con.cursor()
  25 +
  26 + def find_data(self, sql):
  27 + """查询数据"""
  28 + # 先提交事物,同步数据库的最新状态self.con.commit(),然后在查询
  29 + self.con.commit()
  30 + self.cur.execute(sql)
  31 + res = self.cur.fetchall()
  32 + return res
  33 +
  34 +
  35 +db = DB(host=conf.get("mysql", "host"),
  36 + port=conf.getint("mysql", "port"), # 端口需要用int类型
  37 + user=conf.get("mysql", "user"),
  38 + password=conf.get("mysql", "password")
  39 + )
  1 +#!/usr/bin/env python3
  2 +# -*- coding: utf-8 -*-
  3 +# @Time : 2022/12/8 21:58
  4 +# @Author : Shitou
  5 +# @FileName: hand_excel.py
  6 +# @Software: PyCharm
  7 +"""
  8 +封装读写excel表格
  9 +
  10 +"""
  11 +import openpyxl
  12 +
  13 +
  14 +class Excel(object):
  15 + def __init__(self, file_name, file_sheet):
  16 + """
  17 + :param file_name: 文件路径
  18 + :param file_sheet: Excel表格sheet页
  19 + """
  20 + self.file_name = file_name
  21 + self.file_sheet = file_sheet
  22 +
  23 + def open_excel(self):
  24 + """打开工作簿"""
  25 +
  26 + self.wb = openpyxl.load_workbook(self.file_name)
  27 + self.sh = self.wb[self.file_sheet]
  28 +
  29 + def read_excel(self):
  30 + """读取excel表格数据"""
  31 + # 打开工作簿
  32 + self.open_excel()
  33 + # 读取表头
  34 + res = list(self.sh.rows)
  35 + title = []
  36 + for i in res[0]:
  37 + title.append(i.value)
  38 + test_case = []
  39 + # 读取非表头
  40 + for item in res[1:]:
  41 + data = []
  42 + for j in item:
  43 + data.append(j.value)
  44 + case = dict(zip(title, data))
  45 + test_case.append(case)
  46 + return test_case
  47 +
  48 + def read_excel_location(self, row_column):
  49 + """读写指定的单元格"""
  50 + self.open_excel()
  51 + # dy = self.sh["A2"].value
  52 + dy = self.sh[row_column].value
  53 + return dy
  54 +
  55 + def write_excel(self, row, column, value):
  56 +
  57 + """Excel表格写入数据"""
  58 + self.open_excel()
  59 + # 获取单元格定位并写入
  60 + self.sh.cell(row=row, column=column, value=value)
  61 + # 保存
  62 + self.wb.save(self.file_name)
  63 +
  64 +
  65 +if __name__ == '__main__':
  66 + a = Excel(r"/demo_08_workai_1/data/system/test_02_department.xlsx",
  67 + 'adddepartment')
  68 + a.read_excel_location("I2")
  1 +# #!/usr/bin/env python3
  2 +# # -*- coding: utf-8 -*-
  3 +# # @Time : 2022/12/8 23:50
  4 +# # @Author : Shitou
  5 +# # @FileName: handle_log.py
  6 +# # @Software: PyCharm
  7 +# """
  8 +# 封装日志
  9 +# """
  10 +import logging
  11 +import os
  12 +from logging.handlers import TimedRotatingFileHandler, RotatingFileHandler
  13 +from common.handle_path import Log_Path
  14 +from common.handle_config import conf
  15 +
  16 +file_path = os.path.join(Log_Path, "log.log")
  17 +
  18 +
  19 +class HandleLog:
  20 +
  21 + def create_logger():
  22 + # 创建日志收集器
  23 + my_log = logging.getLogger('shitou')
  24 +
  25 + # 设置日志收集器等级
  26 + my_log.setLevel(conf.get("logging", "collect"))
  27 + # 设置输出渠道
  28 + # ---输出到控制台
  29 + sh = logging.StreamHandler()
  30 + sh.setLevel(conf.get("logging", "console"))
  31 + my_log.addHandler(sh)
  32 +
  33 + # ---输出到文件根据时间轮转
  34 + fh = TimedRotatingFileHandler(filename=file_path,
  35 + when=conf.get("logging", "time_units"),
  36 + interval=conf.getint("logging", "time"),
  37 + backupCount=conf.getint("logging", "max_quantity"),
  38 + encoding="utf-8")
  39 + # ---输出到文件根据文件大小轮转
  40 + # fh = RotatingFileHandler(filename=file_path,
  41 + # mode='a',
  42 + # maxBytes=502,
  43 + # backupCount=4,
  44 + # encoding="utf-8", )
  45 + fh.setLevel(conf.get("logging", "file"))
  46 + my_log.addHandler(fh)
  47 + # 设置日志输出格式
  48 + formatter = "%(asctime)s - [%(filename)s-->line:%(lineno)d] - %(levelname)s: %(message)s"
  49 + mate = logging.Formatter(formatter)
  50 + sh.setFormatter(mate)
  51 + fh.setFormatter(mate)
  52 + return my_log
  53 + log = create_logger()
  1 +#!/usr/bin/env python3
  2 +# -*- coding: utf-8 -*-
  3 +# @Time : 2022/12/9 00:08
  4 +# @Author : Shitou
  5 +# @FileName: handle_path.py
  6 +# @Software: PyCharm
  7 +"""
  8 +封装获取路径
  9 +"""
  10 +import os
  11 +
  12 +# 项目根目录
  13 +Base_Path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
  14 +# 测试用例的路径
  15 +TestCase_Path = os.path.join(Base_Path, "testcase")
  16 +# 测试报告的路径
  17 +Report_Path = os.path.join(Base_Path, "report")
  18 +# 日志的路径
  19 +Log_Path = os.path.join(Base_Path, "logs")
  20 +# 测试数据的Excel
  21 +DataExcel_Path = os.path.join(Base_Path, "data")
  22 +# 配置文件的路径
  23 +Config_Path = os.path.join(Base_Path, "conf")
  1 +# -*- coding: utf-8 -*-
  2 +# This file is a part of DDT (https://github.com/txels/ddt)
  3 +# Copyright 2012-2015 Carles Barrobés and DDT contributors
  4 +# For the exact contribution history, see the git revision log.
  5 +# DDT is licensed under the MIT License, included in
  6 +# https://github.com/txels/ddt/blob/master/LICENSE.md
  7 +
  8 +import inspect
  9 +import json
  10 +import os
  11 +import re
  12 +import codecs
  13 +from functools import wraps
  14 +
  15 +try:
  16 + import yaml
  17 +except ImportError: # pragma: no cover
  18 + _have_yaml = False
  19 +else:
  20 + _have_yaml = True
  21 +
  22 +__version__ = '1.2.1'
  23 +
  24 +# These attributes will not conflict with any real python attribute
  25 +# They are added to the decorated test method and processed later
  26 +# by the `ddt` class decorator.
  27 +
  28 +DATA_ATTR = '%values' # store the data the test must run with
  29 +FILE_ATTR = '%file_path' # store the path to JSON file
  30 +UNPACK_ATTR = '%unpack' # remember that we have to unpack values
  31 +index_len = 5 # default max length of case index
  32 +
  33 +
  34 +try:
  35 + trivial_types = (type(None), bool, int, float, basestring)
  36 +except NameError:
  37 + trivial_types = (type(None), bool, int, float, str)
  38 +
  39 +
  40 +def is_trivial(value):
  41 + if isinstance(value, trivial_types):
  42 + return True
  43 + elif isinstance(value, (list, tuple)):
  44 + return all(map(is_trivial, value))
  45 + return False
  46 +
  47 +
  48 +def unpack(func):
  49 + """
  50 + Method decorator to add unpack feature.
  51 +
  52 + """
  53 + setattr(func, UNPACK_ATTR, True)
  54 + return func
  55 +
  56 +
  57 +def data(*values):
  58 + """
  59 + Method decorator to add to your test methods.
  60 +
  61 + Should be added to methods of instances of ``unittest.TestCase``.
  62 +
  63 + """
  64 + global index_len
  65 + index_len = len(str(len(values)))
  66 + return idata(values)
  67 +
  68 +
  69 +def idata(iterable):
  70 + """
  71 + Method decorator to add to your test methods.
  72 +
  73 + Should be added to methods of instances of ``unittest.TestCase``.
  74 +
  75 + """
  76 + def wrapper(func):
  77 + setattr(func, DATA_ATTR, iterable)
  78 + return func
  79 + return wrapper
  80 +
  81 +
  82 +def file_data(value):
  83 + """
  84 + Method decorator to add to your test methods.
  85 +
  86 + Should be added to methods of instances of ``unittest.TestCase``.
  87 +
  88 + ``value`` should be a path relative to the directory of the file
  89 + containing the decorated ``unittest.TestCase``. The file
  90 + should contain JSON encoded data, that can either be a list or a
  91 + dict.
  92 +
  93 + In case of a list, each value in the list will correspond to one
  94 + test case, and the value will be concatenated to the test method
  95 + name.
  96 +
  97 + In case of a dict, keys will be used as suffixes to the name of the
  98 + test case, and values will be fed as test data.
  99 +
  100 + """
  101 + def wrapper(func):
  102 + setattr(func, FILE_ATTR, value)
  103 + return func
  104 + return wrapper
  105 +
  106 +
  107 +def mk_test_name(name, value, index=0):
  108 + """
  109 + Generate a new name for a test case.
  110 +
  111 + It will take the original test name and append an ordinal index and a
  112 + string representation of the value, and convert the result into a valid
  113 + python identifier by replacing extraneous characters with ``_``.
  114 +
  115 + We avoid doing str(value) if dealing with non-trivial values.
  116 + The problem is possible different names with different runs, e.g.
  117 + different order of dictionary keys (see PYTHONHASHSEED) or dealing
  118 + with mock objects.
  119 + Trivial scalar values are passed as is.
  120 +
  121 + A "trivial" value is a plain scalar, or a tuple or list consisting
  122 + only of trivial values.
  123 + """
  124 +
  125 + # Add zeros before index to keep order
  126 + index = "{0:0{1}}".format(index + 1, index_len)
  127 + if not is_trivial(value):
  128 + return "{0}_{1}".format(name, index)
  129 + try:
  130 + value = str(value)
  131 + except UnicodeEncodeError:
  132 + # fallback for python2
  133 + value = value.encode('ascii', 'backslashreplace')
  134 + test_name = "{0}_{1}_{2}".format(name, index, value)
  135 + return re.sub(r'\W|^(?=\d)', '_', test_name)
  136 +
  137 +
  138 +def feed_data(func, new_name, test_data_docstring, *args, **kwargs):
  139 + """
  140 + This internal method decorator feeds the test data item to the test.
  141 +
  142 + """
  143 + @wraps(func)
  144 + def wrapper(self):
  145 + return func(self, *args, **kwargs)
  146 + wrapper.__name__ = new_name
  147 + wrapper.__wrapped__ = func
  148 + # set docstring if exists
  149 + if test_data_docstring is not None:
  150 + wrapper.__doc__ = test_data_docstring
  151 + else:
  152 + # Try to call format on the docstring
  153 + if func.__doc__:
  154 + try:
  155 + wrapper.__doc__ = func.__doc__.format(*args, **kwargs)
  156 + except (IndexError, KeyError):
  157 + # Maybe the user has added some of the formating strings
  158 + # unintentionally in the docstring. Do not raise an exception
  159 + # as it could be that user is not aware of the
  160 + # formating feature.
  161 + pass
  162 + return wrapper
  163 +
  164 +
  165 +def add_test(cls, test_name, test_docstring, func, *args, **kwargs):
  166 + """
  167 + Add a test case to this class.
  168 +
  169 + The test will be based on an existing function but will give it a new
  170 + name.
  171 +
  172 + """
  173 + setattr(cls, test_name, feed_data(func, test_name, test_docstring,
  174 + *args, **kwargs))
  175 +
  176 +
  177 +def process_file_data(cls, name, func, file_attr):
  178 + """
  179 + Process the parameter in the `file_data` decorator.
  180 + """
  181 + cls_path = os.path.abspath(inspect.getsourcefile(cls))
  182 + data_file_path = os.path.join(os.path.dirname(cls_path), file_attr)
  183 +
  184 + def create_error_func(message): # pylint: disable-msg=W0613
  185 + def func(*args):
  186 + raise ValueError(message % file_attr)
  187 + return func
  188 +
  189 + # If file does not exist, provide an error function instead
  190 + if not os.path.exists(data_file_path):
  191 + test_name = mk_test_name(name, "error")
  192 + test_docstring = """Error!"""
  193 + add_test(cls, test_name, test_docstring,
  194 + create_error_func("%s does not exist"), None)
  195 + return
  196 +
  197 + _is_yaml_file = data_file_path.endswith((".yml", ".yaml"))
  198 +
  199 + # Don't have YAML but want to use YAML file.
  200 + if _is_yaml_file and not _have_yaml:
  201 + test_name = mk_test_name(name, "error")
  202 + test_docstring = """Error!"""
  203 + add_test(
  204 + cls,
  205 + test_name,
  206 + test_docstring,
  207 + create_error_func("%s is a YAML file, please install PyYAML"),
  208 + None
  209 + )
  210 + return
  211 +
  212 + with codecs.open(data_file_path, 'r', 'utf-8') as f:
  213 + # Load the data from YAML or JSON
  214 + if _is_yaml_file:
  215 + data = yaml.safe_load(f)
  216 + else:
  217 + data = json.load(f)
  218 +
  219 + _add_tests_from_data(cls, name, func, data)
  220 +
  221 +
  222 +def _add_tests_from_data(cls, name, func, data):
  223 + """
  224 + Add tests from data loaded from the data file into the class
  225 + """
  226 + for i, elem in enumerate(data):
  227 + if isinstance(data, dict):
  228 + key, value = elem, data[elem]
  229 + test_name = mk_test_name(name, key, i)
  230 + elif isinstance(data, list):
  231 + value = elem
  232 + test_name = mk_test_name(name, value, i)
  233 + if isinstance(value, dict):
  234 + add_test(cls, test_name, test_name, func, **value)
  235 + else:
  236 + add_test(cls, test_name, test_name, func, value)
  237 +
  238 +
  239 +def _is_primitive(obj):
  240 + """Finds out if the obj is a "primitive". It is somewhat hacky but it works.
  241 + """
  242 + return not hasattr(obj, '__dict__')
  243 +
  244 +
  245 +def _get_test_data_docstring(func, value):
  246 + """Returns a docstring based on the following resolution strategy:
  247 + 1. Passed value is not a "primitive" and has a docstring, then use it.
  248 + 2. In all other cases return None, i.e the test name is used.
  249 + """
  250 + if not _is_primitive(value) and value.__doc__:
  251 + return value.__doc__
  252 + else:
  253 + return None
  254 +
  255 +
  256 +def ddt(cls):
  257 + """
  258 + Class decorator for subclasses of ``unittest.TestCase``.
  259 +
  260 + Apply this decorator to the test case class, and then
  261 + decorate test methods with ``@data``.
  262 +
  263 + For each method decorated with ``@data``, this will effectively create as
  264 + many methods as data items are passed as parameters to ``@data``.
  265 +
  266 + The names of the test methods follow the pattern
  267 + ``original_test_name_{ordinal}_{data}``. ``ordinal`` is the position of the
  268 + data argument, starting with 1.
  269 +
  270 + For data we use a string representation of the data value converted into a
  271 + valid python identifier. If ``data.__name__`` exists, we use that instead.
  272 +
  273 + For each method decorated with ``@file_data('test_data.json')``, the
  274 + decorator will try to load the test_data.json file located relative
  275 + to the python file containing the method that is decorated. It will,
  276 + for each ``test_name`` key create as many methods in the list of values
  277 + from the ``data`` key.
  278 +
  279 + """
  280 + for name, func in list(cls.__dict__.items()):
  281 + if hasattr(func, DATA_ATTR):
  282 + for i, v in enumerate(getattr(func, DATA_ATTR)):
  283 + test_name = mk_test_name(name, getattr(v, "__name__", v), i)
  284 + # 源码
  285 + # test_data_docstring = _get_test_data_docstring(func, v)
  286 + # 修改
  287 + #----start----
  288 + if v.get("title"):
  289 + test_data_docstring =v["title"]
  290 + else:
  291 + test_data_docstring = _get_test_data_docstring(func, v)
  292 + #----end------
  293 +
  294 + if hasattr(func, UNPACK_ATTR):
  295 + if isinstance(v, tuple) or isinstance(v, list):
  296 + add_test(
  297 + cls,
  298 + test_name,
  299 + test_data_docstring,
  300 + func,
  301 + *v
  302 + )
  303 + else:
  304 + # unpack dictionary
  305 + add_test(
  306 + cls,
  307 + test_name,
  308 + test_data_docstring,
  309 + func,
  310 + **v
  311 + )
  312 + else:
  313 + add_test(cls, test_name, test_data_docstring, func, v)
  314 + delattr(cls, name)
  315 + elif hasattr(func, FILE_ATTR):
  316 + file_attr = getattr(func, FILE_ATTR)
  317 + process_file_data(cls, name, func, file_attr)
  318 + delattr(cls, name)
  319 + return cls
  1 +;============================================================================================
  2 +;环境地址
  3 +;============================================================================================
  4 +[url]
  5 +;测试环境
  6 +url_ip = http://47.110.250.177:8000
  7 +login_token = {"Authorization": "Basic"+" "+"d29ya2FpOjEyMzQ1Ng=="}
  8 +
  9 +
  10 +
  11 +;============================================================================================
  12 +;用户数据
  13 +;============================================================================================
  14 +[user_data]
  15 +;账号
  16 +username = 17301249975
  17 +;密码
  18 +userpassword = f85eea0e15e424aba8675f8848e2cb83
  19 +;登录方式
  20 +;手机验证码登录code,
  21 +;微信OpenId登录:wechat,
  22 +;微信Code登录或注册:wecaht_code,
  23 +;用户名登录name,
  24 +;租户登录hr、hro:tenant、
  25 +;third:三方登录、
  26 +;刷新token:refresh_token
  27 +way = name
  28 +;用户类型teacher老师,
  29 +;student学生,
  30 +;company企业,
  31 +;broker经纪人
  32 +type = teacher
  33 +
  34 +
  35 +
  36 +;============================================================================================
  37 +;报告的相关配置
  38 +;============================================================================================
  39 +[report]
  40 +;报告名称
  41 +filename = report.html
  42 +;报告标题
  43 +title = 优学乐业测试报告
  44 +;测试员
  45 +tester = 石头
  46 +;报告描述
  47 +desc = 优学乐业测试报告
  48 +;报告样式
  49 +templates = 1
  50 +
  51 +
  52 +
  53 +
  54 +
  55 +;============================================================================================
  56 +;日志相关的配置
  57 +;============================================================================================
  58 +[logging]
  59 +;日志收集器等级
  60 +collect = DEBUG
  61 +;输出到控制台等级
  62 +console = CRITICAL
  63 +;输出到文件根据时间轮转等级
  64 +file = DEBUG
  65 +;文件轮转时长单位
  66 +time_units = d
  67 +;文件轮转时长
  68 +time = 1
  69 +;文件轮转最大数量
  70 +max_quantity = 10
  71 +
  72 +
  73 +
  74 +
  75 +
  76 +
  77 +
  78 +;============================================================================================
  79 +;数据库相关的配置
  80 +;============================================================================================
  81 +[mysql]
  82 +host = api.lemonban.com
  83 +port = 3306
  84 +user = future
  85 +password = 123456
不能预览此文件类型
不能预览此文件类型
不能预览此文件类型
不能预览此文件类型
  1 +优学乐业
  2 +====
  3 +> 说明:
  4 +>> 语言:python
  5 +>>
  6 +>>测试框架:unittest
  7 +>>
  8 +>>请求接口:requests(http请求)
  9 +>>
  10 +>>数据驱动:ddt
  11 +>>
  12 +>>数据管理:Excel文件,openpyxl操作读写
  13 +>>
  14 +>>数据库交互:pymysql
  15 +>>
  16 +>>生成测试报告:HTMLTestRunnerNew / unittestreports
  17 +>>
  18 +>>日志处理:logging
  19 +>>
  20 +>>持续集成:定时任务Jenkins
  21 +
  22 +common: 封装的公方法
  23 +----------
  24 +conf: 配置文件
  25 +----------
  26 +data: 存放Excel表格的用例数据
  27 +----------
  28 +logs: 日志
  29 +----------
  30 +report: 测试报告
  31 +----------
  32 +testcase:测试用例
  33 +----------
  34 +
  35 +#### 一.test_01_login.py: 登陆用例
  36 +
  37 +> 登陆成功/失败
  38 +
  39 +#### 二.test_02_system_management.py: 系统管理用例
  40 +
  41 +> 1.院系专业
  42 +>
  43 +> 2.校历设置
  44 +>
  45 +> 3.签章管理
  46 +>
  47 +> 4.模版库
  48 +>
  49 +tools:工具
  50 +----------
  51 +
  52 +run.py:运行文件
  53 +----------
  54 +
  55 +
此 diff 太大无法显示。
此 diff 太大无法显示。
  1 +[{"success": 9, "all": 24, "fail": 15, "skip": 0, "error": 0, "runtime": "12.67 S", "begin_time": "2022-12-19 17:56:09", "pass_rate": "37.50"}, {"success": 9, "all": 24, "fail": 15, "skip": 0, "error": 0, "runtime": "7.87 S", "begin_time": "2022-12-19 17:58:06", "pass_rate": "37.50"}, {"success": 9, "all": 24, "fail": 15, "skip": 0, "error": 0, "runtime": "7.24 S", "begin_time": "2022-12-19 18:17:28", "pass_rate": "37.50"}, {"success": 9, "all": 24, "fail": 15, "skip": 0, "error": 0, "runtime": "7.45 S", "begin_time": "2022-12-19 18:19:47", "pass_rate": "37.50"}, {"success": 9, "all": 24, "fail": 15, "skip": 0, "error": 0, "runtime": "7.72 S", "begin_time": "2022-12-19 19:32:22", "pass_rate": "37.50"}, {"success": 9, "all": 24, "fail": 15, "skip": 0, "error": 0, "runtime": "103.32 S", "begin_time": "2022-12-19 20:35:55", "pass_rate": "37.50"}, {"success": 9, "all": 24, "fail": 15, "skip": 0, "error": 0, "runtime": "6.95 S", "begin_time": "2022-12-20 12:06:06", "pass_rate": "37.50"}, {"success": 9, "all": 24, "fail": 15, "skip": 0, "error": 0, "runtime": "6.92 S", "begin_time": "2022-12-20 21:34:11", "pass_rate": "37.50"}, {"success": 9, "all": 24, "fail": 15, "skip": 0, "error": 0, "runtime": "6.77 S", "begin_time": "2022-12-20 21:35:13", "pass_rate": "37.50"}]
  1 +<!DOCTYPE html>
  2 +<html lang="en">
  3 +<head>
  4 + <meta charset="UTF-8">
  5 + <title>测试报告</title>
  6 +
  7 + <link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.5.0/css/bootstrap.min.css">
  8 + <script src=" https://cdn.staticfile.org/jquery/2.0.0/jquery.min.js"></script>
  9 + <script src="https://cdn.staticfile.org/echarts/5.1.2/echarts.min.js"></script>
  10 + <!-- 页面样式-->
  11 + <style type="text/css">
  12 + /*标题样式*/
  13 + .title {
  14 + width: auto;
  15 + height: 60px;
  16 + text-align: center;
  17 + font: bolder 38px/60px "Microsoft YaHei UI";
  18 + }
  19 +
  20 + /*汇总信息样式*/
  21 + .summary {
  22 + width: 90%;
  23 + position: absolute;
  24 + top: 120px;
  25 + margin-left: 5%;
  26 +
  27 + }
  28 +
  29 + .text-left {
  30 + font: bolder 20px/30px "Microsoft YaHei UI";
  31 + }
  32 +
  33 + .left {
  34 + width: 50%;
  35 + float: left;
  36 +
  37 + }
  38 +
  39 + .right {
  40 + width: 50%;
  41 + float: right;
  42 +
  43 + }
  44 +
  45 + .desc {
  46 + float: left;
  47 + width: 100%;
  48 + }
  49 +
  50 + .list-group-item span {
  51 + font: normal 16px/38px "Microsoft YaHei UI";
  52 + padding: 30px;
  53 +
  54 + }
  55 +
  56 + .list-group-item {
  57 + position: relative;
  58 + display: block;
  59 + padding: .4rem 1.25rem;
  60 + background-color: #fff;
  61 + border: 1px solid rgba(0, 0, 0, .125);
  62 + }
  63 +
  64 + /* 执行信息样式 */
  65 + .test_info {
  66 + width: 90%;
  67 + position: absolute;
  68 + top: 900px;
  69 + margin-left: 5%;
  70 +
  71 + color: #28a745 !important;
  72 + }
  73 +
  74 + .table td, th {
  75 + border: solid 2px rgba(9, 122, 51, 0.11) !important;
  76 + padding: 0;
  77 + line-height: 40px;
  78 + text-align: center;
  79 +
  80 + }
  81 +
  82 +
  83 + select {
  84 + border: 0;
  85 + padding: 0;
  86 + margin: 0;
  87 + height: 2em;
  88 + width: 8em;
  89 + margin-left: 2em;
  90 + }
  91 +
  92 + option {
  93 + text-align: center;
  94 + height: 36px;
  95 + font: none 18px/36px "Microsoft YaHei UI";
  96 + color: #28a745 !important;
  97 + }
  98 +
  99 + .test_log {
  100 + background: rgba(163, 171, 189, 0.15);
  101 + width: 100%;
  102 + height: 50px;
  103 + border-top: none;
  104 + border-bottom: none;
  105 + display: none;
  106 + text-align: left;
  107 + }
  108 +
  109 + .test_log td {
  110 + text-align: left;
  111 + height: 30px;
  112 + margin: 0;
  113 + padding-left: 3em;
  114 + padding-right:3em;
  115 + font: none 18px/24px "Microsoft YaHei UI";
  116 + color: #9e141a;
  117 + }
  118 +
  119 + pre {
  120 + margin: 0;
  121 + white-space: pre-wrap;
  122 + white-space: -moz-pre-wrap;
  123 + white-space: -o-pre-wrap;
  124 + word-wrap: break-word;
  125 + line-height: 22px;
  126 + font-size: 14px
  127 + }
  128 +
  129 + /* 测试图表显示*/
  130 + .char {
  131 + width: 90%;
  132 + position: absolute;
  133 + top: 450px;
  134 + margin-left: 5%;
  135 + color: #28a745 !important;
  136 + }
  137 +
  138 + </style>
  139 +
  140 +</head>
  141 +<body>
  142 +
  143 +<!--报告标题-->
  144 +<div class="title text-success">
  145 + <div class="shadow-lg p-3 mb-5 bg-white rounded">优学乐业测试报告</div>
  146 +</div>
  147 +
  148 +<!--汇总信息-->
  149 +<div class="summary">
  150 + <p class="text-left text-success">测试结果汇总</p>
  151 + <div class="left">
  152 + <ul class="list-group">
  153 + <li class="list-group-item">
  154 + <button type="button" class="btn btn-success">测试人员</button>
  155 + <span class="text-dark">石头</span>
  156 + </li>
  157 + <li class="list-group-item">
  158 + <button type="button" class="btn btn-success">开始时间</button>
  159 + <span class="text-dark">2022-12-20 21:35:13</span>
  160 + </li>
  161 + <li class="list-group-item">
  162 + <button type="button" class="btn btn-success">执行时间</button>
  163 + <span class="text-dark">6.77 S</span>
  164 + </li>
  165 + <li class="list-group-item">
  166 + <button type="button" class="btn btn-success">用例总数</button>
  167 + <span class="text-dark">24</span>
  168 + </li>
  169 +
  170 +
  171 + </ul>
  172 + </div>
  173 + <div class="right">
  174 + <ul class="list-group">
  175 +
  176 + <li class="list-group-item">
  177 + <button type="button" class="btn btn-success">成功用例</button>
  178 + <span class="text-success">9</span>
  179 + </li>
  180 + <li class="list-group-item">
  181 + <button type="button" class="btn btn-warning">失败用例</button>
  182 + <span class="text-warning">15</span>
  183 + </li>
  184 + <li class="list-group-item">
  185 + <button type="button" class="btn btn-danger">错误用例</button>
  186 + <span class="text-danger">0</span>
  187 + </li>
  188 + <li class="list-group-item">
  189 + <button type="button" class="btn btn-secondary">跳过用例</button>
  190 + <span class="text-secondary">0</span>
  191 + </li>
  192 + </ul>
  193 + </div>
  194 + <div class="desc">
  195 + <ul class="list-group">
  196 + <li class="list-group-item">
  197 + <button type="button" class="btn btn-success">描述信息</button>
  198 + <span class="text-secondary">优学乐业测试报告</span>
  199 + </li>
  200 + </ul>
  201 + </div>
  202 +
  203 +
  204 +</div>
  205 +
  206 +<!--测试图表-->
  207 +<div class="char">
  208 + <p class="text-left text-success">图表展示</p>
  209 + <div id="char2" style="width: 49%;height: 400px;float: left"></div>
  210 + <div id="char" style="width: 49%;height: 400px ;float: left"></div>
  211 +</div>
  212 +
  213 +<!--详细信息-->
  214 +<div class="test_info">
  215 +
  216 + <p class="text-left text-success">详细信息</p>
  217 + <div class="table_data">
  218 +
  219 + <table class="table">
  220 + <thead class="bg-success text-light">
  221 + <tr>
  222 + <th scope="col" style="width: 5%;padding: 0">编号</th>
  223 + <th scope="col" style="width: 20%;padding: 0">
  224 + <span>测试类</span>
  225 + <select id="testClass">
  226 + <option>所有</option>
  227 +
  228 + <option>TestLogin</option>
  229 +
  230 + <option>Test02Specialty</option>
  231 +
  232 + <option>Test03Year</option>
  233 +
  234 + <option>Test01Department</option>
  235 +
  236 + </select>
  237 +
  238 + </th>
  239 +
  240 + <th scope="col" style="width: 15%;padding: 0">测试方法</th>
  241 + <th scope="col" style="width: 20%;padding: 0">用例描述</th>
  242 + <th scope="col" style="width: 15%;padding: 0">执行时间</th>
  243 + <th scope="col" style="width: 20%;padding: 0">
  244 +
  245 + <span>执行结果</span>
  246 + <select id="testResult">
  247 + <option>所有</option>
  248 + <option class="text-success">成功</option>
  249 + <option class="text-warning">失败</option>
  250 + <option class="text-danger">错误</option>
  251 + <option class="text-info">跳过</option>
  252 + </select>
  253 +
  254 + </th>
  255 + <th scope="col" style="width: 10%;padding: 0">详细信息</th>
  256 + </tr>
  257 + </thead>
  258 + <tbody>
  259 +
  260 + <tr>
  261 + <td>1</td>
  262 + <td class="TestLogin">TestLogin</td>
  263 + <td>test_login_1</td>
  264 + <td>登陆成功</td>
  265 + <td>0.537s</td>
  266 +
  267 + <td class="text-success">成功</td>
  268 +
  269 + <td>
  270 + <button type="button" class="btn btn-success btn_info">查看详情</button>
  271 + </td>
  272 + </tr>
  273 +
  274 + <tr class="test_log">
  275 +
  276 + <td colspan="7" class="small text-muted" style=" word-wrap:break-word; word-break:break-all">
  277 +
  278 +
  279 + <pre>用例入参:{'way': 'name', 'password': 'f85eea0e15e424aba8675f8848e2cb83', 'type': 'teacher', 'username': '17301249975'}
  280 +预期结果:{'msg': 'success', 'code': 200}
  281 +实际结果:{'msg': 'success', 'code': 200, 'data': {'access_token': 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0ZW5hbnRUeXBlIjoiIiwiYnJva2VySWQiOiIiLCJocm9Vc2VyVG9rZW4iOm51bGwsInVzZXJfbmFtZSI6IjE3MzAxMjQ5OTc1IiwiYXV0aFN0YXR1cyI6IiIsImF1dGhlbnRpY2F0aW9uSWRlbnRpdHkiOiJsb2dpbiIsInR5cGUiOiJ0ZWFjaGVyIiwidXNlcklkIjoiMTUxOTk1OTIwODUyOTg2Njc1MyIsImNsaWVudF9pZCI6IndvcmthaSIsInN0dWRlbnRJZCI6IiIsInRlYWNoZXJJZCI6IjE1MTk5NTkyMDkyNzY0NTI4NjUiLCJ0ZW5hbnROYW1lIjoiIiwicGhvbmUiOiIxNzMwMTI0OTk3NSIsInNjb3BlIjpbImFsbCJdLCJzY2hvb2xJZCI6IjE1MTk5NTg1NjYxMzAyNTc5MjIiLCJ0ZW5hbnRJZCI6IiIsIm5hbWUiOiLmoKHplb8iLCJzdHVkZW50U3RhdHVzIjoiIiwiZXhwIjoxNjcxNTc5MzE0LCJzY2hvb2xOYW1lIjoi5rWL6K-V5aSn5a2mIiwianRpIjoiOThhOTY4NjktZDVlMy00YThlLWEyZmQtNmQxOWY5ZWVkNmIzIiwic3RhdHVzIjoiYWN0aXZlIn0.jGUS_oLPTLxKewnrJmIDQayv941nKoVoDkBpnWpF1L75UyLhkQHrNmvuyEwUiiSsYYfQsU1FV9Tj0BOjJZItppjX7FcRF-tKHIBj_YO2L9e1B9QfZ989vwjxhrV5NCe4dShPQ5QbH1yOQSTvshWKBBR5zEnqizpZtsZPDVSXb2Abd05nozG3MJVuRbYne72oeC86ho71JxdEkxCf2f7bKCFNmZF-oKBrIAhoVWPR4dQMrCE5JgeQGIIKC2buDyhJ9KhUCJhI0iz80raErP9x4RClT6n0RLOj-tXClTYj_snN8Fh_d6uqb9WFj3e37dkdFdWeyVwbg2PaC6gVU1-rlw', 'token_type': 'bearer', 'refresh_token': 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0ZW5hbnRUeXBlIjoiIiwiYnJva2VySWQiOiIiLCJocm9Vc2VyVG9rZW4iOm51bGwsInVzZXJfbmFtZSI6IjE3MzAxMjQ5OTc1IiwiYXV0aFN0YXR1cyI6IiIsImF1dGhlbnRpY2F0aW9uSWRlbnRpdHkiOiJsb2dpbiIsInR5cGUiOiJ0ZWFjaGVyIiwidXNlcklkIjoiMTUxOTk1OTIwODUyOTg2Njc1MyIsImNsaWVudF9pZCI6IndvcmthaSIsInN0dWRlbnRJZCI6IiIsInRlYWNoZXJJZCI6IjE1MTk5NTkyMDkyNzY0NTI4NjUiLCJ0ZW5hbnROYW1lIjoiIiwicGhvbmUiOiIxNzMwMTI0OTk3NSIsInNjb3BlIjpbImFsbCJdLCJzY2hvb2xJZCI6IjE1MTk5NTg1NjYxMzAyNTc5MjIiLCJhdGkiOiI5OGE5Njg2OS1kNWUzLTRhOGUtYTJmZC02ZDE5ZjllZWQ2YjMiLCJ0ZW5hbnRJZCI6IiIsIm5hbWUiOiLmoKHplb8iLCJzdHVkZW50U3RhdHVzIjoiIiwiZXhwIjoxNjcxNjE1MzE0LCJzY2hvb2xOYW1lIjoi5rWL6K-V5aSn5a2mIiwianRpIjoiMmYzNjFlOWQtY2Y5YS00OWUyLWFhZjctYWQwMWQ5NjQyZjg5Iiwic3RhdHVzIjoiYWN0aXZlIn0.E2mScC7k8vugNPnXhieiKeDXiT1AOZ2TwtI3RNZ2a8XWB1L1Vl5NWOwr6FCQSd-ApqvTvOl8k0LYs5rkRdlgsRIJTy-_gNs4VhZU4b8mkWlajCn_prDbToCWcTjKJomPao5biiBgQtQ8Q2zgGYj_oAxv-yQoxIPaxATKECJrXhci7afbRFQjTwTdH8_uchvr7sv1-9lZ9gfKbFSXsYvjgXvlxH220Guvio9q6EGNfxKWVgHuPMsv96H2Le8qrzmJNmTht0660oftw0A2WL84ZFemvmMscaXizRkNL9Nv6bvt1o_unQXOVQwx61SYVNayB2UjsICGRJGU3Y_G2hgKBg', 'expires_in': 35999, 'scope': 'all', 'tenantType': '', 'brokerId': '', 'hroUserToken': None, 'authStatus': '', 'authenticationIdentity': 'login', 'type': 'teacher', 'userId': '1519959208529866753', 'studentId': '', 'teacherId': '1519959209276452865', 'tenantName': '', 'phone': '17301249975', 'schoolId': '1519958566130257922', 'tenantId': '', 'name': '校长', 'studentStatus': '', 'schoolName': '测试大学', 'status': 'active', 'jti': '98a96869-d5e3-4a8e-a2fd-6d19f9eed6b3'}}
  282 +test_login_1 (test_01_login.TestLogin)执行——>【通过】
  283 +</pre>
  284 +
  285 +
  286 + </td>
  287 + </tr>
  288 +
  289 + <tr>
  290 + <td>2</td>
  291 + <td class="TestLogin">TestLogin</td>
  292 + <td>test_login_2</td>
  293 + <td>手机号填写错误的</td>
  294 + <td>0.219s</td>
  295 +
  296 + <td class="text-warning">失败</td>
  297 +
  298 + <td>
  299 + <button type="button" class="btn btn-success btn_info">查看详情</button>
  300 + </td>
  301 + </tr>
  302 +
  303 + <tr class="test_log">
  304 +
  305 + <td colspan="7" class="small text-muted" style=" word-wrap:break-word; word-break:break-all">
  306 +
  307 +
  308 + <pre>用例入参:{'username': '17301149975', 'password': 'f85eea0e15e424aba8675f8848e2cb83', 'type': 'teacher'}
  309 +预期结果:{'code': 500, 'data': None, 'msg': '用户不存在'}
  310 +实际结果:{'code': 500, 'data': None, 'msg': '参数不正确'}
  311 +test_login_2 (test_01_login.TestLogin)执行——>【失败】
  312 +</pre>
  313 +
  314 +
  315 + <pre>Traceback (most recent call last):
  316 +</pre>
  317 +
  318 +
  319 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 59, in testPartExecutor
  320 + yield
  321 +</pre>
  322 +
  323 +
  324 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 615, in run
  325 + testMethod()
  326 +</pre>
  327 +
  328 +
  329 + <pre> File "/Users/shitou/工作/code/work/workAi/yxly/common/myddt.py", line 145, in wrapper
  330 + return func(self, *args, **kwargs)
  331 +</pre>
  332 +
  333 +
  334 + <pre> File "/Users/shitou/工作/code/work/workAi/yxly/testcase/test_01_login.py", line 57, in test_login
  335 + raise e
  336 +</pre>
  337 +
  338 +
  339 + <pre> File "/Users/shitou/工作/code/work/workAi/yxly/testcase/test_01_login.py", line 49, in test_login
  340 + self.assertEqual(expected['msg'], res['msg'])
  341 +</pre>
  342 +
  343 +
  344 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 839, in assertEqual
  345 + assertion_func(first, second, msg=msg)
  346 +</pre>
  347 +
  348 +
  349 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 1220, in assertMultiLineEqual
  350 + self.fail(self._formatMessage(msg, standardMsg))
  351 +</pre>
  352 +
  353 +
  354 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 680, in fail
  355 + raise self.failureException(msg)
  356 +</pre>
  357 +
  358 +
  359 + <pre>AssertionError: '用户不存在' != '参数不正确'
  360 +- 用户不存在
  361 ++ 参数不正确
  362 +
  363 +</pre>
  364 +
  365 +
  366 + </td>
  367 + </tr>
  368 +
  369 + <tr>
  370 + <td>3</td>
  371 + <td class="TestLogin">TestLogin</td>
  372 + <td>test_login_3</td>
  373 + <td>手机号不进行填写</td>
  374 + <td>0.193s</td>
  375 +
  376 + <td class="text-warning">失败</td>
  377 +
  378 + <td>
  379 + <button type="button" class="btn btn-success btn_info">查看详情</button>
  380 + </td>
  381 + </tr>
  382 +
  383 + <tr class="test_log">
  384 +
  385 + <td colspan="7" class="small text-muted" style=" word-wrap:break-word; word-break:break-all">
  386 +
  387 +
  388 + <pre>用例入参:{'username': '', 'password': 'f85eea0e15e424aba8675f8848e2cb83', 'type': 'teacher'}
  389 +预期结果:{'code': 500, 'data': None, 'msg': '用户名和密码不能为空'}
  390 +实际结果:{'code': 500, 'data': None, 'msg': '参数不正确'}
  391 +test_login_3 (test_01_login.TestLogin)执行——>【失败】
  392 +</pre>
  393 +
  394 +
  395 + <pre>Traceback (most recent call last):
  396 +</pre>
  397 +
  398 +
  399 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 59, in testPartExecutor
  400 + yield
  401 +</pre>
  402 +
  403 +
  404 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 615, in run
  405 + testMethod()
  406 +</pre>
  407 +
  408 +
  409 + <pre> File "/Users/shitou/工作/code/work/workAi/yxly/common/myddt.py", line 145, in wrapper
  410 + return func(self, *args, **kwargs)
  411 +</pre>
  412 +
  413 +
  414 + <pre> File "/Users/shitou/工作/code/work/workAi/yxly/testcase/test_01_login.py", line 57, in test_login
  415 + raise e
  416 +</pre>
  417 +
  418 +
  419 + <pre> File "/Users/shitou/工作/code/work/workAi/yxly/testcase/test_01_login.py", line 49, in test_login
  420 + self.assertEqual(expected['msg'], res['msg'])
  421 +</pre>
  422 +
  423 +
  424 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 839, in assertEqual
  425 + assertion_func(first, second, msg=msg)
  426 +</pre>
  427 +
  428 +
  429 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 1220, in assertMultiLineEqual
  430 + self.fail(self._formatMessage(msg, standardMsg))
  431 +</pre>
  432 +
  433 +
  434 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 680, in fail
  435 + raise self.failureException(msg)
  436 +</pre>
  437 +
  438 +
  439 + <pre>AssertionError: '用户名和密码不能为空' != '参数不正确'
  440 +- 用户名和密码不能为空
  441 ++ 参数不正确
  442 +
  443 +</pre>
  444 +
  445 +
  446 + </td>
  447 + </tr>
  448 +
  449 + <tr>
  450 + <td>4</td>
  451 + <td class="TestLogin">TestLogin</td>
  452 + <td>test_login_4</td>
  453 + <td>密码填写错误</td>
  454 + <td>0.199s</td>
  455 +
  456 + <td class="text-warning">失败</td>
  457 +
  458 + <td>
  459 + <button type="button" class="btn btn-success btn_info">查看详情</button>
  460 + </td>
  461 + </tr>
  462 +
  463 + <tr class="test_log">
  464 +
  465 + <td colspan="7" class="small text-muted" style=" word-wrap:break-word; word-break:break-all">
  466 +
  467 +
  468 + <pre>用例入参:{'username': '17301249975', 'password': 'f85eea0e115e424aba8675f8848e2cb83', 'type': 'teacher'}
  469 +预期结果:{'code': 500, 'data': None, 'msg': '密码不正确'}
  470 +实际结果:{'code': 500, 'data': None, 'msg': '参数不正确'}
  471 +test_login_4 (test_01_login.TestLogin)执行——>【失败】
  472 +</pre>
  473 +
  474 +
  475 + <pre>Traceback (most recent call last):
  476 +</pre>
  477 +
  478 +
  479 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 59, in testPartExecutor
  480 + yield
  481 +</pre>
  482 +
  483 +
  484 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 615, in run
  485 + testMethod()
  486 +</pre>
  487 +
  488 +
  489 + <pre> File "/Users/shitou/工作/code/work/workAi/yxly/common/myddt.py", line 145, in wrapper
  490 + return func(self, *args, **kwargs)
  491 +</pre>
  492 +
  493 +
  494 + <pre> File "/Users/shitou/工作/code/work/workAi/yxly/testcase/test_01_login.py", line 57, in test_login
  495 + raise e
  496 +</pre>
  497 +
  498 +
  499 + <pre> File "/Users/shitou/工作/code/work/workAi/yxly/testcase/test_01_login.py", line 49, in test_login
  500 + self.assertEqual(expected['msg'], res['msg'])
  501 +</pre>
  502 +
  503 +
  504 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 839, in assertEqual
  505 + assertion_func(first, second, msg=msg)
  506 +</pre>
  507 +
  508 +
  509 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 1220, in assertMultiLineEqual
  510 + self.fail(self._formatMessage(msg, standardMsg))
  511 +</pre>
  512 +
  513 +
  514 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 680, in fail
  515 + raise self.failureException(msg)
  516 +</pre>
  517 +
  518 +
  519 + <pre>AssertionError: '密码不正确' != '参数不正确'
  520 +- 密码不正确
  521 ++ 参数不正确
  522 +
  523 +</pre>
  524 +
  525 +
  526 + </td>
  527 + </tr>
  528 +
  529 + <tr>
  530 + <td>5</td>
  531 + <td class="TestLogin">TestLogin</td>
  532 + <td>test_login_5</td>
  533 + <td>密码不进行填写</td>
  534 + <td>0.219s</td>
  535 +
  536 + <td class="text-warning">失败</td>
  537 +
  538 + <td>
  539 + <button type="button" class="btn btn-success btn_info">查看详情</button>
  540 + </td>
  541 + </tr>
  542 +
  543 + <tr class="test_log">
  544 +
  545 + <td colspan="7" class="small text-muted" style=" word-wrap:break-word; word-break:break-all">
  546 +
  547 +
  548 + <pre>用例入参:{'username': '17301249975', 'password': '', 'type': 'teacher'}
  549 +预期结果:{'code': 500, 'data': None, 'msg': '用户名和密码不能为空'}
  550 +实际结果:{'code': 500, 'data': None, 'msg': '参数不正确'}
  551 +test_login_5 (test_01_login.TestLogin)执行——>【失败】
  552 +</pre>
  553 +
  554 +
  555 + <pre>Traceback (most recent call last):
  556 +</pre>
  557 +
  558 +
  559 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 59, in testPartExecutor
  560 + yield
  561 +</pre>
  562 +
  563 +
  564 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 615, in run
  565 + testMethod()
  566 +</pre>
  567 +
  568 +
  569 + <pre> File "/Users/shitou/工作/code/work/workAi/yxly/common/myddt.py", line 145, in wrapper
  570 + return func(self, *args, **kwargs)
  571 +</pre>
  572 +
  573 +
  574 + <pre> File "/Users/shitou/工作/code/work/workAi/yxly/testcase/test_01_login.py", line 57, in test_login
  575 + raise e
  576 +</pre>
  577 +
  578 +
  579 + <pre> File "/Users/shitou/工作/code/work/workAi/yxly/testcase/test_01_login.py", line 49, in test_login
  580 + self.assertEqual(expected['msg'], res['msg'])
  581 +</pre>
  582 +
  583 +
  584 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 839, in assertEqual
  585 + assertion_func(first, second, msg=msg)
  586 +</pre>
  587 +
  588 +
  589 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 1220, in assertMultiLineEqual
  590 + self.fail(self._formatMessage(msg, standardMsg))
  591 +</pre>
  592 +
  593 +
  594 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 680, in fail
  595 + raise self.failureException(msg)
  596 +</pre>
  597 +
  598 +
  599 + <pre>AssertionError: '用户名和密码不能为空' != '参数不正确'
  600 +- 用户名和密码不能为空
  601 ++ 参数不正确
  602 +
  603 +</pre>
  604 +
  605 +
  606 + </td>
  607 + </tr>
  608 +
  609 + <tr>
  610 + <td>6</td>
  611 + <td class="Test01Department">Test01Department</td>
  612 + <td>test_add_department_1</td>
  613 + <td>新增院系成功</td>
  614 + <td>0.254s</td>
  615 +
  616 + <td class="text-success">成功</td>
  617 +
  618 + <td>
  619 + <button type="button" class="btn btn-success btn_info">查看详情</button>
  620 + </td>
  621 + </tr>
  622 +
  623 + <tr class="test_log">
  624 +
  625 + <td colspan="7" class="small text-muted" style=" word-wrap:break-word; word-break:break-all">
  626 +
  627 +
  628 + <pre>用例入参:{'name': 'py自动化院系20221220_21:35:15_1', 'code': 'py_code20221220_21:35:15_1'}
  629 +预期结果: {'msg': 'success', 'code': 200, 'data': True}
  630 +实际结果: {'msg': 'success', 'code': 200, 'data': True}
  631 +test_add_department_1 (test_02_system_management.Test01Department)执行——>【通过】
  632 +</pre>
  633 +
  634 +
  635 + </td>
  636 + </tr>
  637 +
  638 + <tr>
  639 + <td>7</td>
  640 + <td class="Test01Department">Test01Department</td>
  641 + <td>test_add_department_2</td>
  642 + <td>院系名称未填写</td>
  643 + <td>0.186s</td>
  644 +
  645 + <td class="text-warning">失败</td>
  646 +
  647 + <td>
  648 + <button type="button" class="btn btn-success btn_info">查看详情</button>
  649 + </td>
  650 + </tr>
  651 +
  652 + <tr class="test_log">
  653 +
  654 + <td colspan="7" class="small text-muted" style=" word-wrap:break-word; word-break:break-all">
  655 +
  656 +
  657 + <pre>用例入参:{'name': '', 'code': 'py_code20221220_21:35:15_2'}
  658 +预期结果: {'msg': '院系名称未填写', 'code': 500, 'data': None}
  659 +实际结果: {'msg': 'size must be between 1 and 30', 'code': 500, 'data': None}
  660 +test_add_department_2 (test_02_system_management.Test01Department)执行——>【失败】
  661 +</pre>
  662 +
  663 +
  664 + <pre>Traceback (most recent call last):
  665 +</pre>
  666 +
  667 +
  668 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 59, in testPartExecutor
  669 + yield
  670 +</pre>
  671 +
  672 +
  673 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 615, in run
  674 + testMethod()
  675 +</pre>
  676 +
  677 +
  678 + <pre> File "/Users/shitou/工作/code/work/workAi/yxly/common/myddt.py", line 145, in wrapper
  679 + return func(self, *args, **kwargs)
  680 +</pre>
  681 +
  682 +
  683 + <pre> File "/Users/shitou/工作/code/work/workAi/yxly/testcase/test_02_system_management.py", line 84, in test_add_department
  684 + raise e
  685 +</pre>
  686 +
  687 +
  688 + <pre> File "/Users/shitou/工作/code/work/workAi/yxly/testcase/test_02_system_management.py", line 77, in test_add_department
  689 + self.assertEqual(expected['msg'], res['msg'])
  690 +</pre>
  691 +
  692 +
  693 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 839, in assertEqual
  694 + assertion_func(first, second, msg=msg)
  695 +</pre>
  696 +
  697 +
  698 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 1220, in assertMultiLineEqual
  699 + self.fail(self._formatMessage(msg, standardMsg))
  700 +</pre>
  701 +
  702 +
  703 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 680, in fail
  704 + raise self.failureException(msg)
  705 +</pre>
  706 +
  707 +
  708 + <pre>AssertionError: '院系名称未填写' != 'size must be between 1 and 30'
  709 +- 院系名称未填写
  710 ++ size must be between 1 and 30
  711 +
  712 +</pre>
  713 +
  714 +
  715 + </td>
  716 + </tr>
  717 +
  718 + <tr>
  719 + <td>8</td>
  720 + <td class="Test01Department">Test01Department</td>
  721 + <td>test_add_department_3</td>
  722 + <td>院系名称重复</td>
  723 + <td>0.246s</td>
  724 +
  725 + <td class="text-success">成功</td>
  726 +
  727 + <td>
  728 + <button type="button" class="btn btn-success btn_info">查看详情</button>
  729 + </td>
  730 + </tr>
  731 +
  732 + <tr class="test_log">
  733 +
  734 + <td colspan="7" class="small text-muted" style=" word-wrap:break-word; word-break:break-all">
  735 +
  736 +
  737 + <pre>用例入参:{'name': '院系1', 'code': 'py_code20221220_21:35:15_3'}
  738 +预期结果: {'msg': '院系名称已存在,请确认', 'code': 500, 'data': None}
  739 +实际结果: {'msg': '院系名称已存在,请确认', 'code': 500, 'data': None}
  740 +test_add_department_3 (test_02_system_management.Test01Department)执行——>【通过】
  741 +</pre>
  742 +
  743 +
  744 + </td>
  745 + </tr>
  746 +
  747 + <tr>
  748 + <td>9</td>
  749 + <td class="Test01Department">Test01Department</td>
  750 + <td>test_add_department_4</td>
  751 + <td>院系名称长度不可大于30位</td>
  752 + <td>0.225s</td>
  753 +
  754 + <td class="text-warning">失败</td>
  755 +
  756 + <td>
  757 + <button type="button" class="btn btn-success btn_info">查看详情</button>
  758 + </td>
  759 + </tr>
  760 +
  761 + <tr class="test_log">
  762 +
  763 + <td colspan="7" class="small text-muted" style=" word-wrap:break-word; word-break:break-all">
  764 +
  765 +
  766 + <pre>用例入参:{'name': '院系名称长度大于30的测试院系名称长度大于30的测试院系名称长度大于30的测试院系名称长度大于30的测试', 'code': 'py_code20221220_21:35:16_4'}
  767 +预期结果: {'msg': '院系名称长度不可大于30', 'code': 500, 'data': None}
  768 +实际结果: {'msg': 'size must be between 1 and 30', 'code': 500, 'data': None}
  769 +test_add_department_4 (test_02_system_management.Test01Department)执行——>【失败】
  770 +</pre>
  771 +
  772 +
  773 + <pre>Traceback (most recent call last):
  774 +</pre>
  775 +
  776 +
  777 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 59, in testPartExecutor
  778 + yield
  779 +</pre>
  780 +
  781 +
  782 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 615, in run
  783 + testMethod()
  784 +</pre>
  785 +
  786 +
  787 + <pre> File "/Users/shitou/工作/code/work/workAi/yxly/common/myddt.py", line 145, in wrapper
  788 + return func(self, *args, **kwargs)
  789 +</pre>
  790 +
  791 +
  792 + <pre> File "/Users/shitou/工作/code/work/workAi/yxly/testcase/test_02_system_management.py", line 84, in test_add_department
  793 + raise e
  794 +</pre>
  795 +
  796 +
  797 + <pre> File "/Users/shitou/工作/code/work/workAi/yxly/testcase/test_02_system_management.py", line 77, in test_add_department
  798 + self.assertEqual(expected['msg'], res['msg'])
  799 +</pre>
  800 +
  801 +
  802 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 839, in assertEqual
  803 + assertion_func(first, second, msg=msg)
  804 +</pre>
  805 +
  806 +
  807 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 1220, in assertMultiLineEqual
  808 + self.fail(self._formatMessage(msg, standardMsg))
  809 +</pre>
  810 +
  811 +
  812 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 680, in fail
  813 + raise self.failureException(msg)
  814 +</pre>
  815 +
  816 +
  817 + <pre>AssertionError: '院系名称长度不可大于30' != 'size must be between 1 and 30'
  818 +- 院系名称长度不可大于30
  819 ++ size must be between 1 and 30
  820 +
  821 +</pre>
  822 +
  823 +
  824 + </td>
  825 + </tr>
  826 +
  827 + <tr>
  828 + <td>10</td>
  829 + <td class="Test01Department">Test01Department</td>
  830 + <td>test_add_department_5</td>
  831 + <td>院系代码不能为空</td>
  832 + <td>0.188s</td>
  833 +
  834 + <td class="text-warning">失败</td>
  835 +
  836 + <td>
  837 + <button type="button" class="btn btn-success btn_info">查看详情</button>
  838 + </td>
  839 + </tr>
  840 +
  841 + <tr class="test_log">
  842 +
  843 + <td colspan="7" class="small text-muted" style=" word-wrap:break-word; word-break:break-all">
  844 +
  845 +
  846 + <pre>用例入参:{'name': 'py自动化院系20221220_21:35:16_5', 'code': ''}
  847 +预期结果: {'msg': '院系代码不能为空', 'code': 500, 'data': None}
  848 +实际结果: {'msg': 'size must be between 1 and 30', 'code': 500, 'data': None}
  849 +test_add_department_5 (test_02_system_management.Test01Department)执行——>【失败】
  850 +</pre>
  851 +
  852 +
  853 + <pre>Traceback (most recent call last):
  854 +</pre>
  855 +
  856 +
  857 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 59, in testPartExecutor
  858 + yield
  859 +</pre>
  860 +
  861 +
  862 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 615, in run
  863 + testMethod()
  864 +</pre>
  865 +
  866 +
  867 + <pre> File "/Users/shitou/工作/code/work/workAi/yxly/common/myddt.py", line 145, in wrapper
  868 + return func(self, *args, **kwargs)
  869 +</pre>
  870 +
  871 +
  872 + <pre> File "/Users/shitou/工作/code/work/workAi/yxly/testcase/test_02_system_management.py", line 84, in test_add_department
  873 + raise e
  874 +</pre>
  875 +
  876 +
  877 + <pre> File "/Users/shitou/工作/code/work/workAi/yxly/testcase/test_02_system_management.py", line 77, in test_add_department
  878 + self.assertEqual(expected['msg'], res['msg'])
  879 +</pre>
  880 +
  881 +
  882 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 839, in assertEqual
  883 + assertion_func(first, second, msg=msg)
  884 +</pre>
  885 +
  886 +
  887 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 1220, in assertMultiLineEqual
  888 + self.fail(self._formatMessage(msg, standardMsg))
  889 +</pre>
  890 +
  891 +
  892 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 680, in fail
  893 + raise self.failureException(msg)
  894 +</pre>
  895 +
  896 +
  897 + <pre>AssertionError: '院系代码不能为空' != 'size must be between 1 and 30'
  898 +- 院系代码不能为空
  899 ++ size must be between 1 and 30
  900 +
  901 +</pre>
  902 +
  903 +
  904 + </td>
  905 + </tr>
  906 +
  907 + <tr>
  908 + <td>11</td>
  909 + <td class="Test01Department">Test01Department</td>
  910 + <td>test_add_department_6</td>
  911 + <td>院系代码长度不可大于30</td>
  912 + <td>0.204s</td>
  913 +
  914 + <td class="text-warning">失败</td>
  915 +
  916 + <td>
  917 + <button type="button" class="btn btn-success btn_info">查看详情</button>
  918 + </td>
  919 + </tr>
  920 +
  921 + <tr class="test_log">
  922 +
  923 + <td colspan="7" class="small text-muted" style=" word-wrap:break-word; word-break:break-all">
  924 +
  925 +
  926 + <pre>用例入参:{'name': 'py自动化院系20221220_21:35:16_6', 'code': '院系代码长度大于30的测试院系代码长度大于30的测试院系代码长度大于30的测试'}
  927 +预期结果: {'msg': '院系代码不可大于30', 'code': 500, 'data': None}
  928 +实际结果: {'msg': 'size must be between 1 and 30', 'code': 500, 'data': None}
  929 +test_add_department_6 (test_02_system_management.Test01Department)执行——>【失败】
  930 +</pre>
  931 +
  932 +
  933 + <pre>Traceback (most recent call last):
  934 +</pre>
  935 +
  936 +
  937 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 59, in testPartExecutor
  938 + yield
  939 +</pre>
  940 +
  941 +
  942 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 615, in run
  943 + testMethod()
  944 +</pre>
  945 +
  946 +
  947 + <pre> File "/Users/shitou/工作/code/work/workAi/yxly/common/myddt.py", line 145, in wrapper
  948 + return func(self, *args, **kwargs)
  949 +</pre>
  950 +
  951 +
  952 + <pre> File "/Users/shitou/工作/code/work/workAi/yxly/testcase/test_02_system_management.py", line 84, in test_add_department
  953 + raise e
  954 +</pre>
  955 +
  956 +
  957 + <pre> File "/Users/shitou/工作/code/work/workAi/yxly/testcase/test_02_system_management.py", line 77, in test_add_department
  958 + self.assertEqual(expected['msg'], res['msg'])
  959 +</pre>
  960 +
  961 +
  962 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 839, in assertEqual
  963 + assertion_func(first, second, msg=msg)
  964 +</pre>
  965 +
  966 +
  967 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 1220, in assertMultiLineEqual
  968 + self.fail(self._formatMessage(msg, standardMsg))
  969 +</pre>
  970 +
  971 +
  972 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 680, in fail
  973 + raise self.failureException(msg)
  974 +</pre>
  975 +
  976 +
  977 + <pre>AssertionError: '院系代码不可大于30' != 'size must be between 1 and 30'
  978 +- 院系代码不可大于30
  979 ++ size must be between 1 and 30
  980 +
  981 +</pre>
  982 +
  983 +
  984 + </td>
  985 + </tr>
  986 +
  987 + <tr>
  988 + <td>12</td>
  989 + <td class="Test01Department">Test01Department</td>
  990 + <td>test_add_department_7</td>
  991 + <td>新增院系成功</td>
  992 + <td>0.251s</td>
  993 +
  994 + <td class="text-success">成功</td>
  995 +
  996 + <td>
  997 + <button type="button" class="btn btn-success btn_info">查看详情</button>
  998 + </td>
  999 + </tr>
  1000 +
  1001 + <tr class="test_log">
  1002 +
  1003 + <td colspan="7" class="small text-muted" style=" word-wrap:break-word; word-break:break-all">
  1004 +
  1005 +
  1006 + <pre>用例入参:{'name': 'py自动化院系20221220_21:35:16_7', 'code': 'py_code20221220_21:35:16_7'}
  1007 +预期结果: {'msg': 'success', 'code': 200, 'data': True}
  1008 +实际结果: {'msg': 'success', 'code': 200, 'data': True}
  1009 +test_add_department_7 (test_02_system_management.Test01Department)执行——>【通过】
  1010 +</pre>
  1011 +
  1012 +
  1013 + </td>
  1014 + </tr>
  1015 +
  1016 + <tr>
  1017 + <td>13</td>
  1018 + <td class="Test02Specialty">Test02Specialty</td>
  1019 + <td>test_add_specialty_01</td>
  1020 + <td>新增专业成功</td>
  1021 + <td>0.243s</td>
  1022 +
  1023 + <td class="text-success">成功</td>
  1024 +
  1025 + <td>
  1026 + <button type="button" class="btn btn-success btn_info">查看详情</button>
  1027 + </td>
  1028 + </tr>
  1029 +
  1030 + <tr class="test_log">
  1031 +
  1032 + <td colspan="7" class="small text-muted" style=" word-wrap:break-word; word-break:break-all">
  1033 +
  1034 +
  1035 + <pre>用例入参:{'name': 'py专业21:35:17_1', 'code': 'py_code21:35:17_1', 'departmentId': '1597509063577825282', 'category': 'science'}
  1036 +预期结果: {'msg': 'success', 'code': 200, 'data': True}
  1037 +实际结果: {'msg': 'success', 'code': 200, 'data': True}
  1038 +test_add_specialty_01 (test_02_system_management.Test02Specialty)执行——>【通过】
  1039 +</pre>
  1040 +
  1041 +
  1042 + </td>
  1043 + </tr>
  1044 +
  1045 + <tr>
  1046 + <td>14</td>
  1047 + <td class="Test02Specialty">Test02Specialty</td>
  1048 + <td>test_add_specialty_02</td>
  1049 + <td>新增专业失败,院系未填写</td>
  1050 + <td>0.234s</td>
  1051 +
  1052 + <td class="text-success">成功</td>
  1053 +
  1054 + <td>
  1055 + <button type="button" class="btn btn-success btn_info">查看详情</button>
  1056 + </td>
  1057 + </tr>
  1058 +
  1059 + <tr class="test_log">
  1060 +
  1061 + <td colspan="7" class="small text-muted" style=" word-wrap:break-word; word-break:break-all">
  1062 +
  1063 +
  1064 + <pre>用例入参:{'name': 'py专业21:35:17_2', 'code': 'py_code21:35:17_2', 'departmentId': '', 'category': 'science'}
  1065 +预期结果: {'msg': '院系不能为空', 'code': 500, 'data': None}
  1066 +实际结果: {'msg': '院系不能为空', 'code': 500, 'data': None}
  1067 +test_add_specialty_02 (test_02_system_management.Test02Specialty)执行——>【通过】
  1068 +</pre>
  1069 +
  1070 +
  1071 + </td>
  1072 + </tr>
  1073 +
  1074 + <tr>
  1075 + <td>15</td>
  1076 + <td class="Test02Specialty">Test02Specialty</td>
  1077 + <td>test_add_specialty_03</td>
  1078 + <td>新增专业失败,院系不存在</td>
  1079 + <td>0.229s</td>
  1080 +
  1081 + <td class="text-success">成功</td>
  1082 +
  1083 + <td>
  1084 + <button type="button" class="btn btn-success btn_info">查看详情</button>
  1085 + </td>
  1086 + </tr>
  1087 +
  1088 + <tr class="test_log">
  1089 +
  1090 + <td colspan="7" class="small text-muted" style=" word-wrap:break-word; word-break:break-all">
  1091 +
  1092 +
  1093 + <pre>用例入参:{'name': 'py专业21:35:17_3', 'code': 'py_code21:35:17_3', 'departmentId': '1597509163577825282', 'category': 'science'}
  1094 +预期结果: {'msg': '院系不存在', 'code': 500, 'data': None}
  1095 +实际结果: {'msg': '院系不存在', 'code': 500, 'data': None}
  1096 +test_add_specialty_03 (test_02_system_management.Test02Specialty)执行——>【通过】
  1097 +</pre>
  1098 +
  1099 +
  1100 + </td>
  1101 + </tr>
  1102 +
  1103 + <tr>
  1104 + <td>16</td>
  1105 + <td class="Test02Specialty">Test02Specialty</td>
  1106 + <td>test_add_specialty_04</td>
  1107 + <td>新增专业失败,专业名称未填写</td>
  1108 + <td>0.189s</td>
  1109 +
  1110 + <td class="text-warning">失败</td>
  1111 +
  1112 + <td>
  1113 + <button type="button" class="btn btn-success btn_info">查看详情</button>
  1114 + </td>
  1115 + </tr>
  1116 +
  1117 + <tr class="test_log">
  1118 +
  1119 + <td colspan="7" class="small text-muted" style=" word-wrap:break-word; word-break:break-all">
  1120 +
  1121 +
  1122 + <pre>用例入参:{'name': '', 'code': 'py_code21:35:18_4', 'departmentId': '1597509063577825282', 'category': 'science'}
  1123 +预期结果: {'msg': '专业名称未填写', 'code': 500, 'data': None}
  1124 +实际结果: {'msg': 'size must be between 1 and 30', 'code': 500, 'data': None}
  1125 +test_add_specialty_04 (test_02_system_management.Test02Specialty)执行——>【失败】
  1126 +</pre>
  1127 +
  1128 +
  1129 + <pre>Traceback (most recent call last):
  1130 +</pre>
  1131 +
  1132 +
  1133 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 59, in testPartExecutor
  1134 + yield
  1135 +</pre>
  1136 +
  1137 +
  1138 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 615, in run
  1139 + testMethod()
  1140 +</pre>
  1141 +
  1142 +
  1143 + <pre> File "/Users/shitou/工作/code/work/workAi/yxly/common/myddt.py", line 145, in wrapper
  1144 + return func(self, *args, **kwargs)
  1145 +</pre>
  1146 +
  1147 +
  1148 + <pre> File "/Users/shitou/工作/code/work/workAi/yxly/testcase/test_02_system_management.py", line 146, in test_add_specialty
  1149 + raise e
  1150 +</pre>
  1151 +
  1152 +
  1153 + <pre> File "/Users/shitou/工作/code/work/workAi/yxly/testcase/test_02_system_management.py", line 140, in test_add_specialty
  1154 + self.assertEqual(expected["msg"], res["msg"])
  1155 +</pre>
  1156 +
  1157 +
  1158 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 839, in assertEqual
  1159 + assertion_func(first, second, msg=msg)
  1160 +</pre>
  1161 +
  1162 +
  1163 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 1220, in assertMultiLineEqual
  1164 + self.fail(self._formatMessage(msg, standardMsg))
  1165 +</pre>
  1166 +
  1167 +
  1168 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 680, in fail
  1169 + raise self.failureException(msg)
  1170 +</pre>
  1171 +
  1172 +
  1173 + <pre>AssertionError: '专业名称未填写' != 'size must be between 1 and 30'
  1174 +- 专业名称未填写
  1175 ++ size must be between 1 and 30
  1176 +
  1177 +</pre>
  1178 +
  1179 +
  1180 + </td>
  1181 + </tr>
  1182 +
  1183 + <tr>
  1184 + <td>17</td>
  1185 + <td class="Test02Specialty">Test02Specialty</td>
  1186 + <td>test_add_specialty_05</td>
  1187 + <td>新增专业失败,专业名称长度不能大于30</td>
  1188 + <td>0.228s</td>
  1189 +
  1190 + <td class="text-warning">失败</td>
  1191 +
  1192 + <td>
  1193 + <button type="button" class="btn btn-success btn_info">查看详情</button>
  1194 + </td>
  1195 + </tr>
  1196 +
  1197 + <tr class="test_log">
  1198 +
  1199 + <td colspan="7" class="small text-muted" style=" word-wrap:break-word; word-break:break-all">
  1200 +
  1201 +
  1202 + <pre>用例入参:{'name': '专业大于301234567890专业大于301234567890', 'code': 'py_code21:35:18_5', 'departmentId': '1597509063577825282', 'category': 'science'}
  1203 +预期结果: {'msg': '专业名称不能大于30', 'code': 500, 'data': None}
  1204 +实际结果: {'msg': 'size must be between 1 and 30', 'code': 500, 'data': None}
  1205 +test_add_specialty_05 (test_02_system_management.Test02Specialty)执行——>【失败】
  1206 +</pre>
  1207 +
  1208 +
  1209 + <pre>Traceback (most recent call last):
  1210 +</pre>
  1211 +
  1212 +
  1213 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 59, in testPartExecutor
  1214 + yield
  1215 +</pre>
  1216 +
  1217 +
  1218 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 615, in run
  1219 + testMethod()
  1220 +</pre>
  1221 +
  1222 +
  1223 + <pre> File "/Users/shitou/工作/code/work/workAi/yxly/common/myddt.py", line 145, in wrapper
  1224 + return func(self, *args, **kwargs)
  1225 +</pre>
  1226 +
  1227 +
  1228 + <pre> File "/Users/shitou/工作/code/work/workAi/yxly/testcase/test_02_system_management.py", line 146, in test_add_specialty
  1229 + raise e
  1230 +</pre>
  1231 +
  1232 +
  1233 + <pre> File "/Users/shitou/工作/code/work/workAi/yxly/testcase/test_02_system_management.py", line 140, in test_add_specialty
  1234 + self.assertEqual(expected["msg"], res["msg"])
  1235 +</pre>
  1236 +
  1237 +
  1238 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 839, in assertEqual
  1239 + assertion_func(first, second, msg=msg)
  1240 +</pre>
  1241 +
  1242 +
  1243 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 1220, in assertMultiLineEqual
  1244 + self.fail(self._formatMessage(msg, standardMsg))
  1245 +</pre>
  1246 +
  1247 +
  1248 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 680, in fail
  1249 + raise self.failureException(msg)
  1250 +</pre>
  1251 +
  1252 +
  1253 + <pre>AssertionError: '专业名称不能大于30' != 'size must be between 1 and 30'
  1254 +- 专业名称不能大于30
  1255 ++ size must be between 1 and 30
  1256 +
  1257 +</pre>
  1258 +
  1259 +
  1260 + </td>
  1261 + </tr>
  1262 +
  1263 + <tr>
  1264 + <td>18</td>
  1265 + <td class="Test02Specialty">Test02Specialty</td>
  1266 + <td>test_add_specialty_06</td>
  1267 + <td>新增专业失败,专业名称重复</td>
  1268 + <td>0.217s</td>
  1269 +
  1270 + <td class="text-success">成功</td>
  1271 +
  1272 + <td>
  1273 + <button type="button" class="btn btn-success btn_info">查看详情</button>
  1274 + </td>
  1275 + </tr>
  1276 +
  1277 + <tr class="test_log">
  1278 +
  1279 + <td colspan="7" class="small text-muted" style=" word-wrap:break-word; word-break:break-all">
  1280 +
  1281 +
  1282 + <pre>用例入参:{'name': '第二个专业-2-1', 'code': 'py_code21:35:18_6', 'departmentId': '1597509063577825282', 'category': 'science'}
  1283 +预期结果: {'msg': '专业名称已存在,请确认', 'code': 500, 'data': None}
  1284 +实际结果: {'msg': '专业名称已存在,请确认', 'code': 500, 'data': None}
  1285 +test_add_specialty_06 (test_02_system_management.Test02Specialty)执行——>【通过】
  1286 +</pre>
  1287 +
  1288 +
  1289 + </td>
  1290 + </tr>
  1291 +
  1292 + <tr>
  1293 + <td>19</td>
  1294 + <td class="Test02Specialty">Test02Specialty</td>
  1295 + <td>test_add_specialty_07</td>
  1296 + <td>新增专业失败,专业代码未填写</td>
  1297 + <td>0.193s</td>
  1298 +
  1299 + <td class="text-warning">失败</td>
  1300 +
  1301 + <td>
  1302 + <button type="button" class="btn btn-success btn_info">查看详情</button>
  1303 + </td>
  1304 + </tr>
  1305 +
  1306 + <tr class="test_log">
  1307 +
  1308 + <td colspan="7" class="small text-muted" style=" word-wrap:break-word; word-break:break-all">
  1309 +
  1310 +
  1311 + <pre>用例入参:{'name': 'py专业21:35:18_7', 'code': '', 'departmentId': '1597509063577825282', 'category': 'science'}
  1312 +预期结果: {'msg': '专业代码不能为空', 'code': 500, 'data': None}
  1313 +实际结果: {'msg': 'size must be between 1 and 30', 'code': 500, 'data': None}
  1314 +test_add_specialty_07 (test_02_system_management.Test02Specialty)执行——>【失败】
  1315 +</pre>
  1316 +
  1317 +
  1318 + <pre>Traceback (most recent call last):
  1319 +</pre>
  1320 +
  1321 +
  1322 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 59, in testPartExecutor
  1323 + yield
  1324 +</pre>
  1325 +
  1326 +
  1327 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 615, in run
  1328 + testMethod()
  1329 +</pre>
  1330 +
  1331 +
  1332 + <pre> File "/Users/shitou/工作/code/work/workAi/yxly/common/myddt.py", line 145, in wrapper
  1333 + return func(self, *args, **kwargs)
  1334 +</pre>
  1335 +
  1336 +
  1337 + <pre> File "/Users/shitou/工作/code/work/workAi/yxly/testcase/test_02_system_management.py", line 146, in test_add_specialty
  1338 + raise e
  1339 +</pre>
  1340 +
  1341 +
  1342 + <pre> File "/Users/shitou/工作/code/work/workAi/yxly/testcase/test_02_system_management.py", line 140, in test_add_specialty
  1343 + self.assertEqual(expected["msg"], res["msg"])
  1344 +</pre>
  1345 +
  1346 +
  1347 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 839, in assertEqual
  1348 + assertion_func(first, second, msg=msg)
  1349 +</pre>
  1350 +
  1351 +
  1352 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 1220, in assertMultiLineEqual
  1353 + self.fail(self._formatMessage(msg, standardMsg))
  1354 +</pre>
  1355 +
  1356 +
  1357 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 680, in fail
  1358 + raise self.failureException(msg)
  1359 +</pre>
  1360 +
  1361 +
  1362 + <pre>AssertionError: '专业代码不能为空' != 'size must be between 1 and 30'
  1363 +- 专业代码不能为空
  1364 ++ size must be between 1 and 30
  1365 +
  1366 +</pre>
  1367 +
  1368 +
  1369 + </td>
  1370 + </tr>
  1371 +
  1372 + <tr>
  1373 + <td>20</td>
  1374 + <td class="Test02Specialty">Test02Specialty</td>
  1375 + <td>test_add_specialty_08</td>
  1376 + <td>新增专业失败,专业代码长度不能大于30</td>
  1377 + <td>0.223s</td>
  1378 +
  1379 + <td class="text-warning">失败</td>
  1380 +
  1381 + <td>
  1382 + <button type="button" class="btn btn-success btn_info">查看详情</button>
  1383 + </td>
  1384 + </tr>
  1385 +
  1386 + <tr class="test_log">
  1387 +
  1388 + <td colspan="7" class="small text-muted" style=" word-wrap:break-word; word-break:break-all">
  1389 +
  1390 +
  1391 + <pre>用例入参:{'name': 'py专业21:35:18_8', 'code': '专业代码大于301234567890专业大于301234567890', 'departmentId': '1597509063577825282', 'category': 'science'}
  1392 +预期结果: {'msg': '专业代码不能大于30', 'code': 500, 'data': None}
  1393 +实际结果: {'msg': 'size must be between 1 and 30', 'code': 500, 'data': None}
  1394 +test_add_specialty_08 (test_02_system_management.Test02Specialty)执行——>【失败】
  1395 +</pre>
  1396 +
  1397 +
  1398 + <pre>Traceback (most recent call last):
  1399 +</pre>
  1400 +
  1401 +
  1402 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 59, in testPartExecutor
  1403 + yield
  1404 +</pre>
  1405 +
  1406 +
  1407 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 615, in run
  1408 + testMethod()
  1409 +</pre>
  1410 +
  1411 +
  1412 + <pre> File "/Users/shitou/工作/code/work/workAi/yxly/common/myddt.py", line 145, in wrapper
  1413 + return func(self, *args, **kwargs)
  1414 +</pre>
  1415 +
  1416 +
  1417 + <pre> File "/Users/shitou/工作/code/work/workAi/yxly/testcase/test_02_system_management.py", line 146, in test_add_specialty
  1418 + raise e
  1419 +</pre>
  1420 +
  1421 +
  1422 + <pre> File "/Users/shitou/工作/code/work/workAi/yxly/testcase/test_02_system_management.py", line 140, in test_add_specialty
  1423 + self.assertEqual(expected["msg"], res["msg"])
  1424 +</pre>
  1425 +
  1426 +
  1427 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 839, in assertEqual
  1428 + assertion_func(first, second, msg=msg)
  1429 +</pre>
  1430 +
  1431 +
  1432 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 1220, in assertMultiLineEqual
  1433 + self.fail(self._formatMessage(msg, standardMsg))
  1434 +</pre>
  1435 +
  1436 +
  1437 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 680, in fail
  1438 + raise self.failureException(msg)
  1439 +</pre>
  1440 +
  1441 +
  1442 + <pre>AssertionError: '专业代码不能大于30' != 'size must be between 1 and 30'
  1443 +- 专业代码不能大于30
  1444 ++ size must be between 1 and 30
  1445 +
  1446 +</pre>
  1447 +
  1448 +
  1449 + </td>
  1450 + </tr>
  1451 +
  1452 + <tr>
  1453 + <td>21</td>
  1454 + <td class="Test02Specialty">Test02Specialty</td>
  1455 + <td>test_add_specialty_09</td>
  1456 + <td>新增专业失败,学科门类未填写</td>
  1457 + <td>0.222s</td>
  1458 +
  1459 + <td class="text-warning">失败</td>
  1460 +
  1461 + <td>
  1462 + <button type="button" class="btn btn-success btn_info">查看详情</button>
  1463 + </td>
  1464 + </tr>
  1465 +
  1466 + <tr class="test_log">
  1467 +
  1468 + <td colspan="7" class="small text-muted" style=" word-wrap:break-word; word-break:break-all">
  1469 +
  1470 +
  1471 + <pre>用例入参:{'name': 'py专业21:35:19_9', 'code': 'py_code21:35:19_9', 'departmentId': '1597509063577825282', 'category': ''}
  1472 +预期结果: {'msg': '学科门类不能为空', 'code': 500, 'data': None}
  1473 +实际结果: {'msg': 'success', 'code': 200, 'data': True}
  1474 +test_add_specialty_09 (test_02_system_management.Test02Specialty)执行——>【失败】
  1475 +</pre>
  1476 +
  1477 +
  1478 + <pre>Traceback (most recent call last):
  1479 +</pre>
  1480 +
  1481 +
  1482 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 59, in testPartExecutor
  1483 + yield
  1484 +</pre>
  1485 +
  1486 +
  1487 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 615, in run
  1488 + testMethod()
  1489 +</pre>
  1490 +
  1491 +
  1492 + <pre> File "/Users/shitou/工作/code/work/workAi/yxly/common/myddt.py", line 145, in wrapper
  1493 + return func(self, *args, **kwargs)
  1494 +</pre>
  1495 +
  1496 +
  1497 + <pre> File "/Users/shitou/工作/code/work/workAi/yxly/testcase/test_02_system_management.py", line 146, in test_add_specialty
  1498 + raise e
  1499 +</pre>
  1500 +
  1501 +
  1502 + <pre> File "/Users/shitou/工作/code/work/workAi/yxly/testcase/test_02_system_management.py", line 140, in test_add_specialty
  1503 + self.assertEqual(expected["msg"], res["msg"])
  1504 +</pre>
  1505 +
  1506 +
  1507 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 839, in assertEqual
  1508 + assertion_func(first, second, msg=msg)
  1509 +</pre>
  1510 +
  1511 +
  1512 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 1220, in assertMultiLineEqual
  1513 + self.fail(self._formatMessage(msg, standardMsg))
  1514 +</pre>
  1515 +
  1516 +
  1517 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 680, in fail
  1518 + raise self.failureException(msg)
  1519 +</pre>
  1520 +
  1521 +
  1522 + <pre>AssertionError: '学科门类不能为空' != 'success'
  1523 +- 学科门类不能为空
  1524 ++ success
  1525 +
  1526 +</pre>
  1527 +
  1528 +
  1529 + </td>
  1530 + </tr>
  1531 +
  1532 + <tr>
  1533 + <td>22</td>
  1534 + <td class="Test02Specialty">Test02Specialty</td>
  1535 + <td>test_add_specialty_10</td>
  1536 + <td>新增专业失败,学科门类填写错误</td>
  1537 + <td>0.243s</td>
  1538 +
  1539 + <td class="text-warning">失败</td>
  1540 +
  1541 + <td>
  1542 + <button type="button" class="btn btn-success btn_info">查看详情</button>
  1543 + </td>
  1544 + </tr>
  1545 +
  1546 + <tr class="test_log">
  1547 +
  1548 + <td colspan="7" class="small text-muted" style=" word-wrap:break-word; word-break:break-all">
  1549 +
  1550 +
  1551 + <pre>用例入参:{'name': 'py专业21:35:19_10', 'code': 'py_code21:35:19_10', 'departmentId': '1597509063577825282', 'category': 'scienwce'}
  1552 +预期结果: {'msg': '学科门类不存在', 'code': 500, 'data': None}
  1553 +实际结果: {'msg': 'success', 'code': 200, 'data': True}
  1554 +test_add_specialty_10 (test_02_system_management.Test02Specialty)执行——>【失败】
  1555 +</pre>
  1556 +
  1557 +
  1558 + <pre>Traceback (most recent call last):
  1559 +</pre>
  1560 +
  1561 +
  1562 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 59, in testPartExecutor
  1563 + yield
  1564 +</pre>
  1565 +
  1566 +
  1567 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 615, in run
  1568 + testMethod()
  1569 +</pre>
  1570 +
  1571 +
  1572 + <pre> File "/Users/shitou/工作/code/work/workAi/yxly/common/myddt.py", line 145, in wrapper
  1573 + return func(self, *args, **kwargs)
  1574 +</pre>
  1575 +
  1576 +
  1577 + <pre> File "/Users/shitou/工作/code/work/workAi/yxly/testcase/test_02_system_management.py", line 146, in test_add_specialty
  1578 + raise e
  1579 +</pre>
  1580 +
  1581 +
  1582 + <pre> File "/Users/shitou/工作/code/work/workAi/yxly/testcase/test_02_system_management.py", line 140, in test_add_specialty
  1583 + self.assertEqual(expected["msg"], res["msg"])
  1584 +</pre>
  1585 +
  1586 +
  1587 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 839, in assertEqual
  1588 + assertion_func(first, second, msg=msg)
  1589 +</pre>
  1590 +
  1591 +
  1592 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 1220, in assertMultiLineEqual
  1593 + self.fail(self._formatMessage(msg, standardMsg))
  1594 +</pre>
  1595 +
  1596 +
  1597 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 680, in fail
  1598 + raise self.failureException(msg)
  1599 +</pre>
  1600 +
  1601 +
  1602 + <pre>AssertionError: '学科门类不存在' != 'success'
  1603 +- 学科门类不存在
  1604 ++ success
  1605 +
  1606 +</pre>
  1607 +
  1608 +
  1609 + </td>
  1610 + </tr>
  1611 +
  1612 + <tr>
  1613 + <td>23</td>
  1614 + <td class="Test03Year">Test03Year</td>
  1615 + <td>test_add_year_1</td>
  1616 + <td>新增学年学期成功</td>
  1617 + <td>0.219s</td>
  1618 +
  1619 + <td class="text-success">成功</td>
  1620 +
  1621 + <td>
  1622 + <button type="button" class="btn btn-success btn_info">查看详情</button>
  1623 + </td>
  1624 + </tr>
  1625 +
  1626 + <tr class="test_log">
  1627 +
  1628 + <td colspan="7" class="small text-muted" style=" word-wrap:break-word; word-break:break-all">
  1629 +
  1630 +
  1631 + <pre>用例入参:{'year': 'py学年21:35:20_1', 'remark': 'py_comment备注21:35:20_1', 'terms': [{'sort': 1, 'startTime': 1667376499000, 'endTime': 1704115459000}]}
  1632 +预期结果: {'msg': 'success', 'code': 200, 'data': True}
  1633 +实际结果: {'msg': 'success', 'code': 200, 'data': True}
  1634 +test_add_year_1 (test_02_system_management.Test03Year)执行——>【通过】
  1635 +</pre>
  1636 +
  1637 +
  1638 + </td>
  1639 + </tr>
  1640 +
  1641 + <tr>
  1642 + <td>24</td>
  1643 + <td class="Test03Year">Test03Year</td>
  1644 + <td>test_add_year_2</td>
  1645 + <td>学年学期开始时间和结束时间不可交叉</td>
  1646 + <td>0.227s</td>
  1647 +
  1648 + <td class="text-warning">失败</td>
  1649 +
  1650 + <td>
  1651 + <button type="button" class="btn btn-success btn_info">查看详情</button>
  1652 + </td>
  1653 + </tr>
  1654 +
  1655 + <tr class="test_log">
  1656 +
  1657 + <td colspan="7" class="small text-muted" style=" word-wrap:break-word; word-break:break-all">
  1658 +
  1659 +
  1660 + <pre>用例入参:{'year': 'py学年21:35:20_2', 'remark': 'py_comment备注21:35:20_2', 'terms': [{'sort': 1, 'startTime': 1667376499000, 'endTime': 1704115459000}, {'sort': 2, 'startTime': 1667376499000, 'endTime': 1704115459000}]}
  1661 +预期结果: {'msg': '学期起止时间不能交叉', 'code': 500, 'data': None}
  1662 +实际结果: {'msg': 'success', 'code': 200, 'data': True}
  1663 +test_add_year_2 (test_02_system_management.Test03Year)执行——>【失败】
  1664 +</pre>
  1665 +
  1666 +
  1667 + <pre>Traceback (most recent call last):
  1668 +</pre>
  1669 +
  1670 +
  1671 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 59, in testPartExecutor
  1672 + yield
  1673 +</pre>
  1674 +
  1675 +
  1676 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 615, in run
  1677 + testMethod()
  1678 +</pre>
  1679 +
  1680 +
  1681 + <pre> File "/Users/shitou/工作/code/work/workAi/yxly/common/myddt.py", line 145, in wrapper
  1682 + return func(self, *args, **kwargs)
  1683 +</pre>
  1684 +
  1685 +
  1686 + <pre> File "/Users/shitou/工作/code/work/workAi/yxly/testcase/test_02_system_management.py", line 205, in test_add_year
  1687 + raise e
  1688 +</pre>
  1689 +
  1690 +
  1691 + <pre> File "/Users/shitou/工作/code/work/workAi/yxly/testcase/test_02_system_management.py", line 199, in test_add_year
  1692 + self.assertEqual(expected["msg"], res["msg"])
  1693 +</pre>
  1694 +
  1695 +
  1696 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 839, in assertEqual
  1697 + assertion_func(first, second, msg=msg)
  1698 +</pre>
  1699 +
  1700 +
  1701 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 1220, in assertMultiLineEqual
  1702 + self.fail(self._formatMessage(msg, standardMsg))
  1703 +</pre>
  1704 +
  1705 +
  1706 + <pre> File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 680, in fail
  1707 + raise self.failureException(msg)
  1708 +</pre>
  1709 +
  1710 +
  1711 + <pre>AssertionError: '学期起止时间不能交叉' != 'success'
  1712 +- 学期起止时间不能交叉
  1713 ++ success
  1714 +
  1715 +</pre>
  1716 +
  1717 +
  1718 + </td>
  1719 + </tr>
  1720 +
  1721 +
  1722 + </tbody>
  1723 + </table>
  1724 + </div>
  1725 +
  1726 + <div style="height: 200px"></div>
  1727 +</div>
  1728 +
  1729 +
  1730 +<script>
  1731 + var tbodyTr = $('tbody tr');
  1732 + var testResult = $("#testResult");
  1733 + var testClass = $("#testClass");
  1734 + <!-- 用例执行详细信息显示切换-->
  1735 + $(".btn_info").click(function () {
  1736 + $(this).parent().parent().next().toggle();
  1737 +
  1738 + });
  1739 + // 当选择用例类之后触发
  1740 + testClass.change(function () {
  1741 + var cls = $(this).val();
  1742 + var res = testResult.val();
  1743 + elementDisplay(cls, res);
  1744 + sort()
  1745 + });
  1746 + testResult.change(function () {
  1747 + var res = $(this).val();
  1748 + var cls = testClass.val();
  1749 + elementDisplay(cls, res);
  1750 + sort()
  1751 + });
  1752 +
  1753 + function elementDisplay(cls, res) {
  1754 + // 用例数据的显示
  1755 + if (cls === "所有") {
  1756 + if (res === "所有") {
  1757 + tbodyTr.has('button').show();
  1758 + } else if (res === '成功') {
  1759 + tbodyTr.hide();
  1760 + tbodyTr.has('button').has('.text-success').show()
  1761 +
  1762 + } else if (res === '失败') {
  1763 + tbodyTr.hide();
  1764 + tbodyTr.has('button').has('.text-warning').show()
  1765 +
  1766 + } else if (res === '错误') {
  1767 + tbodyTr.hide();
  1768 + tbodyTr.has('button').has('.text-danger').show()
  1769 +
  1770 + } else if (res === '跳过') {
  1771 + tbodyTr.hide();
  1772 + tbodyTr.has('button').has('.text-info').show()
  1773 + }
  1774 + } else {
  1775 + if (res === "所有") {
  1776 + tbodyTr.hide();
  1777 + tbodyTr.has('button').has('.' + cls + '').show()
  1778 + } else if (res === '成功') {
  1779 + tbodyTr.hide();
  1780 + tbodyTr.has('button').has('.' + cls + '').has('.text-success').show()
  1781 + } else if (res === '失败') {
  1782 + tbodyTr.hide();
  1783 + tbodyTr.has('button').has('.' + cls + '').has('.text-warning').show()
  1784 + } else if (res === '错误') {
  1785 + tbodyTr.hide();
  1786 + tbodyTr.has('button').has('.' + cls + '').has('.text-danger').show()
  1787 + } else if (res === '跳过') {
  1788 + tbodyTr.hide();
  1789 + tbodyTr.has('button').has('.' + cls + '').has('.text-info').show()
  1790 + }
  1791 + }
  1792 + }
  1793 +
  1794 + function sort() {
  1795 + //重新排列显示序号
  1796 + // 选择所有可以见的tr
  1797 + var visibleTr = tbodyTr.filter(":visible");
  1798 +
  1799 + visibleTr.each(function (index, element) {
  1800 + element.firstElementChild.innerHTML = index + 1;
  1801 +
  1802 + })
  1803 +
  1804 + }
  1805 +
  1806 +
  1807 +</script>
  1808 +
  1809 +<script type="text/javascript">
  1810 + // 基于准备好的dom,初始化echarts实例
  1811 + var myChart = echarts.init(document.getElementById('char'));
  1812 + var myChart2 = echarts.init(document.getElementById('char2'));
  1813 + // 指定图表的配置项和数据
  1814 + option = {
  1815 + color: ['#00a10a', '#ddb518', 'rgba(204,46,41,0.73)', '#85898c'],
  1816 + tooltip: {
  1817 + trigger: 'item',
  1818 + formatter: '{a} <br/>{b}: {c} ({d}%)'
  1819 + },
  1820 + legend: {
  1821 + orient: 'vertical',
  1822 + left: 10,
  1823 + data: ['通过', '失败', '错误', '跳过']
  1824 + },
  1825 + series: [
  1826 + {
  1827 + name: '测试结果',
  1828 + type: 'pie',
  1829 + radius: ['50%', '70%'],
  1830 + avoidLabelOverlap: false,
  1831 + label: {
  1832 + show: false,
  1833 + position: 'center'
  1834 + },
  1835 + emphasis: {
  1836 + label: {
  1837 + show: true,
  1838 + fontSize: '30',
  1839 + fontWeight: 'bold'
  1840 + }
  1841 + },
  1842 + labelLine: {
  1843 + show: false
  1844 + },
  1845 + data: [
  1846 + {value: 9, name: '通过'},
  1847 + {value: 15, name: '失败'},
  1848 + {value: 0, name: '错误'},
  1849 + {value: 0, name: '跳过'}
  1850 + ]
  1851 + }
  1852 + ]
  1853 + };
  1854 + option2 = {
  1855 + tooltip: {
  1856 + formatter: '{a} <br/>{b} : {c}%'
  1857 + },
  1858 + toolbox: {
  1859 + feature: {
  1860 + restore: {},
  1861 + saveAsImage: {}
  1862 + }
  1863 + },
  1864 + series: [
  1865 + {
  1866 + name: '测试结果',
  1867 + type: 'gauge',
  1868 + detail: {formatter: '37.50%'},
  1869 + data: [{value: '37.50', name: '用例通过率'}],
  1870 + axisLine: {
  1871 + lineStyle: {
  1872 + color: [
  1873 + [0.2, '#c20000'],
  1874 + [0.8, '#ddb518'],
  1875 + [1, '#00a10a']]
  1876 + }
  1877 + }
  1878 + }
  1879 + ]
  1880 + };
  1881 +
  1882 +
  1883 + myChart2.setOption(option2);
  1884 + // 使用刚指定的配置项和数据显示图表。
  1885 + myChart.setOption(option);
  1886 +</script>
  1887 +
  1888 +
  1889 +</body>
  1890 +</html>
  1 +#!/usr/bin/env python3
  2 +# -*- coding: utf-8 -*-
  3 +# @Time : 2022/12/8 21:52
  4 +# @Author : Shitou
  5 +# @FileName: run.py
  6 +# @Software: PyCharm
  7 +
  8 +import unittest
  9 +from unittestreport import TestRunner
  10 +from common.handle_path import TestCase_Path, Report_Path
  11 +from common.handle_config import conf
  12 +
  13 +# 创建测试套件
  14 +suite = unittest.TestSuite()
  15 +# 加载用例
  16 +# ---创建加载器
  17 +load = unittest.TestLoader()
  18 +# ---用例放到加载器
  19 +suite.addTest(load.discover(TestCase_Path))
  20 +
  21 +# 运行
  22 +runner = TestRunner(suite=suite,
  23 + filename=conf.get("report", "filename"),
  24 + report_dir=Report_Path,
  25 + title=conf.get("report", "title"),
  26 + tester=conf.get("report", "tester"),
  27 + desc=conf.get("report", "desc"),
  28 + templates=conf.getint("report", "templates")
  29 + )
  30 +runner.run()
  31 +# 执行失败重新运行机制
  32 +# runner.rerun_run(count=2, interval=3)
  33 +"""
  34 +发送邮件
  35 +"""
  36 +# QQ邮箱SMTP服务器地址为“smtp.qq.com”
  37 +# 163邮箱smtp.163.com 465
  38 +# 阿里云smtp.qiye.aliyun.com 465
  39 +runner.send_email(host="smtp.qiye.aliyun.com",
  40 + port=465,
  41 + user="shishut@workai.com.cn",
  42 + password="mKh50p89DqvqJ7pd",
  43 + to_addrs=["1171621168@qq.com", "1109927930@qq.com", "shishut@workai.com.cn"]
  44 + )
  1 +#!/usr/bin/env python3
  2 +# -*- coding: utf-8 -*-
  3 +# @Time : 2022/12/8 21:53
  4 +# @Author : Shitou
  5 +# @FileName: test_login.py
  6 +# @Software: PyCharm
  7 +"""
  8 +优秀学乐业----登陆测试用例
  9 +"""
  10 +import json
  11 +import os
  12 +import unittest
  13 +import requests
  14 +from common import myddt
  15 +from common.handle_excel import Excel
  16 +from common.handle_log import HandleLog
  17 +from common.handle_path import DataExcel_Path
  18 +from jsonpath import jsonpath
  19 +from common.handle_config import conf
  20 +
  21 +headers = {
  22 + "Authorization": "Basic" + " d29ya2FpOjEyMzQ1Ng=="
  23 +}
  24 +
  25 +
  26 +@myddt.ddt
  27 +class TestLogin(unittest.TestCase):
  28 + open_excel = Excel(os.path.join(DataExcel_Path, "test_01_login.xlsx"), "login")
  29 + test_case = open_excel.read_excel()
  30 +
  31 + @myddt.data(*test_case)
  32 + def test_login(self, case):
  33 +
  34 + # 准备数据
  35 + data = eval(case['data'])
  36 + expected = json.loads(case['expected'])
  37 + # 请求接口
  38 + url = conf.get("url", "url_ip") + case['url']
  39 + method = case['method']
  40 + # req = requests.request(method=method, url=url, json=data, headers=headers)
  41 + req = requests.post(url=url, json=data, headers=headers)
  42 + res = req.json()
  43 + # 将数据在测试报告中进行展示
  44 + print("用例入参:{}".format(data))
  45 + print("预期结果:{}".format(expected))
  46 + print("实际结果:{}".format(res))
  47 + # 断言
  48 + try:
  49 + self.assertEqual(expected['msg'], res['msg'])
  50 + self.assertEqual(expected['code'], res['code'])
  51 + except AssertionError as e:
  52 + # 结果写入到excel中
  53 + self.open_excel.write_excel(row=case['id'] + 1, column=7, value="不通过")
  54 + HandleLog.log.error("用例标题{},不通过".format(case['title']))
  55 + # 将异常信息输出到日志,等级为Error
  56 + HandleLog.log.exception(e)
  57 + raise e
  58 + else:
  59 + # 结果写入到excel中
  60 + self.open_excel.write_excel(row=case['id'] + 1, column=7, value="通过")
  61 + HandleLog.log.error("用例标题{},通过".format(case['title']))
  62 +
  1 +#!/usr/bin/env python3
  2 +# -*- coding: utf-8 -*-
  3 +# @Time : 2022/12/8 23:53
  4 +# @Author : Shitou
  5 +# @FileName: test_02_department.xlsx.py
  6 +# @Software: PyCharm
  7 +
  8 +"""
  9 +系统管理菜单用例
  10 +"""
  11 +import json
  12 +import os
  13 +import unittest
  14 +import requests
  15 +import time
  16 +from common import myddt
  17 +from common.handle_excel import Excel
  18 +from common.handle_log import HandleLog
  19 +from common.handle_path import DataExcel_Path
  20 +from common.handle_config import conf
  21 +from tools.handle_token import LoginToken
  22 +
  23 +
  24 +# 系统管理相关的用例目录
  25 +System_path = os.path.join(DataExcel_Path, "system")
  26 +
  27 +
  28 +# 院系相关的用例
  29 +@myddt.ddt
  30 +class Test01Department(unittest.TestCase):
  31 + """院系"""
  32 +
  33 + open_excel = Excel(os.path.join(System_path, "test_02_department.xlsx"), "add_department")
  34 + test_case = open_excel.read_excel()
  35 +
  36 + @classmethod
  37 + def setUpClass(cls):
  38 + """
  39 + 用例类执行前执行的函数
  40 + :return:token
  41 + """
  42 + # 获取token
  43 + cls.token = LoginToken.login_token()
  44 +
  45 + def setUp(self):
  46 + """单条用例执行前执行的函数"""
  47 + new_time = time.strftime("%Y%m%d_%H:%M:%S")
  48 + # 随机院系名称
  49 + self.department_name = "py自动化院系" + new_time
  50 + # 随机院系代码
  51 + self.department_code = "py_code" + new_time
  52 +
  53 + @myddt.data(*test_case)
  54 + def test_add_department(self, case):
  55 + """新增院系"""
  56 + url = conf.get("url", "url_ip") + case['url']
  57 + # 准备数据
  58 + # -----写入数据
  59 + if "#department#" in case["data"]:
  60 + case["data"] = case["data"].replace("#department#", self.department_name + "_" + str(case["id"]))
  61 + if "#department_code#" in case["data"]:
  62 + case["data"] = case["data"].replace("#department_code#", self.department_code + "_" + str(case["id"]))
  63 + data = json.loads(case['data'])
  64 + # -----预期结果
  65 + expected = json.loads(case['expected'])
  66 + # 调用接口
  67 + # 请求头
  68 + headers = {}
  69 + headers["Authorization"] = self.token
  70 + response = requests.request(method=case["method"], url=url, json=data, headers=headers)
  71 + res = response.json()
  72 + print("用例入参:{}".format(data))
  73 + print("预期结果:", expected)
  74 + print("实际结果:", res)
  75 + # 断言
  76 + try:
  77 + self.assertEqual(expected['msg'], res['msg'])
  78 + self.assertEqual(expected['code'], res['code'])
  79 + except AssertionError as e:
  80 + # 写入Excel
  81 + self.open_excel.write_excel(row=case["id"] + 1, column=7, value="不通过")
  82 + HandleLog.log.error("用例标题{},不通过".format(case['title']))
  83 + HandleLog.log.exception(e)
  84 + raise e
  85 + else:
  86 + self.open_excel.write_excel(row=case["id"] + 1, column=7, value="通过")
  87 + # 将创建使用的数据写入到excel表格中
  88 + self.open_excel.write_excel(row=case["id"] + 1, column=9,
  89 + value=case["data"])
  90 + HandleLog.log.info("用例{},执行通过".format(case["title"]))
  91 +
  92 +
  93 +# 专业相关的用例
  94 +@myddt.ddt
  95 +class Test02Specialty(unittest.TestCase):
  96 + """专业相关的用例"""
  97 + open_speciality_excel = Excel(os.path.join(System_path, "test_03_specialty.xlsx"), "add_specialty")
  98 + test_data = open_speciality_excel.read_excel()
  99 +
  100 + @classmethod
  101 + def setUpClass(cls):
  102 + """
  103 + :return: token
  104 + """
  105 + # 获取token
  106 + cls.token = LoginToken.login_token()
  107 +
  108 + def setUp(self):
  109 + """单条用例执行前执行的函数"""
  110 + new_time = time.strftime("%H:%M:%S")
  111 + # 随机专业名称
  112 + self.specialty_name = "py专业" + new_time
  113 + # 随机专业代码
  114 + self.specialty_code = "py_code" + new_time
  115 +
  116 + @myddt.data(*test_data)
  117 + def test_add_specialty(self, case):
  118 + """新增专业"""
  119 + # 准备数据
  120 + # --写入数据
  121 + if "#specialty_name#" in case["data"]:
  122 + case["data"] = case["data"].replace("#specialty_name#", self.specialty_name + "_" + str(case["id"]))
  123 + if "#specialty_code#" in case["data"]:
  124 + case["data"] = case["data"].replace("#specialty_code#", self.specialty_code + "_" + str(case["id"]))
  125 + data = json.loads(case["data"])
  126 + # --预期结果
  127 + expected = json.loads(case["expected"])
  128 + # 调用接口
  129 + url = conf.get("url", "url_ip") + case["url"]
  130 +
  131 + headers = {}
  132 + headers["Authorization"] = self.token
  133 + req = requests.request(method=case["method"], url=url, json=data, headers=headers)
  134 + res = req.json()
  135 + print("用例入参:{}".format(data))
  136 + print("预期结果:", expected)
  137 + print("实际结果:", res)
  138 + # 断言
  139 + try:
  140 + self.assertEqual(expected["msg"], res["msg"])
  141 + self.assertEqual(expected["code"], res["code"])
  142 + except AssertionError as e:
  143 + self.open_speciality_excel.write_excel(row=case["id"] + 1, column=7, value="不通过")
  144 + HandleLog.log.error("用例标题{},不通过".format(case['title']))
  145 + HandleLog.log.exception(e)
  146 + raise e
  147 + else:
  148 + self.open_speciality_excel.write_excel(row=case["id"] + 1, column=7, value="通过")
  149 + HandleLog.log.info("用例{},执行通过".format(case["title"]))
  150 +
  151 +
  152 +# 校历(学年学期)相关的用例---2022 12.15
  153 +@myddt.ddt
  154 +class Test03Year(unittest.TestCase):
  155 + """校历相关的用例"""
  156 + open_year_excel = Excel(os.path.join(System_path, "test_04_term.xlsx"), "add_term")
  157 + test_data = open_year_excel.read_excel()
  158 +
  159 + @classmethod
  160 + def setUpClass(cls):
  161 + """
  162 + :return: token
  163 + """
  164 + # 获取token
  165 + cls.token = LoginToken.login_token()
  166 +
  167 + def setUp(self):
  168 + """单条用例执行前执行的函数"""
  169 + new_time = time.strftime("%H:%M:%S")
  170 + # 随机学年名称
  171 + self.year_name = "py学年" + new_time
  172 + # 随机学年备注
  173 + self.year_comment = "py_comment备注" + new_time
  174 +
  175 + @myddt.data(*test_data)
  176 + def test_add_year(self, case):
  177 + """新增专业"""
  178 + # 准备数据
  179 + # --写入数据
  180 + if "#year#" in case["data"]:
  181 + case["data"] = case["data"].replace("#year#", self.year_name + "_" + str(case["id"]))
  182 + if "#remark#" in case["data"]:
  183 + case["data"] = case["data"].replace("#remark#", self.year_comment + "_" + str(case["id"]))
  184 + data = json.loads(case["data"])
  185 + # --预期结果
  186 + expected = json.loads(case["expected"])
  187 + # 调用接口
  188 + url = conf.get("url", "url_ip") + case["url"]
  189 +
  190 + headers = {}
  191 + headers["Authorization"] = self.token
  192 + req = requests.request(method=case["method"], url=url, json=data, headers=headers)
  193 + res = req.json()
  194 + print("用例入参:{}".format(data))
  195 + print("预期结果:", expected)
  196 + print("实际结果:", res)
  197 + # 断言
  198 + try:
  199 + self.assertEqual(expected["msg"], res["msg"])
  200 + self.assertEqual(expected["code"], res["code"])
  201 + except AssertionError as e:
  202 + self.open_year_excel.write_excel(row=case["id"] + 1, column=7, value="不通过")
  203 + HandleLog.log.error("用例标题{},不通过".format(case['title']))
  204 + HandleLog.log.exception(e)
  205 + raise e
  206 + else:
  207 + self.open_year_excel.write_excel(row=case["id"] + 1, column=7, value="通过")
  208 + HandleLog.log.info("用例{},执行通过".format(case["title"]))
  1 +# -*- coding: utf-8 -*-
  2 +"""======================================
  3 +@Software: PyCharm
  4 +@Author : Shitou ✊
  5 +@Time : 2022/12/17 22:10
  6 +@FileName: test_03_teaching_affairs.py
  7 +====================================="""
  8 +"""
  9 +"""
  1 +#!/usr/bin/env python3
  2 +# -*- coding: utf-8 -*-
  3 +# @Time : 2022/12/15 22:55
  4 +# @Author : Shitou
  5 +# @FileName: handle_token.py
  6 +# @Software: PyCharm
  7 +
  8 +"""
  9 +登陆获取token
  10 +"""
  11 +import requests
  12 +from common.handle_config import conf
  13 +from jsonpath import jsonpath
  14 +
  15 +
  16 +class LoginToken:
  17 + def login_token():
  18 + # 登陆获取token
  19 + login_url = conf.get("url", "url_ip") + "/auth/v1/login"
  20 + headers = eval(conf.get('url', 'login_token'))
  21 + params = {
  22 + "way": conf.get('user_data', 'way'),
  23 + "password": conf.get('user_data', 'userpassword'),
  24 + "type": conf.get('user_data', 'type'),
  25 + "username": conf.get('user_data', 'username'),
  26 + }
  27 + response = requests.request(url=login_url, method="post", json=params, headers=headers)
  28 + res = response.json()
  29 + # 获取token
  30 + token = "Bearer" + " " + jsonpath(res, "$..access_token")[0]
  31 + return token
  32 +
  33 +
  34 +if __name__ == '__main__':
  35 + LoginToken.login_token()
注册登录 后发表评论