zhuzh hai 1 semana
pai
achega
1831af2ec1
Modificáronse 86 ficheiros con 5427 adicións e 0 borrados
  1. 18 0
      .gitignore
  2. 3 0
      .idea/.gitignore
  3. 10 0
      .idea/api-engine.iml
  4. 72 0
      .idea/inspectionProfiles/Project_Default.xml
  5. 6 0
      .idea/inspectionProfiles/profiles_settings.xml
  6. 4 0
      .idea/misc.xml
  7. 8 0
      .idea/modules.xml
  8. 194 0
      LICENSE
  9. 21 0
      apirun/Log/Log.py
  10. 0 0
      apirun/Log/__init__.py
  11. BIN=BIN
      apirun/Log/__pycache__/Log.cpython-39.pyc
  12. BIN=BIN
      apirun/Log/__pycache__/__init__.cpython-39.pyc
  13. 1 0
      apirun/__init__.py
  14. BIN=BIN
      apirun/__pycache__/__init__.cpython-39.pyc
  15. BIN=BIN
      apirun/__pycache__/conftest.cpython-39-pytest-8.0.2.pyc
  16. 97 0
      apirun/conftest.py
  17. 53 0
      apirun/core/ApiTestRunner.py
  18. 1 0
      apirun/core/__init__.py
  19. BIN=BIN
      apirun/core/__pycache__/ApiTestRunner.cpython-39-pytest-8.0.2.pyc
  20. BIN=BIN
      apirun/core/__pycache__/__init__.cpython-39.pyc
  21. BIN=BIN
      apirun/core/__pycache__/globalContext.cpython-39.pyc
  22. 24 0
      apirun/core/globalContext.py
  23. 1 0
      apirun/extend/__init__.py
  24. BIN=BIN
      apirun/extend/__pycache__/__init__.cpython-39.pyc
  25. BIN=BIN
      apirun/extend/__pycache__/keywords.cpython-39.pyc
  26. 323 0
      apirun/extend/keywords.py
  27. 41 0
      apirun/extend/keywords.yaml
  28. BIN=BIN
      apirun/files/20240725223321.png
  29. 2 0
      apirun/files/__init__.py
  30. 2740 0
      apirun/logdata.log
  31. 24 0
      apirun/parse/CaseParser.py
  32. 169 0
      apirun/parse/ExcelCaseParser.py
  33. 133 0
      apirun/parse/YamlCaseParser.py
  34. 1 0
      apirun/parse/__init__.py
  35. BIN=BIN
      apirun/parse/__pycache__/CaseParser.cpython-39.pyc
  36. BIN=BIN
      apirun/parse/__pycache__/ExcelCaseParser.cpython-39.pyc
  37. BIN=BIN
      apirun/parse/__pycache__/YamlCaseParser.cpython-39.pyc
  38. BIN=BIN
      apirun/parse/__pycache__/__init__.cpython-39.pyc
  39. 0 0
      apirun/parse/testlog.log
  40. 10 0
      apirun/pytest.ini
  41. 335 0
      apirun/testlog.log
  42. 31 0
      apirun/utils/DynamicTitle.py
  43. 44 0
      apirun/utils/VarRender.py
  44. 1 0
      apirun/utils/__init__.py
  45. BIN=BIN
      apirun/utils/__pycache__/DynamicTitle.cpython-39.pyc
  46. BIN=BIN
      apirun/utils/__pycache__/VarRender.cpython-39.pyc
  47. BIN=BIN
      apirun/utils/__pycache__/__init__.cpython-39.pyc
  48. 41 0
      cli.py
  49. 32 0
      examples/examples-ds/0_用户注册驱动.yaml
  50. 29 0
      examples/examples-ds/10_提交订单-购物车_json.yaml
  51. 33 0
      examples/examples-ds/11_提交订单-商品详情_json.yaml
  52. 27 0
      examples/examples-ds/12_加密接口.yaml
  53. BIN=BIN
      examples/examples-ds/1_测试用例.xlsx
  54. 60 0
      examples/examples-ds/1_登录接口数据驱动.yaml
  55. 37 0
      examples/examples-ds/2_登录成功测试用例.yaml
  56. 33 0
      examples/examples-ds/3_加入购物车成功-表单.yaml
  57. 33 0
      examples/examples-ds/3_加入购物车成功_json.yaml
  58. 33 0
      examples/examples-ds/4_查询购物车列表_get.yaml
  59. 25 0
      examples/examples-ds/5_删除购物车列表.yaml
  60. 30 0
      examples/examples-ds/6_添加地址接口.yaml
  61. 28 0
      examples/examples-ds/7_查询地址列表接口_get.yaml
  62. 25 0
      examples/examples-ds/8_删除地址列表接口.yaml
  63. 28 0
      examples/examples-ds/9_查询地址列表接口.yaml
  64. 8 0
      examples/examples-ds/context.yaml
  65. 32 0
      examples/examples-ds/haidun_pj/20_用户注册驱动.yaml
  66. 60 0
      examples/examples-ds/haidun_pj/21_登录接口数据驱动.yaml
  67. 37 0
      examples/examples-ds/haidun_pj/22_登录成功测试用例.yaml
  68. 33 0
      examples/examples-ds/haidun_pj/23_加入购物车成功-表单.yaml
  69. 33 0
      examples/examples-ds/haidun_pj/23_加入购物车成功_json.yaml
  70. 33 0
      examples/examples-ds/haidun_pj/24_查询购物车列表_get.yaml
  71. 25 0
      examples/examples-ds/haidun_pj/25_删除购物车列表.yaml
  72. 30 0
      examples/examples-ds/haidun_pj/26_添加地址接口.yaml
  73. 28 0
      examples/examples-ds/haidun_pj/27_查询地址列表接口_get.yaml
  74. 25 0
      examples/examples-ds/haidun_pj/28_删除地址列表接口.yaml
  75. 28 0
      examples/examples-ds/haidun_pj/29_查询地址列表接口.yaml
  76. 29 0
      examples/examples-ds/haidun_pj/30_提交订单-购物车_json.yaml
  77. 33 0
      examples/examples-ds/haidun_pj/31_提交订单-商品详情_json.yaml
  78. 27 0
      examples/examples-ds/haidun_pj/32_加密接口.yaml
  79. BIN=BIN
      examples/examples-dsw/1_测试用例_读书屋.xlsx
  80. BIN=BIN
      examples/examples-dsw/2_测试用例_读书屋.xlsx
  81. BIN=BIN
      examples/examples-dsw/3_测试用例_读书屋.xlsx
  82. BIN=BIN
      examples/examples-dsw/4_测试用例_读书屋.xlsx
  83. BIN=BIN
      examples/examples-dsw/context.xlsx
  84. BIN=BIN
      examples/examples-dsw/海顿_测试用例.xlsx
  85. 46 0
      requirements.txt
  86. 59 0
      setup.py

+ 18 - 0
.gitignore

@@ -0,0 +1,18 @@
+# Build and Release Folders
+bin-debug/
+bin-release/
+[Oo]bj/
+[Bb]in/
+
+# Other files and folders
+.settings/
+
+# Executables
+*.swf
+*.air
+*.ipa
+*.apk
+
+# Project files, i.e. `.project`, `.actionScriptProperties` and `.flexProperties`
+# should NOT be excluded as they contain compiler settings and other important
+# information for Eclipse / Flash Builder.

+ 3 - 0
.idea/.gitignore

@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml

+ 10 - 0
.idea/api-engine.iml

@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="PYTHON_MODULE" version="4">
+  <component name="NewModuleRootManager">
+    <content url="file://$MODULE_DIR$">
+      <excludeFolder url="file://$MODULE_DIR$/venv" />
+    </content>
+    <orderEntry type="jdk" jdkName="Python 3.9 (api-engine)" jdkType="Python SDK" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>

+ 72 - 0
.idea/inspectionProfiles/Project_Default.xml

@@ -0,0 +1,72 @@
+<component name="InspectionProjectProfileManager">
+  <profile version="1.0">
+    <option name="myName" value="Project Default" />
+    <inspection_tool class="PyPackageRequirementsInspection" enabled="true" level="WARNING" enabled_by_default="true">
+      <option name="ignoredPackages">
+        <value>
+          <list size="52">
+            <item index="0" class="java.lang.String" itemvalue="Jinjia2" />
+            <item index="1" class="java.lang.String" itemvalue="greenlet" />
+            <item index="2" class="java.lang.String" itemvalue="PyYAML" />
+            <item index="3" class="java.lang.String" itemvalue="trio-websocket" />
+            <item index="4" class="java.lang.String" itemvalue="pluggy" />
+            <item index="5" class="java.lang.String" itemvalue="SQLAlchemy" />
+            <item index="6" class="java.lang.String" itemvalue="cffi" />
+            <item index="7" class="java.lang.String" itemvalue="h11" />
+            <item index="8" class="java.lang.String" itemvalue="MarkupSafe" />
+            <item index="9" class="java.lang.String" itemvalue="pycparser" />
+            <item index="10" class="java.lang.String" itemvalue="requests" />
+            <item index="11" class="java.lang.String" itemvalue="numpy" />
+            <item index="12" class="java.lang.String" itemvalue="Jinja2" />
+            <item index="13" class="java.lang.String" itemvalue="sniffio" />
+            <item index="14" class="java.lang.String" itemvalue="fsspec" />
+            <item index="15" class="java.lang.String" itemvalue="exceptiongroup" />
+            <item index="16" class="java.lang.String" itemvalue="trio" />
+            <item index="17" class="java.lang.String" itemvalue="selenium" />
+            <item index="18" class="java.lang.String" itemvalue="certifi" />
+            <item index="19" class="java.lang.String" itemvalue="jsonpath" />
+            <item index="20" class="java.lang.String" itemvalue="urllib3" />
+            <item index="21" class="java.lang.String" itemvalue="pyyaml-include" />
+            <item index="22" class="java.lang.String" itemvalue="outcome" />
+            <item index="23" class="java.lang.String" itemvalue="pytest-metadata" />
+            <item index="24" class="java.lang.String" itemvalue="packaging" />
+            <item index="25" class="java.lang.String" itemvalue="allure-pytest" />
+            <item index="26" class="java.lang.String" itemvalue="wsproto" />
+            <item index="27" class="java.lang.String" itemvalue="attrs" />
+            <item index="28" class="java.lang.String" itemvalue="sortedcontainers" />
+            <item index="29" class="java.lang.String" itemvalue="PySocks" />
+            <item index="30" class="java.lang.String" itemvalue="typing_extensions" />
+            <item index="31" class="java.lang.String" itemvalue="charset-normalizer" />
+            <item index="32" class="java.lang.String" itemvalue="allure-python-commons" />
+            <item index="33" class="java.lang.String" itemvalue="pytest-html" />
+            <item index="34" class="java.lang.String" itemvalue="pycryptodome" />
+            <item index="35" class="java.lang.String" itemvalue="PyMySQL" />
+            <item index="36" class="java.lang.String" itemvalue="idna" />
+            <item index="37" class="java.lang.String" itemvalue="pytest" />
+            <item index="38" class="java.lang.String" itemvalue="blinker" />
+            <item index="39" class="java.lang.String" itemvalue="Flask-Cors" />
+            <item index="40" class="java.lang.String" itemvalue="Flask-Script" />
+            <item index="41" class="java.lang.String" itemvalue="Werkzeug" />
+            <item index="42" class="java.lang.String" itemvalue="click" />
+            <item index="43" class="java.lang.String" itemvalue="Flask-SQLAlchemy" />
+            <item index="44" class="java.lang.String" itemvalue="importlib-metadata" />
+            <item index="45" class="java.lang.String" itemvalue="flask_jwt_extended" />
+            <item index="46" class="java.lang.String" itemvalue="pyyaml" />
+            <item index="47" class="java.lang.String" itemvalue="colorama" />
+            <item index="48" class="java.lang.String" itemvalue="zipp" />
+            <item index="49" class="java.lang.String" itemvalue="itsdangerous" />
+            <item index="50" class="java.lang.String" itemvalue="Flask" />
+            <item index="51" class="java.lang.String" itemvalue="flask_script" />
+          </list>
+        </value>
+      </option>
+    </inspection_tool>
+    <inspection_tool class="PyUnresolvedReferencesInspection" enabled="true" level="WARNING" enabled_by_default="true">
+      <option name="ignoredIdentifiers">
+        <list>
+          <option value="pytest" />
+        </list>
+      </option>
+    </inspection_tool>
+  </profile>
+</component>

+ 6 - 0
.idea/inspectionProfiles/profiles_settings.xml

@@ -0,0 +1,6 @@
+<component name="InspectionProjectProfileManager">
+  <settings>
+    <option name="USE_PROJECT_PROFILE" value="false" />
+    <version value="1.0" />
+  </settings>
+</component>

+ 4 - 0
.idea/misc.xml

@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.9 (api-engine)" project-jdk-type="Python SDK" />
+</project>

+ 8 - 0
.idea/modules.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/.idea/api-engine.iml" filepath="$PROJECT_DIR$/.idea/api-engine.iml" />
+    </modules>
+  </component>
+</project>

+ 194 - 0
LICENSE

@@ -0,0 +1,194 @@
+木兰宽松许可证,第2版
+
+木兰宽松许可证,第2版
+
+2020年1月 http://license.coscl.org.cn/MulanPSL2
+
+您对“软件”的复制、使用、修改及分发受木兰宽松许可证,第2版(“本许可证”)的如下条款的约束:
+
+0.   定义
+
+“软件” 是指由“贡献”构成的许可在“本许可证”下的程序和相关文档的集合。
+
+“贡献” 是指由任一“贡献者”许可在“本许可证”下的受版权法保护的作品。
+
+“贡献者” 是指将受版权法保护的作品许可在“本许可证”下的自然人或“法人实体”。
+
+“法人实体” 是指提交贡献的机构及其“关联实体”。
+
+“关联实体” 是指,对“本许可证”下的行为方而言,控制、受控制或与其共同受控制的机构,此处的控制是
+指有受控方或共同受控方至少50%直接或间接的投票权、资金或其他有价证券。
+
+1.   授予版权许可
+
+每个“贡献者”根据“本许可证”授予您永久性的、全球性的、免费的、非独占的、不可撤销的版权许可,您可
+以复制、使用、修改、分发其“贡献”,不论修改与否。
+
+2.   授予专利许可
+
+每个“贡献者”根据“本许可证”授予您永久性的、全球性的、免费的、非独占的、不可撤销的(根据本条规定
+撤销除外)专利许可,供您制造、委托制造、使用、许诺销售、销售、进口其“贡献”或以其他方式转移其“贡
+献”。前述专利许可仅限于“贡献者”现在或将来拥有或控制的其“贡献”本身或其“贡献”与许可“贡献”时的“软
+件”结合而将必然会侵犯的专利权利要求,不包括对“贡献”的修改或包含“贡献”的其他结合。如果您或您的“
+关联实体”直接或间接地,就“软件”或其中的“贡献”对任何人发起专利侵权诉讼(包括反诉或交叉诉讼)或
+其他专利维权行动,指控其侵犯专利权,则“本许可证”授予您对“软件”的专利许可自您提起诉讼或发起维权
+行动之日终止。
+
+3.   无商标许可
+
+“本许可证”不提供对“贡献者”的商品名称、商标、服务标志或产品名称的商标许可,但您为满足第4条规定
+的声明义务而必须使用除外。
+
+4.   分发限制
+
+您可以在任何媒介中将“软件”以源程序形式或可执行形式重新分发,不论修改与否,但您必须向接收者提供“
+本许可证”的副本,并保留“软件”中的版权、商标、专利及免责声明。
+
+5.   免责声明与责任限制
+
+“软件”及其中的“贡献”在提供时不带任何明示或默示的担保。在任何情况下,“贡献者”或版权所有者不对
+任何人因使用“软件”或其中的“贡献”而引发的任何直接或间接损失承担责任,不论因何种原因导致或者基于
+何种法律理论,即使其曾被建议有此种损失的可能性。
+
+6.   语言
+
+“本许可证”以中英文双语表述,中英文版本具有同等法律效力。如果中英文版本存在任何冲突不一致,以中文
+版为准。
+
+条款结束
+
+如何将木兰宽松许可证,第2版,应用到您的软件
+
+如果您希望将木兰宽松许可证,第2版,应用到您的新软件,为了方便接收者查阅,建议您完成如下三步:
+
+1, 请您补充如下声明中的空白,包括软件名、软件的首次发表年份以及您作为版权人的名字;
+
+2, 请您在软件包的一级目录下创建以“LICENSE”为名的文件,将整个许可证文本放入该文件中;
+
+3, 请将如下声明文本放入每个源文件的头部注释中。
+
+Copyright (c) [Year] [name of copyright holder]
+[Software Name] is licensed under Mulan PSL v2.
+You can use this software according to the terms and conditions of the Mulan
+PSL v2.
+You may obtain a copy of Mulan PSL v2 at:
+         http://license.coscl.org.cn/MulanPSL2
+THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY
+KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
+NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+See the Mulan PSL v2 for more details.
+
+Mulan Permissive Software License,Version 2
+
+Mulan Permissive Software License,Version 2 (Mulan PSL v2)
+
+January 2020 http://license.coscl.org.cn/MulanPSL2
+
+Your reproduction, use, modification and distribution of the Software shall
+be subject to Mulan PSL v2 (this License) with the following terms and
+conditions:
+
+0. Definition
+
+Software means the program and related documents which are licensed under
+this License and comprise all Contribution(s).
+
+Contribution means the copyrightable work licensed by a particular
+Contributor under this License.
+
+Contributor means the Individual or Legal Entity who licenses its
+copyrightable work under this License.
+
+Legal Entity means the entity making a Contribution and all its
+Affiliates.
+
+Affiliates means entities that control, are controlled by, or are under
+common control with the acting entity under this License, ‘control’ means
+direct or indirect ownership of at least fifty percent (50%) of the voting
+power, capital or other securities of controlled or commonly controlled
+entity.
+
+1. Grant of Copyright License
+
+Subject to the terms and conditions of this License, each Contributor hereby
+grants to you a perpetual, worldwide, royalty-free, non-exclusive,
+irrevocable copyright license to reproduce, use, modify, or distribute its
+Contribution, with modification or not.
+
+2. Grant of Patent License
+
+Subject to the terms and conditions of this License, each Contributor hereby
+grants to you a perpetual, worldwide, royalty-free, non-exclusive,
+irrevocable (except for revocation under this Section) patent license to
+make, have made, use, offer for sale, sell, import or otherwise transfer its
+Contribution, where such patent license is only limited to the patent claims
+owned or controlled by such Contributor now or in future which will be
+necessarily infringed by its Contribution alone, or by combination of the
+Contribution with the Software to which the Contribution was contributed.
+The patent license shall not apply to any modification of the Contribution,
+and any other combination which includes the Contribution. If you or your
+Affiliates directly or indirectly institute patent litigation (including a
+cross claim or counterclaim in a litigation) or other patent enforcement
+activities against any individual or entity by alleging that the Software or
+any Contribution in it infringes patents, then any patent license granted to
+you under this License for the Software shall terminate as of the date such
+litigation or activity is filed or taken.
+
+3. No Trademark License
+
+No trademark license is granted to use the trade names, trademarks, service
+marks, or product names of Contributor, except as required to fulfill notice
+requirements in section 4.
+
+4. Distribution Restriction
+
+You may distribute the Software in any medium with or without modification,
+whether in source or executable forms, provided that you provide recipients
+with a copy of this License and retain copyright, patent, trademark and
+disclaimer statements in the Software.
+
+5. Disclaimer of Warranty and Limitation of Liability
+
+THE SOFTWARE AND CONTRIBUTION IN IT ARE PROVIDED WITHOUT WARRANTIES OF ANY
+KIND, EITHER EXPRESS OR IMPLIED. IN NO EVENT SHALL ANY CONTRIBUTOR OR
+COPYRIGHT HOLDER BE LIABLE TO YOU FOR ANY DAMAGES, INCLUDING, BUT NOT
+LIMITED TO ANY DIRECT, OR INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING
+FROM YOUR USE OR INABILITY TO USE THE SOFTWARE OR THE CONTRIBUTION IN IT, NO
+MATTER HOW IT’S CAUSED OR BASED ON WHICH LEGAL THEORY, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGES.
+
+6. Language
+
+THIS LICENSE IS WRITTEN IN BOTH CHINESE AND ENGLISH, AND THE CHINESE VERSION
+AND ENGLISH VERSION SHALL HAVE THE SAME LEGAL EFFECT. IN THE CASE OF
+DIVERGENCE BETWEEN THE CHINESE AND ENGLISH VERSIONS, THE CHINESE VERSION
+SHALL PREVAIL.
+
+END OF THE TERMS AND CONDITIONS
+
+How to Apply the Mulan Permissive Software License,Version 2
+(Mulan PSL v2) to Your Software
+
+To apply the Mulan PSL v2 to your work, for easy identification by
+recipients, you are suggested to complete following three steps:
+
+i. Fill in the blanks in following statement, including insert your software
+name, the year of the first publication of your software, and your name
+identified as the copyright owner;
+
+ii. Create a file named "LICENSE" which contains the whole context of this
+License in the first directory of your software package;
+
+iii. Attach the statement to the appropriate annotated syntax at the
+beginning of each source file.
+
+Copyright (c) [Year] [name of copyright holder]
+[Software Name] is licensed under Mulan PSL v2.
+You can use this software according to the terms and conditions of the Mulan
+PSL v2.
+You may obtain a copy of Mulan PSL v2 at:
+         http://license.coscl.org.cn/MulanPSL2
+THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY
+KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
+NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+See the Mulan PSL v2 for more details.

+ 21 - 0
apirun/Log/Log.py

@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*-
+import logging
+from logging import handlers
+
+# 创建一个日志记录文件,名称是testlog
+logger = logging.getLogger('testlog')
+# 设置日志级别
+logger.setLevel(logging.INFO)
+# 创建一个RotatingFileHandler,用来轮转日志文件
+th = handlers.RotatingFileHandler(filename='testlog.log', mode='w', encoding='utf-8')
+# 设置日志格式
+fmt = '[%(asctime)s] %(levelname)s %(message)s'
+formatter = logging.Formatter(fmt)
+th.setFormatter(formatter)
+# 将处理器添加到日志记录器
+logger.addHandler(th)
+
+
+# # 创建一个输出日志到控制台的StreamHandler
+# hdr = logging.StreamHandler()
+# hdr.setFormatter(formatter)

+ 0 - 0
apirun/Log/__init__.py


BIN=BIN
apirun/Log/__pycache__/Log.cpython-39.pyc


BIN=BIN
apirun/Log/__pycache__/__init__.cpython-39.pyc


+ 1 - 0
apirun/__init__.py

@@ -0,0 +1 @@
+# -*- coding: utf-8 -*-

BIN=BIN
apirun/__pycache__/__init__.cpython-39.pyc


BIN=BIN
apirun/__pycache__/conftest.cpython-39-pytest-8.0.2.pyc


+ 97 - 0
apirun/conftest.py

@@ -0,0 +1,97 @@
+# -*- coding: utf-8 -*-
+from filelock import FileLock
+from apirun.Log.Log import logger
+import pytest
+import logging
+import allure
+import os
+import jsonpath
+import json
+from apirun.parse.CaseParser import case_parser
+from xdist.scheduler import LoadScopeScheduling
+
+class CustomScopeScheduler(LoadScopeScheduling):
+    """
+    自定义调度器类,用于根据测试范围分发测试用例。
+    重写该方法
+    """
+    def _split_scope(self, nodeid: str) -> str:
+        """
+        根据节点ID分割测试范围。
+        :param nodeid: 测试的唯一标识符。
+        :return: 测试范围。
+        """
+        # 返回 nodeid 的作为测试范围
+        # 根据实际需求修改这个逻辑
+        return nodeid.split("--P", 1)[0]
+
+
+def pytest_xdist_make_scheduler(config, log):
+    return CustomScopeScheduler(config, log)
+
+def pytest_addoption(parser):
+    """
+    增加pytest运行的配置项
+    :param parser:
+    :return:
+    """
+    parser.addoption("--type", action="store", default="yaml", help="测试用例类型")
+    parser.addoption("--cases", action="store", default="./examples", help="测试用例目录")
+
+
+def pytest_generate_tests(metafunc):
+    """
+     主要用来生成测试用例的,相当于 参数化。
+    :param metafunc:
+    :return:
+    """
+    # 读取用户传过来的参数
+    case_type = metafunc.config.getoption("type")  # 类型
+    cases_dir = metafunc.config.getoption("cases")  # 路径
+
+    # 调用方法
+    data = case_parser(case_type, cases_dir)
+
+    # 进行测试用例进行参数化,自动交给runner去进行执行执行
+    if "caseinfo" in metafunc.fixturenames:
+        metafunc.parametrize("caseinfo", data["case_infos"], ids=data["case_process"])
+
+
+@pytest.hookimpl(hookwrapper=True, tryfirst=True)
+def pytest_runtest_makereport(item, call):
+    # 通过 out = yield 定义了一个生成器。在生成器中,res = out.get_result() 获取了测试结果对象。
+    out = yield  #  类似于return,但是它返回之后执行完毕会自动回来
+    res = out.get_result()
+    #  res.when == "call":表示正在运行调用测试函数的阶段。
+    if res.when == "call":
+        logging.info(f"用例ID:{res.nodeid}")
+        logging.info(f"测试结果:{res.outcome}")
+        logging.info(f"故障表示:{res.longrepr}")
+        logging.info(f"异常:{call.excinfo}")
+        logging.info(f"用例耗时:{res.duration}")
+        logging.info("**************************************")
+
+# def login():
+#     pass
+
+# @pytest.fixture(scope="session")
+# def token_fix(tmp_path_factory, worker_id):
+#     # 代表是单机运行
+#     if worker_id == "master":
+#         token = login()
+#         print("fixture:请求登录接口,获取token", token)
+#         os.environ['token'] = token
+#         return token
+#     # 分布式运行
+#     # 获取所有子节点共享的临时目录,无需修改【不可删除、修改】
+#     root_tmp_dir = tmp_path_factory.getbasetemp().parent
+#     fn = root_tmp_dir / "data.json"
+#     with FileLock(str(fn) + ".lock"):
+#         if fn.is_file():  # 代表已经有进程执行过该fixture
+#             token = json.loads(fn.read_text())
+#         else:  # 代表该fixture第一次被执行
+#             token = login()
+#             fn.write_text(json.dumps(token))
+#         # 最好将后续需要保留的数据存在某个地方,比如这里是os的环境变量
+#         os.environ['token'] = token
+#     return token

+ 53 - 0
apirun/core/ApiTestRunner.py

@@ -0,0 +1,53 @@
+# -*- coding: utf-8 -*-
+import copy
+import allure
+from apirun.Log.Log import logger
+from apirun.extend.keywords import KeyWords
+from apirun.utils.VarRender import refresh  # 变量渲染方法
+from apirun.utils.DynamicTitle import dynamicTitle  # 测试标题生成
+from apirun.core.globalContext import g_context  # 全局变量
+
+
+class TestRunner:
+    # TODO 1: 读取到对应的数据
+    # caseinfo = case_parser("excel","./examples") #  参数
+
+    # TODO 2: 生成全量测试数据
+    # @pytest.mark.parametrize("caseinfo", caseinfo["case_infos"])
+    def test_case_execute(self, caseinfo):
+        casename = caseinfo["_case_name"]
+        # TODO 2-1 : 调用动态生成标题的方法
+        dynamicTitle(caseinfo)
+
+        # TODO 2-2: 基于我们步骤一步步进行执行
+        try:
+            # 实例化关键字对象
+            keywords = KeyWords()
+
+            # 获取当前用例变量,方便后续的渲染
+            local_context = caseinfo.get("context",{})
+            context = copy.deepcopy(g_context().show_dict())
+            context.update(local_context)
+
+            steps = caseinfo.get("steps", None)
+            logger.info(f"-----------------开始执行测试用例:{steps}-------------")
+            for index,step in enumerate(steps):
+                #  提示信息
+                step_name = list(step.keys())[0]
+                step_value = list(step.values())[0]
+                # TODO : 每一个步骤进行变量的渲染
+                context = copy.deepcopy(g_context().show_dict())
+                context.update(local_context)
+                step_value = eval(refresh(step_value, context))
+                logger.info(f"测试用例名称:{casename},开始执行步骤{index}:{step_name} - {step_value}")
+                # 基于每个步骤的关键字,找到对应的方法,然后把参数给它
+                #  通过【反射】的方式去找到对应的方法
+                with allure.step(step_name):
+                    key = step_value["关键字"]  # 具体的方法名, 在 keywords 里面找到这个方法
+                    try:
+                        key_func = keywords.__getattribute__(key)  # 从keywords获取到对应方法
+                    except AttributeError as e:
+                        logger.error(f"测试用例名称:{casename},没有这个关键字方法", e)
+                    key_func(**step_value)  # 调用方法
+        finally:
+            logger.info(f"-------------------测试用例名称:{casename}执行结束----------------------")

+ 1 - 0
apirun/core/__init__.py

@@ -0,0 +1 @@
+# -*- coding: utf-8 -*-

BIN=BIN
apirun/core/__pycache__/ApiTestRunner.cpython-39-pytest-8.0.2.pyc


BIN=BIN
apirun/core/__pycache__/__init__.cpython-39.pyc


BIN=BIN
apirun/core/__pycache__/globalContext.cpython-39.pyc


+ 24 - 0
apirun/core/globalContext.py

@@ -0,0 +1,24 @@
+# -*- coding: utf-8 -*-
+
+# 全局变量 --- 字典格式存储
+# 内置属性--外部不可修改
+# 提供对应的方法: 可以对这个属性进行修改\增加\显示
+
+class g_context(object):
+    _dic = {}  # 内置属性--外部不可修改
+
+    # TODO 1 : 通过key去进行设置
+    def set_dict(self, key, value):
+        self._dic[key] = value
+
+    # TODO 2 : 通过key去进行获取数据
+    def get_dict(self, key):
+        return self._dic.get(key, None)  # 如果这个key不存在,则会返回None
+
+    # TODO 3 : 通过自字典去设置数据
+    def set_by_dict(self, dic):
+        self._dic.update(dic)
+
+    # TODO 4 : 显示对应全局变量所有值
+    def show_dict(self):
+        return self._dic

+ 1 - 0
apirun/extend/__init__.py

@@ -0,0 +1 @@
+# -*- coding: utf-8 -*-

BIN=BIN
apirun/extend/__pycache__/__init__.cpython-39.pyc


BIN=BIN
apirun/extend/__pycache__/keywords.cpython-39.pyc


+ 323 - 0
apirun/extend/keywords.py

@@ -0,0 +1,323 @@
+# -*- coding: utf-8 -*-
+
+"""
+    这是接口关键字驱动类,用于提供自动化接口测试的关键字方法。
+    主要是实现常用的关键字内容,并定义好所有的参数内容即可
+    接口中常用关键字:
+        1.各种模拟请求方法:Post/get/put/delete/header/....
+        2.根据需求进行断言封装:jsonpath、数据库断言
+        3.集合Allure,可添加@allure.step,这样在自动化执行的时候
+        Allure报告可以直接捕捉相关的执行信息,让测试报告更详细
+"""
+import json
+import random
+from apirun.Log.Log import logger
+import allure
+import requests
+import jsonpath
+from apirun.core.globalContext import g_context
+from deepdiff import DeepDiff
+from Crypto.Cipher import AES
+from Crypto.Util.Padding import pad, unpad
+import base64
+
+
+class KeyWords:
+    request = None
+
+    @allure.step("参数数据:发送Post请求")
+    def request_post(self, **kwargs):
+        response = requests.post(**kwargs)
+        # TODO: 扩展- 把对应的响应数据写到变量渲染中
+        g_context().set_dict("current_response", response)  # 默认设置成变量渲染
+        return response
+
+    @allure.step("参数数据:发送Get请求")
+    def request_get(self, **kwargs):
+        url = kwargs.get("URL", None)
+        params = kwargs.get("PARAMS", None)
+        headers = kwargs.get("HEADERS", None)
+
+        request_data = {
+            "url": url,
+            "params": params,
+            "headers": headers,
+        }
+
+        response = requests.get(**request_data)
+        g_context().set_dict("current_response", response)
+        return response
+
+    @allure.step("参数数据:发送Post请求-form_urlencoded")
+    def request_post_form_urlencoded(self, **kwargs):
+        """
+        发送Post请求
+        """
+        url = kwargs.get("URL", None)
+        params = kwargs.get("PARAMS", None)
+        headers = kwargs.get("HEADERS", None)
+        data = kwargs.get("DATA", None)
+
+        request_data = {
+            "url": url,
+            "params": params,
+            "headers": headers,
+            "data": data,
+        }
+
+        response = requests.post(**request_data)
+        g_context().set_dict("current_response", response)
+        return response
+
+    @allure.step("参数数据:发送Post请求-row_json")
+    def request_post_row_json(self, **kwargs):
+        """
+        发送Post请求
+        """
+        url = kwargs.get("URL", None)
+        params = kwargs.get("PARAMS", None)
+        headers = kwargs.get("HEADERS", None)
+        data = kwargs.get("DATA", None)
+
+        request_data = {
+            "url": url,
+            "params": params,
+            "headers": headers,
+            "json": data,
+        }
+
+        response = requests.post(**request_data)
+        g_context().set_dict("current_response", response)  # 默认设置成全局变量
+        return response
+
+    @allure.step("参数数据:发送Post请求-form_data")
+    def request_post_form_data(self, **kwargs):
+        """
+        发送Post请求
+        """
+        url = kwargs.get("URL", None)
+        files = kwargs.get("FILES", None)
+        params = kwargs.get("PARAMS", None)
+        headers = kwargs.get("HEADERS", None)
+        data = kwargs.get("DATA", None)
+
+        request_data = {
+            "url": url,
+            "params": params,
+            "headers": headers,
+            "data": data,
+            "files": eval(files)  # 变成字典格式
+        }
+
+        response = requests.post(**request_data)
+        g_context().set_dict("current_response", response)  # 默认设置成全局变量
+        return response
+
+    @allure.step("参数数据:发送Delete请求")
+    def request_delete(self, **kwargs):
+        """
+        发送Post请求
+        """
+        url = kwargs.get("URL", None)
+        params = kwargs.get("PARAMS", None)
+        headers = kwargs.get("HEADERS", None)
+        data = kwargs.get("DATA", None)
+
+        request_data = {
+            "url": url,
+            "params": params,
+            "headers": headers,
+            "json": data,
+        }
+
+        response = requests.delete(**request_data)
+        g_context().set_dict("current_response", response)  # 默认设置成全局变量
+        return response
+
+    # TODO: 扩展 - JAONPATH提取的方法
+    @allure.step("参数数据:提取响应数据并存储")
+    def ex_jsonData(self, **kwargs):
+        """
+        提取json数据
+        EXVALUE:提取josn的表达式
+        INDEX: 非必填,默认为0,all代表所有
+        VARNAME:存储的变量名,方便后面使用
+        """
+        # 获取JsonPath的值
+        EXPRESSION = kwargs.get("EXVALUE", None)
+        # 获取对应的下标,非必填,默认为0
+        INDEX = kwargs.get("INDEX", 0)
+        if INDEX is None:
+            INDEX = 0
+        # 获取响应数据
+        response = g_context().get_dict("current_response").json()
+
+        if INDEX == "all":
+            ex_data = jsonpath.jsonpath(response, EXPRESSION)
+        else:
+            ex_data = jsonpath.jsonpath(response, EXPRESSION)[INDEX]  # 通过JsonPath进行提取
+        g_context().set_dict(kwargs["VARNAME"], ex_data)  # 根据变量名设置成变量渲染
+        return ex_data
+
+    # TODO: 扩展 - 数据库提取的方法
+    @allure.step("参数数据:提取数据库数据并存储")
+    def ex_mysqlData(self, **kwargs):
+        """
+        数据库 : 数据库的名称
+        引用变量:数据库要存储的变量名,列表格式
+        存储到全局变量:{“变量名_下标”:数据}
+        """
+        import pymysql
+        from pymysql import cursors
+        config = {"cursorclass": cursors.DictCursor}
+        # 读取全局变量 - 根据选择的数据 读取指定的数据库配置 连接对应的数据库
+        db_config = g_context().get_dict("_database")[kwargs["数据库"]]
+        config.update(db_config)
+
+        con = pymysql.connect(**config)
+        cur = con.cursor()
+        cur.execute(kwargs["SQL"])
+        rs = cur.fetchall()
+        cur.close()
+        con.close()
+        logger.info("数据库查询结果:", rs)
+
+        var_names = kwargs["引用变量"].split(",")
+        result = {}
+        for i, data in enumerate(rs, start=1):
+            for j, value in enumerate(var_names):
+                result[f'{var_names[j]}_{i}'] = data.get(var_names[j])  # 根据变量名称找读取出来的内容
+        g_context().set_by_dict(result)
+
+    # TODO: 扩展 - 文本断言方法
+    @allure.step("参数数据:断言当前文本内容")
+    def assert_text_comparators(self, **kwargs):
+        """
+        封装断言以进行不同的比较操作。
+
+        参数:
+        value (Any): 要比较的值。
+        expected (Any): 预期的值。
+        op_str (str): 操作符的字符串表示(如 '>', '<', '==' 等)。
+        message (str, optional): 自定义的错误消息。
+
+        返回:
+        None: 如果断言成功,则不返回任何内容。
+
+        引发:
+        AssertionError: 如果断言失败。
+        """
+        comparators = {
+            '>': lambda a, b: a > b,
+            '<': lambda a, b: a < b,
+            '==': lambda a, b: a == b,
+            '>=': lambda a, b: a >= b,
+            '<=': lambda a, b: a <= b,
+            '!=': lambda a, b: a != b,
+        }
+
+        message = kwargs.get("MESSAGE", None)
+
+        if kwargs["OP_STR"] not in comparators:
+            raise ValueError(f"没有该操作方式: {kwargs['OP_STR']}")
+
+        if not comparators[kwargs['OP_STR']](kwargs['VALUE'], kwargs["EXPECTED"]):
+            if message:
+                raise AssertionError(message)
+            else:
+                raise AssertionError(f"{kwargs['VALUE']} {kwargs['OP_STR']} {kwargs['EXPECTED']} 失败")
+
+
+
+    # TODO: 扩展 - 全量断言-对比两个Json的差异
+    @allure.step("参数数据:全量断言-对比两个Json的差异")
+    def assert_json_DeepDiff(self, **kwargs):
+        """
+        对比两个json的差异
+        :param json1: 期望结果
+        :param json2: 实际结果
+        :param exclude_paths:需要排除的字段,集合的类型,比如{“id”,...}
+        :param ignore_order: 忽略顺序,一般用户有序数据类型,比如列表
+        :param ignore_string_case:忽略值的大小写,False
+        :return: 当数据没有差异则返回空集合
+        """
+        json1 = kwargs["json1"]
+        json2 = kwargs["json2"]
+
+        exclude_paths = kwargs.get("过滤字段", None)
+        ignore_order = kwargs.get("忽略顺序", None)
+        ignore_string_case = kwargs.get("忽略大小写", False)
+
+        screen_data = {"exclude_paths": exclude_paths, "ignore_order": ignore_order,
+                       "ignore_string_case": ignore_string_case}
+
+        diff = DeepDiff(json1, json2, **screen_data)
+
+        assert not diff, f"全量断言失败:{diff}"
+
+    # TODO: 扩展 - 加密处理
+    @allure.step("参数数据:对数据进行AES加密处理")
+    def encrypt_aes(self, **kwargs):
+        """
+        对数据进行AES加密
+        :param data: 需要加密的数据
+        :param VARNAME: 存储到全局变量的名称
+        :return:
+        """
+        key = b"1234567812345678"  # key 密码
+        data = kwargs["data"].encode('utf-8')
+        cipher = AES.new(key, AES.MODE_ECB)  # 使用ECB模式
+        ct_bytes = cipher.encrypt(pad(data, AES.block_size))  # 使用PKCS7填充,初始化数据块大小, 16位
+        encrypt_data = base64.b64encode(ct_bytes).decode('utf-8')
+
+        g_context().set_dict(kwargs["VARNAME"], encrypt_data)  # 根据变量名设置成变量
+
+    # ----------------------实战扩展方法------------------------------
+    @allure.step("参数数据:对数据进行AES加密处理")
+    def generate_name(self, **kwargs):
+        data = "hami" + str(random.randint(0, 9999))
+        g_context().set_dict(kwargs["VARNAME"], data)  # 根据变量名设置成变量
+
+
+    # TODO: 扩展 - JSOND断言方法
+    @allure.step("参数数据:JSOND断言文本内容")
+    def assert_json_comparators(self, **kwargs):
+        """
+        封装断言以进行不同的比较操作。
+
+        参数:
+        value (Any): 要比较的jsonPath值。
+        expected (Any): 预期的值。
+        op_str (str): 操作符的字符串表示(如 '>', '<', '==' 等)。
+        message (str, optional): 自定义的错误消息。
+
+        返回:
+        None: 如果断言成功,则不返回任何内容。
+
+        引发:
+        AssertionError: 如果断言失败。
+        """
+        comparators = {
+            '>': lambda a, b: a > b,
+            '<': lambda a, b: a < b,
+            '==': lambda a, b: a == b,
+            '>=': lambda a, b: a >= b,
+            '<=': lambda a, b: a <= b,
+            '!=': lambda a, b: a != b,
+        }
+
+        message = kwargs.get("MESSAGE", None)
+
+        if kwargs["OP_STR"] not in comparators:
+            raise ValueError(f"没有该操作方式: {kwargs['OP_STR']}")
+
+        # 通过jsonpath获取对应的数据
+        # 获取响应数据
+        response = g_context().get_dict("current_response").json()
+        ex_data = jsonpath.jsonpath(response, kwargs['VALUE'])[0] # 默认就取第一个
+
+        if not comparators[kwargs['OP_STR']](ex_data, kwargs["EXPECTED"]):
+            if message:
+                raise AssertionError(message)
+            else:
+                raise AssertionError(f"{ex_data} {kwargs['OP_STR']} {kwargs['EXPECTED']} 失败")

+ 41 - 0
apirun/extend/keywords.yaml

@@ -0,0 +1,41 @@
+# 用来维护关键字对应的对应的变量数据
+request_post_form_urlencoded:
+  - URL
+  - PARAMS
+  - HEADERS
+  - DATA
+request_post_row_json:
+  - URL
+  - PARAMS
+  - HEADERS
+  - DATA
+request_post_form_data:
+  - URL
+  - FILES
+  - PARAMS
+  - HEADERS
+  - DATA
+request_get:
+  - URL
+  - PARAMS
+  - HEADERS
+ex_jsonData:
+  - EXVALUE  # JSON表达式
+  - INDEX # 下标,默认0
+  - VARNAME # 需要存储的变量
+ex_reData:
+  - EXVALUE  # 正则表达式
+  - INDEX # 下标,默认0
+  - VARNAME # 需要存储的变量
+ex_mysqlData:
+  - 数据库 # 数据库的名字,在你context中维护的
+  - SQL
+  - 引用变量  # 列表格式
+assert_text_comparators:
+  - VALUE # 实际结果
+  - EXPECTED # 期望结果
+  - OP_STR # 操作符的字符串表示(如 '>', '<', '==' 等)
+assert_json_comparators:
+  - VALUE # JSONPATH表达式
+  - EXPECTED # 期望结果
+  - OP_STR # 操作符的字符串表示(如 '>', '<', '==' 等)

BIN=BIN
apirun/files/20240725223321.png


+ 2 - 0
apirun/files/__init__.py

@@ -0,0 +1,2 @@
+# -*- coding: utf-8 -*-
+# @Author : Hami

+ 2740 - 0
apirun/logdata.log

@@ -0,0 +1,2740 @@
+2024-11-04 20:25:36 INFO -----------------开始执行测试用例:[{'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/user/login', 'PARAMS': None, 'HEADERS': None, 'DATA': {'username': '{{username}}', 'password': '{{password}}'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'通过JSONPATH提取数据-TOKEN': {'关键字': 'ex_jsonData', 'EXVALUE': '$..token', 'INDEX': None, 'VARNAME': 'token'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:36 INFO 测试用例名称:能够正确登录用例,开始执行步骤0:发送Post请求 - {'关键字': 'request_post_form_urlencoded', 'URL': 'http://120.25.127.201:18001//user/login', 'PARAMS': None, 'HEADERS': None, 'DATA': {'username': '15096268001', 'password': '123456'}} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:36 INFO 测试用例名称:能够正确登录用例,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:36 INFO 测试用例名称:能够正确登录用例,开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:36 INFO 测试用例名称:能够正确登录用例,开始执行步骤3:通过JSONPATH提取数据-TOKEN - {'关键字': 'ex_jsonData', 'EXVALUE': '$..token', 'INDEX': None, 'VARNAME': 'token'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:36 INFO 测试用例名称:能够正确登录用例,开始执行步骤4:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:36 INFO 测试用例名称:能够正确登录用例,开始执行步骤5:断言-等于-CODE - {'关键字': 'assert_text_comparators', 'VALUE': '200', 'EXPECTED': '200', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:36 INFO -------------------测试用例名称:能够正确登录用例执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:36 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G0--P0] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:36 INFO 测试结果:passed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:36 INFO 故障表示:None conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:36 INFO 异常:None conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:36 INFO 用例耗时:0.10566030000000004 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:36 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:36 INFO -----------------开始执行测试用例:[{'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/user/login', 'PARAMS': None, 'HEADERS': None, 'DATA': {'username': '15096268001', 'password': '1234562'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': '手机号或密码错误!', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '1004', 'OP_STR': '=='}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:36 INFO 测试用例名称:登录失败-手机号或密码错误用例,开始执行步骤0:发送Post请求 - {'关键字': 'request_post_form_urlencoded', 'URL': 'http://120.25.127.201:18001//user/login', 'PARAMS': None, 'HEADERS': None, 'DATA': {'username': '15096268001', 'password': '1234562'}} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:36 INFO 测试用例名称:登录失败-手机号或密码错误用例,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:36 INFO 测试用例名称:登录失败-手机号或密码错误用例,开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:36 INFO 测试用例名称:登录失败-手机号或密码错误用例,开始执行步骤3:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': '手机号或密码错误!', 'EXPECTED': '手机号或密码错误!', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:36 INFO 测试用例名称:登录失败-手机号或密码错误用例,开始执行步骤4:断言-等于-CODE - {'关键字': 'assert_text_comparators', 'VALUE': '1004', 'EXPECTED': '1004', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:36 INFO -------------------测试用例名称:登录失败-手机号或密码错误用例执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:36 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G0--P1] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:36 INFO 测试结果:passed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:36 INFO 故障表示:None conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:36 INFO 异常:None conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:36 INFO 用例耗时:0.08426139999999993 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:36 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:36 INFO -----------------开始执行测试用例:[{'发送Get请求': {'关键字': 'request_get', 'URL': '{{URL}}/user/userInfo', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..username', 'INDEX': 0, 'VARNAME': 'msg_username'}}, {'断言-等于-响应USERNAME': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_username}}', 'EXPECTED': '{{username}}', 'OP_STR': '=='}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:36 INFO 测试用例名称:查看用户信息,开始执行步骤0:发送Get请求 - {'关键字': 'request_get', 'URL': 'http://120.25.127.201:18001//user/userInfo', 'PARAMS': None, 'HEADERS': {'Authorization': 'eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE3MzEzMjc5MzYsInN1YiI6IntcImlkXCI6MTc5MTA1NjM4NjYzOTg3MjAwMCxcInVzZXJuYW1lXCI6XCIxNTA5NjI2ODAwMVwiLFwibmlja05hbWVcIjpcIuS4gOS6jOS4iVwifSIsImNyZWF0ZWQiOjE3MzA3MjMxMzYyMzN9.mrpQ6h4-izAgP-HbalIICX7HU8gSPH7xTJkjVrzLJGPv2X5e0mpRRg1-8elFCs_pn8yjdwolXOYALYsb-E1n1Q'}} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:36 INFO 测试用例名称:查看用户信息,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:36 INFO 测试用例名称:查看用户信息,开始执行步骤2:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:36 INFO 测试用例名称:查看用户信息,开始执行步骤3:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..username', 'INDEX': 0, 'VARNAME': 'msg_username'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:36 INFO 测试用例名称:查看用户信息,开始执行步骤4:断言-等于-响应USERNAME - {'关键字': 'assert_text_comparators', 'VALUE': '15096268001', 'EXPECTED': '15096268001', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:36 INFO -------------------测试用例名称:查看用户信息执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:36 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G0--P2] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:36 INFO 测试结果:passed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:36 INFO 故障表示:None conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:36 INFO 异常:None conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:36 INFO 用例耗时:0.09925839999999986 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:36 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:36 INFO -----------------开始执行测试用例:[{'发送Post请求-上传图片': {'关键字': 'request_post_form_data', 'URL': '{{URL}}/file/picUpload', 'FILES': '{"file":open("./files/20240725223321.png","rb")}', 'PARAMS': None, 'HEADERS': None}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}, {'通过JSONPATH提取数据-图片路径': {'关键字': 'ex_jsonData', 'EXVALUE': '$..data', 'INDEX': 0, 'VARNAME': 'msg_data'}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:36 INFO 测试用例名称:修改头像-上传头像,开始执行步骤0:发送Post请求-上传图片 - {'关键字': 'request_post_form_data', 'URL': 'http://120.25.127.201:18001//file/picUpload', 'FILES': '{"file":open("./files/20240725223321.png","rb")}', 'PARAMS': None, 'HEADERS': None} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:36 INFO 测试用例名称:修改头像-上传头像,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:36 INFO 测试用例名称:修改头像-上传头像,开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:36 INFO 测试用例名称:修改头像-上传头像,开始执行步骤3:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:36 INFO 测试用例名称:修改头像-上传头像,开始执行步骤4:断言-等于-CODE - {'关键字': 'assert_text_comparators', 'VALUE': '200', 'EXPECTED': '200', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:36 INFO 测试用例名称:修改头像-上传头像,开始执行步骤5:通过JSONPATH提取数据-图片路径 - {'关键字': 'ex_jsonData', 'EXVALUE': '$..data', 'INDEX': 0, 'VARNAME': 'msg_data'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:36 INFO -------------------测试用例名称:修改头像-上传头像执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:36 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G0--P3] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:36 INFO 测试结果:passed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:36 INFO 故障表示:None conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:36 INFO 异常:None conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:36 INFO 用例耗时:0.08409670000000014 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:36 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:36 INFO -----------------开始执行测试用例:[{'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/user/updateUserInfo', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'userPhoto': '{{msg_data}}'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:36 INFO 测试用例名称:修改头像-确定修改头像,开始执行步骤0:发送Post请求 - {'关键字': 'request_post_form_urlencoded', 'URL': 'http://120.25.127.201:18001//user/updateUserInfo', 'PARAMS': None, 'HEADERS': {'Authorization': 'eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE3MzEzMjc5MzYsInN1YiI6IntcImlkXCI6MTc5MTA1NjM4NjYzOTg3MjAwMCxcInVzZXJuYW1lXCI6XCIxNTA5NjI2ODAwMVwiLFwibmlja05hbWVcIjpcIuS4gOS6jOS4iVwifSIsImNyZWF0ZWQiOjE3MzA3MjMxMzYyMzN9.mrpQ6h4-izAgP-HbalIICX7HU8gSPH7xTJkjVrzLJGPv2X5e0mpRRg1-8elFCs_pn8yjdwolXOYALYsb-E1n1Q'}, 'DATA': {'userPhoto': '/localPic/2024/11/04/aa51dc43ea3448bb91f269fb9c489aa3.png'}} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:36 INFO 测试用例名称:修改头像-确定修改头像,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:36 INFO 测试用例名称:修改头像-确定修改头像,开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:36 INFO 测试用例名称:修改头像-确定修改头像,开始执行步骤3:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:36 INFO 测试用例名称:修改头像-确定修改头像,开始执行步骤4:断言-等于-CODE - {'关键字': 'assert_text_comparators', 'VALUE': '200', 'EXPECTED': '200', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:36 INFO -------------------测试用例名称:修改头像-确定修改头像执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:36 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G0--P4] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:36 INFO 测试结果:passed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:36 INFO 故障表示:None conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:36 INFO 异常:None conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:36 INFO 用例耗时:0.11206969999999972 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:36 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:36 INFO -----------------开始执行测试用例:[{'提取评价的书籍ID': {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}}, {'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': '{{id_1}}', 'commentContent': 'hami的接口自动化'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:36 INFO 测试用例名称:我的书评-发布正常的书评(可能会失败),开始执行步骤0:提取评价的书籍ID - {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:36 INFO -------------------测试用例名称:我的书评-发布正常的书评(可能会失败)执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:37 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G0--P5] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:37 INFO 测试结果:failed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:37 INFO 故障表示:self = <apirun.core.ApiTestRunner.TestRunner object at 0x00000215ADDBEFA0>
+caseinfo = {'_case_name': '我的书评-发布正常的书评(可能会失败)', 'desc': '我的书评-发布正常的书评(可能会失败)', 'featureName': '我的书评', 'process': 'G0--P', ...}
+
+    def test_case_execute(self, caseinfo):
+        casename = caseinfo["_case_name"]
+        # TODO 2-1 : 调用动态生成标题的方法
+        dynamicTitle(caseinfo)
+    
+        # TODO 2-2: 基于我们步骤一步步进行执行
+        try:
+            # 实例化关键字对象
+            keywords = KeyWords()
+    
+            # 获取当前用例变量,方便后续的渲染
+            local_context = caseinfo.get("context",{})
+            context = copy.deepcopy(g_context().show_dict())
+            context.update(local_context)
+    
+            steps = caseinfo.get("steps", None)
+            logger.info(f"-----------------开始执行测试用例:{steps}-------------")
+            for index,step in enumerate(steps):
+                #  提示信息
+                step_name = list(step.keys())[0]
+                step_value = list(step.values())[0]
+                # TODO : 每一个步骤进行变量的渲染
+                context = copy.deepcopy(g_context().show_dict())
+                context.update(local_context)
+                step_value = eval(refresh(step_value, context))
+                logger.info(f"测试用例名称:{casename},开始执行步骤{index}:{step_name} - {step_value}")
+                # 基于每个步骤的关键字,找到对应的方法,然后把参数给它
+                #  通过【反射】的方式去找到对应的方法
+                with allure.step(step_name):
+                    key = step_value["关键字"]  # 具体的方法名, 在 keywords 里面找到这个方法
+                    try:
+                        key_func = keywords.__getattribute__(key)  # 从keywords获取到对应方法
+                    except AttributeError as e:
+                        logger.error(f"测试用例名称:{casename},没有这个关键字方法", e)
+>                   key_func(**step_value)  # 调用方法
+
+core\ApiTestRunner.py:51: 
+_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+extend\keywords.py:183: in ex_mysqlData
+    logger.info("数据库查询结果:", rs)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1446: in info
+    self._log(INFO, msg, args, **kwargs)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1589: in _log
+    self.handle(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1599: in handle
+    self.callHandlers(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1661: in callHandlers
+    hdlr.handle(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:952: in handle
+    self.emit(record)
+..\myenv\lib\site-packages\_pytest\logging.py:380: in emit
+    super().emit(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1091: in emit
+    self.handleError(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1083: in emit
+    msg = self.format(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:927: in format
+    return fmt.format(record)
+..\myenv\lib\site-packages\_pytest\logging.py:140: in format
+    return super().format(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:663: in format
+    record.message = record.getMessage()
+_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+
+self = <LogRecord: testlog, 20, D:\001_zzh\eng\api-engine\apirun\extend\keywords.py, 183, "数据库查询结果:">
+
+    def getMessage(self):
+        """
+        Return the message for this LogRecord.
+    
+        Return the message for this LogRecord after merging any user-supplied
+        arguments with the message.
+        """
+        msg = str(self.msg)
+        if self.args:
+>           msg = msg % self.args
+E           TypeError: not all arguments converted during string formatting
+
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:367: TypeError conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:37 INFO 异常:<ExceptionInfo TypeError('not all arguments converted during string formatting') tblen=43> conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:37 INFO 用例耗时:0.24739699999999987 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:37 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:37 INFO -----------------开始执行测试用例:[{'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': '', 'commentContent': 'hami的接口自动化'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': '书籍ID不存在', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:37 INFO 测试用例名称:我的书评-发布不存在的书籍ID(BUG),开始执行步骤0:发送Post请求 - {'关键字': 'request_post_form_urlencoded', 'URL': 'http://120.25.127.201:18001//book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': 'eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE3MzEzMjc5MzYsInN1YiI6IntcImlkXCI6MTc5MTA1NjM4NjYzOTg3MjAwMCxcInVzZXJuYW1lXCI6XCIxNTA5NjI2ODAwMVwiLFwibmlja05hbWVcIjpcIuS4gOS6jOS4iVwifSIsImNyZWF0ZWQiOjE3MzA3MjMxMzYyMzN9.mrpQ6h4-izAgP-HbalIICX7HU8gSPH7xTJkjVrzLJGPv2X5e0mpRRg1-8elFCs_pn8yjdwolXOYALYsb-E1n1Q'}, 'DATA': {'bookId': '', 'commentContent': 'hami的接口自动化'}} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:37 INFO 测试用例名称:我的书评-发布不存在的书籍ID(BUG),开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:37 INFO 测试用例名称:我的书评-发布不存在的书籍ID(BUG),开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:37 INFO 测试用例名称:我的书评-发布不存在的书籍ID(BUG),开始执行步骤3:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': '书籍ID不存在', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:37 INFO -------------------测试用例名称:我的书评-发布不存在的书籍ID(BUG)执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:37 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G0--P6] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:37 INFO 测试结果:failed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:37 INFO 故障表示:self = <apirun.core.ApiTestRunner.TestRunner object at 0x00000215ADDBE520>
+caseinfo = {'_case_name': '我的书评-发布不存在的书籍ID(BUG)', 'desc': '我的书评-发布不存在的书籍ID(BUG)', 'featureName': '我的书评', 'process': 'G0--P', ...}
+
+    def test_case_execute(self, caseinfo):
+        casename = caseinfo["_case_name"]
+        # TODO 2-1 : 调用动态生成标题的方法
+        dynamicTitle(caseinfo)
+    
+        # TODO 2-2: 基于我们步骤一步步进行执行
+        try:
+            # 实例化关键字对象
+            keywords = KeyWords()
+    
+            # 获取当前用例变量,方便后续的渲染
+            local_context = caseinfo.get("context",{})
+            context = copy.deepcopy(g_context().show_dict())
+            context.update(local_context)
+    
+            steps = caseinfo.get("steps", None)
+            logger.info(f"-----------------开始执行测试用例:{steps}-------------")
+            for index,step in enumerate(steps):
+                #  提示信息
+                step_name = list(step.keys())[0]
+                step_value = list(step.values())[0]
+                # TODO : 每一个步骤进行变量的渲染
+                context = copy.deepcopy(g_context().show_dict())
+                context.update(local_context)
+                step_value = eval(refresh(step_value, context))
+                logger.info(f"测试用例名称:{casename},开始执行步骤{index}:{step_name} - {step_value}")
+                # 基于每个步骤的关键字,找到对应的方法,然后把参数给它
+                #  通过【反射】的方式去找到对应的方法
+                with allure.step(step_name):
+                    key = step_value["关键字"]  # 具体的方法名, 在 keywords 里面找到这个方法
+                    try:
+                        key_func = keywords.__getattribute__(key)  # 从keywords获取到对应方法
+                    except AttributeError as e:
+                        logger.error(f"测试用例名称:{casename},没有这个关键字方法", e)
+>                   key_func(**step_value)  # 调用方法
+
+core\ApiTestRunner.py:51: 
+_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+
+self = <apirun.extend.keywords.KeyWords object at 0x00000215AE0115B0>
+kwargs = {'EXPECTED': '书籍ID不存在', 'OP_STR': '==', 'VALUE': 'SUCCESS', '关键字': 'assert_text_comparators'}
+comparators = {'!=': <function KeyWords.assert_text_comparators.<locals>.<lambda> at 0x00000215ADFDBA60>, '<': <function KeyWords.as...at 0x00000215ADFDB9D0>, '==': <function KeyWords.assert_text_comparators.<locals>.<lambda> at 0x00000215ADFDB8B0>, ...}
+message = None
+
+    @allure.step("参数数据:断言当前文本内容")
+    def assert_text_comparators(self, **kwargs):
+        """
+        封装断言以进行不同的比较操作。
+    
+        参数:
+        value (Any): 要比较的值。
+        expected (Any): 预期的值。
+        op_str (str): 操作符的字符串表示(如 '>', '<', '==' 等)。
+        message (str, optional): 自定义的错误消息。
+    
+        返回:
+        None: 如果断言成功,则不返回任何内容。
+    
+        引发:
+        AssertionError: 如果断言失败。
+        """
+        comparators = {
+            '>': lambda a, b: a > b,
+            '<': lambda a, b: a < b,
+            '==': lambda a, b: a == b,
+            '>=': lambda a, b: a >= b,
+            '<=': lambda a, b: a <= b,
+            '!=': lambda a, b: a != b,
+        }
+    
+        message = kwargs.get("MESSAGE", None)
+    
+        if kwargs["OP_STR"] not in comparators:
+            raise ValueError(f"没有该操作方式: {kwargs['OP_STR']}")
+    
+        if not comparators[kwargs['OP_STR']](kwargs['VALUE'], kwargs["EXPECTED"]):
+            if message:
+                raise AssertionError(message)
+            else:
+>               raise AssertionError(f"{kwargs['VALUE']} {kwargs['OP_STR']} {kwargs['EXPECTED']} 失败")
+E               AssertionError: SUCCESS == 书籍ID不存在 失败
+
+extend\keywords.py:228: AssertionError conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:37 INFO 异常:<ExceptionInfo AssertionError('SUCCESS == 书籍ID不存在 失败') tblen=31> conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:37 INFO 用例耗时:0.11110720000000018 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:37 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:37 INFO -----------------开始执行测试用例:[{'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': 118, 'commentContent': 'hami的接口自动化'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': '已评价过该书籍!', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '3001', 'OP_STR': '=='}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:37 INFO 测试用例名称:我的书评-发布已评价的数据,开始执行步骤0:发送Post请求 - {'关键字': 'request_post_form_urlencoded', 'URL': 'http://120.25.127.201:18001//book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': 'eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE3MzEzMjc5MzYsInN1YiI6IntcImlkXCI6MTc5MTA1NjM4NjYzOTg3MjAwMCxcInVzZXJuYW1lXCI6XCIxNTA5NjI2ODAwMVwiLFwibmlja05hbWVcIjpcIuS4gOS6jOS4iVwifSIsImNyZWF0ZWQiOjE3MzA3MjMxMzYyMzN9.mrpQ6h4-izAgP-HbalIICX7HU8gSPH7xTJkjVrzLJGPv2X5e0mpRRg1-8elFCs_pn8yjdwolXOYALYsb-E1n1Q'}, 'DATA': {'bookId': 118, 'commentContent': 'hami的接口自动化'}} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:37 INFO 测试用例名称:我的书评-发布已评价的数据,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:37 INFO 测试用例名称:我的书评-发布已评价的数据,开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:37 INFO 测试用例名称:我的书评-发布已评价的数据,开始执行步骤3:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': '已评价过该书籍!', 'EXPECTED': '已评价过该书籍!', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:37 INFO 测试用例名称:我的书评-发布已评价的数据,开始执行步骤4:断言-等于-CODE - {'关键字': 'assert_text_comparators', 'VALUE': '3001', 'EXPECTED': '3001', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:37 INFO -------------------测试用例名称:我的书评-发布已评价的数据执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:37 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G0--P7] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:37 INFO 测试结果:passed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:37 INFO 故障表示:None conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:37 INFO 异常:None conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:37 INFO 用例耗时:0.09267849999999989 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:37 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:37 INFO -----------------开始执行测试用例:[{'提取评价的书籍ID': {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}}, {'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': '{{id_1}}', 'commentContent': 'ham'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:37 INFO 测试用例名称:我的书评-发布不满五个字的书评(BUG),开始执行步骤0:提取评价的书籍ID - {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:37 INFO -------------------测试用例名称:我的书评-发布不满五个字的书评(BUG)执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:37 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G0--P8] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:37 INFO 测试结果:failed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:37 INFO 故障表示:self = <apirun.core.ApiTestRunner.TestRunner object at 0x00000215ADDBE190>
+caseinfo = {'_case_name': '我的书评-发布不满五个字的书评(BUG)', 'desc': '我的书评-发布不满五个字的书评(BUG)', 'featureName': '我的书评', 'process': 'G0--P', ...}
+
+    def test_case_execute(self, caseinfo):
+        casename = caseinfo["_case_name"]
+        # TODO 2-1 : 调用动态生成标题的方法
+        dynamicTitle(caseinfo)
+    
+        # TODO 2-2: 基于我们步骤一步步进行执行
+        try:
+            # 实例化关键字对象
+            keywords = KeyWords()
+    
+            # 获取当前用例变量,方便后续的渲染
+            local_context = caseinfo.get("context",{})
+            context = copy.deepcopy(g_context().show_dict())
+            context.update(local_context)
+    
+            steps = caseinfo.get("steps", None)
+            logger.info(f"-----------------开始执行测试用例:{steps}-------------")
+            for index,step in enumerate(steps):
+                #  提示信息
+                step_name = list(step.keys())[0]
+                step_value = list(step.values())[0]
+                # TODO : 每一个步骤进行变量的渲染
+                context = copy.deepcopy(g_context().show_dict())
+                context.update(local_context)
+                step_value = eval(refresh(step_value, context))
+                logger.info(f"测试用例名称:{casename},开始执行步骤{index}:{step_name} - {step_value}")
+                # 基于每个步骤的关键字,找到对应的方法,然后把参数给它
+                #  通过【反射】的方式去找到对应的方法
+                with allure.step(step_name):
+                    key = step_value["关键字"]  # 具体的方法名, 在 keywords 里面找到这个方法
+                    try:
+                        key_func = keywords.__getattribute__(key)  # 从keywords获取到对应方法
+                    except AttributeError as e:
+                        logger.error(f"测试用例名称:{casename},没有这个关键字方法", e)
+>                   key_func(**step_value)  # 调用方法
+
+core\ApiTestRunner.py:51: 
+_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+extend\keywords.py:183: in ex_mysqlData
+    logger.info("数据库查询结果:", rs)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1446: in info
+    self._log(INFO, msg, args, **kwargs)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1589: in _log
+    self.handle(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1599: in handle
+    self.callHandlers(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1661: in callHandlers
+    hdlr.handle(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:952: in handle
+    self.emit(record)
+..\myenv\lib\site-packages\_pytest\logging.py:380: in emit
+    super().emit(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1091: in emit
+    self.handleError(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1083: in emit
+    msg = self.format(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:927: in format
+    return fmt.format(record)
+..\myenv\lib\site-packages\_pytest\logging.py:140: in format
+    return super().format(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:663: in format
+    record.message = record.getMessage()
+_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+
+self = <LogRecord: testlog, 20, D:\001_zzh\eng\api-engine\apirun\extend\keywords.py, 183, "数据库查询结果:">
+
+    def getMessage(self):
+        """
+        Return the message for this LogRecord.
+    
+        Return the message for this LogRecord after merging any user-supplied
+        arguments with the message.
+        """
+        msg = str(self.msg)
+        if self.args:
+>           msg = msg % self.args
+E           TypeError: not all arguments converted during string formatting
+
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:367: TypeError conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:37 INFO 异常:<ExceptionInfo TypeError('not all arguments converted during string formatting') tblen=43> conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:37 INFO 用例耗时:0.22507089999999996 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:37 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:37 INFO -----------------开始执行测试用例:[{'提取评价的书籍ID': {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}}, {'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': '{{id_1}}', 'commentContent': 'hamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhahamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamham'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': '评价不能超过200字符!', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:37 INFO 测试用例名称:我的书评-发布超过200个字的书评,开始执行步骤0:提取评价的书籍ID - {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:38 INFO -------------------测试用例名称:我的书评-发布超过200个字的书评执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:38 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G0--P9] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:38 INFO 测试结果:failed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:38 INFO 故障表示:self = <apirun.core.ApiTestRunner.TestRunner object at 0x00000215ADDBE610>
+caseinfo = {'_case_name': '我的书评-发布超过200个字的书评', 'desc': '我的书评-发布超过200个字的书评', 'featureName': '我的书评', 'process': 'G0--P', ...}
+
+    def test_case_execute(self, caseinfo):
+        casename = caseinfo["_case_name"]
+        # TODO 2-1 : 调用动态生成标题的方法
+        dynamicTitle(caseinfo)
+    
+        # TODO 2-2: 基于我们步骤一步步进行执行
+        try:
+            # 实例化关键字对象
+            keywords = KeyWords()
+    
+            # 获取当前用例变量,方便后续的渲染
+            local_context = caseinfo.get("context",{})
+            context = copy.deepcopy(g_context().show_dict())
+            context.update(local_context)
+    
+            steps = caseinfo.get("steps", None)
+            logger.info(f"-----------------开始执行测试用例:{steps}-------------")
+            for index,step in enumerate(steps):
+                #  提示信息
+                step_name = list(step.keys())[0]
+                step_value = list(step.values())[0]
+                # TODO : 每一个步骤进行变量的渲染
+                context = copy.deepcopy(g_context().show_dict())
+                context.update(local_context)
+                step_value = eval(refresh(step_value, context))
+                logger.info(f"测试用例名称:{casename},开始执行步骤{index}:{step_name} - {step_value}")
+                # 基于每个步骤的关键字,找到对应的方法,然后把参数给它
+                #  通过【反射】的方式去找到对应的方法
+                with allure.step(step_name):
+                    key = step_value["关键字"]  # 具体的方法名, 在 keywords 里面找到这个方法
+                    try:
+                        key_func = keywords.__getattribute__(key)  # 从keywords获取到对应方法
+                    except AttributeError as e:
+                        logger.error(f"测试用例名称:{casename},没有这个关键字方法", e)
+>                   key_func(**step_value)  # 调用方法
+
+core\ApiTestRunner.py:51: 
+_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+extend\keywords.py:183: in ex_mysqlData
+    logger.info("数据库查询结果:", rs)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1446: in info
+    self._log(INFO, msg, args, **kwargs)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1589: in _log
+    self.handle(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1599: in handle
+    self.callHandlers(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1661: in callHandlers
+    hdlr.handle(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:952: in handle
+    self.emit(record)
+..\myenv\lib\site-packages\_pytest\logging.py:380: in emit
+    super().emit(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1091: in emit
+    self.handleError(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1083: in emit
+    msg = self.format(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:927: in format
+    return fmt.format(record)
+..\myenv\lib\site-packages\_pytest\logging.py:140: in format
+    return super().format(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:663: in format
+    record.message = record.getMessage()
+_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+
+self = <LogRecord: testlog, 20, D:\001_zzh\eng\api-engine\apirun\extend\keywords.py, 183, "数据库查询结果:">
+
+    def getMessage(self):
+        """
+        Return the message for this LogRecord.
+    
+        Return the message for this LogRecord after merging any user-supplied
+        arguments with the message.
+        """
+        msg = str(self.msg)
+        if self.args:
+>           msg = msg % self.args
+E           TypeError: not all arguments converted during string formatting
+
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:367: TypeError conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:38 INFO 异常:<ExceptionInfo TypeError('not all arguments converted during string formatting') tblen=43> conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:38 INFO 用例耗时:0.2116956000000001 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:38 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:38 INFO -----------------开始执行测试用例:[{'发送Get请求': {'关键字': 'request_get', 'URL': '{{URL}}/book/listClickRank', 'PARAMS': None, 'HEADERS': None}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': None, 'VARNAME': 'msg_success'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:38 INFO 测试用例名称:点击榜单能够显示对应的数据,开始执行步骤0:发送Get请求 - {'关键字': 'request_get', 'URL': 'http://120.25.127.201:18001//book/listClickRank', 'PARAMS': None, 'HEADERS': None} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:38 INFO 测试用例名称:点击榜单能够显示对应的数据,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': None, 'VARNAME': 'msg_success'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:38 INFO 测试用例名称:点击榜单能够显示对应的数据,开始执行步骤2:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:38 INFO -------------------测试用例名称:点击榜单能够显示对应的数据执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:38 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G0--P10] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:38 INFO 测试结果:passed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:38 INFO 故障表示:None conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:38 INFO 异常:None conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:38 INFO 用例耗时:0.12249089999999985 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:38 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:38 INFO -----------------开始执行测试用例:[{'提取评价的书籍ID': {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}}, {'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': '{{id_1}}', 'commentContent': 'hami的接口自动化'}}}, {'JSON断言-等于-响应MSG': {'关键字': 'assert_json_comparators', 'VALUE': '$..msg', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'JSON断言-等于-CODE': {'关键字': 'assert_json_comparators', 'VALUE': '$..code', 'EXPECTED': '200', 'OP_STR': '=='}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:38 INFO 测试用例名称:我的书评-发布正常的书评(优化-直接Josn断言),开始执行步骤0:提取评价的书籍ID - {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:38 INFO -------------------测试用例名称:我的书评-发布正常的书评(优化-直接Josn断言)执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:38 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G0--P11] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:38 INFO 测试结果:failed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:38 INFO 故障表示:self = <apirun.core.ApiTestRunner.TestRunner object at 0x00000215ADDBE8B0>
+caseinfo = {'_case_name': '我的书评-发布正常的书评(优化-直接Josn断言)', 'desc': '我的书评-发布正常的书评(优化-直接Josn断言)', 'featureName': '我的书评', 'process': 'G0--P', ...}
+
+    def test_case_execute(self, caseinfo):
+        casename = caseinfo["_case_name"]
+        # TODO 2-1 : 调用动态生成标题的方法
+        dynamicTitle(caseinfo)
+    
+        # TODO 2-2: 基于我们步骤一步步进行执行
+        try:
+            # 实例化关键字对象
+            keywords = KeyWords()
+    
+            # 获取当前用例变量,方便后续的渲染
+            local_context = caseinfo.get("context",{})
+            context = copy.deepcopy(g_context().show_dict())
+            context.update(local_context)
+    
+            steps = caseinfo.get("steps", None)
+            logger.info(f"-----------------开始执行测试用例:{steps}-------------")
+            for index,step in enumerate(steps):
+                #  提示信息
+                step_name = list(step.keys())[0]
+                step_value = list(step.values())[0]
+                # TODO : 每一个步骤进行变量的渲染
+                context = copy.deepcopy(g_context().show_dict())
+                context.update(local_context)
+                step_value = eval(refresh(step_value, context))
+                logger.info(f"测试用例名称:{casename},开始执行步骤{index}:{step_name} - {step_value}")
+                # 基于每个步骤的关键字,找到对应的方法,然后把参数给它
+                #  通过【反射】的方式去找到对应的方法
+                with allure.step(step_name):
+                    key = step_value["关键字"]  # 具体的方法名, 在 keywords 里面找到这个方法
+                    try:
+                        key_func = keywords.__getattribute__(key)  # 从keywords获取到对应方法
+                    except AttributeError as e:
+                        logger.error(f"测试用例名称:{casename},没有这个关键字方法", e)
+>                   key_func(**step_value)  # 调用方法
+
+core\ApiTestRunner.py:51: 
+_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+extend\keywords.py:183: in ex_mysqlData
+    logger.info("数据库查询结果:", rs)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1446: in info
+    self._log(INFO, msg, args, **kwargs)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1589: in _log
+    self.handle(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1599: in handle
+    self.callHandlers(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1661: in callHandlers
+    hdlr.handle(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:952: in handle
+    self.emit(record)
+..\myenv\lib\site-packages\_pytest\logging.py:380: in emit
+    super().emit(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1091: in emit
+    self.handleError(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1083: in emit
+    msg = self.format(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:927: in format
+    return fmt.format(record)
+..\myenv\lib\site-packages\_pytest\logging.py:140: in format
+    return super().format(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:663: in format
+    record.message = record.getMessage()
+_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+
+self = <LogRecord: testlog, 20, D:\001_zzh\eng\api-engine\apirun\extend\keywords.py, 183, "数据库查询结果:">
+
+    def getMessage(self):
+        """
+        Return the message for this LogRecord.
+    
+        Return the message for this LogRecord after merging any user-supplied
+        arguments with the message.
+        """
+        msg = str(self.msg)
+        if self.args:
+>           msg = msg % self.args
+E           TypeError: not all arguments converted during string formatting
+
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:367: TypeError conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:38 INFO 异常:<ExceptionInfo TypeError('not all arguments converted during string formatting') tblen=43> conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:38 INFO 用例耗时:0.20688920000000044 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:38 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:38 INFO -----------------开始执行测试用例:[{'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/user/login', 'PARAMS': None, 'HEADERS': None, 'DATA': {'username': '{{username}}', 'password': '{{password}}'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'通过JSONPATH提取数据-TOKEN': {'关键字': 'ex_jsonData', 'EXVALUE': '$..token', 'INDEX': None, 'VARNAME': 'token'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:38 INFO 测试用例名称:备份_能够正确登录用例,开始执行步骤0:发送Post请求 - {'关键字': 'request_post_form_urlencoded', 'URL': 'http://120.25.127.201:18001//user/login', 'PARAMS': None, 'HEADERS': None, 'DATA': {'username': '15096268001', 'password': '123456'}} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:38 INFO 测试用例名称:备份_能够正确登录用例,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:38 INFO 测试用例名称:备份_能够正确登录用例,开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:38 INFO 测试用例名称:备份_能够正确登录用例,开始执行步骤3:通过JSONPATH提取数据-TOKEN - {'关键字': 'ex_jsonData', 'EXVALUE': '$..token', 'INDEX': None, 'VARNAME': 'token'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:38 INFO 测试用例名称:备份_能够正确登录用例,开始执行步骤4:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:38 INFO 测试用例名称:备份_能够正确登录用例,开始执行步骤5:断言-等于-CODE - {'关键字': 'assert_text_comparators', 'VALUE': '200', 'EXPECTED': '200', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:38 INFO -------------------测试用例名称:备份_能够正确登录用例执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:38 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G0--P12] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:38 INFO 测试结果:passed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:38 INFO 故障表示:None conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:38 INFO 异常:None conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:38 INFO 用例耗时:0.08122730000000011 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:38 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:38 INFO -----------------开始执行测试用例:[{'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/user/login', 'PARAMS': None, 'HEADERS': None, 'DATA': {'username': '15096268001', 'password': '1234562'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': '手机号或密码错误!', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '1004', 'OP_STR': '=='}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:38 INFO 测试用例名称:备份_登录失败-手机号或密码错误用例,开始执行步骤0:发送Post请求 - {'关键字': 'request_post_form_urlencoded', 'URL': 'http://120.25.127.201:18001//user/login', 'PARAMS': None, 'HEADERS': None, 'DATA': {'username': '15096268001', 'password': '1234562'}} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:38 INFO 测试用例名称:备份_登录失败-手机号或密码错误用例,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:38 INFO 测试用例名称:备份_登录失败-手机号或密码错误用例,开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:38 INFO 测试用例名称:备份_登录失败-手机号或密码错误用例,开始执行步骤3:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': '手机号或密码错误!', 'EXPECTED': '手机号或密码错误!', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:38 INFO 测试用例名称:备份_登录失败-手机号或密码错误用例,开始执行步骤4:断言-等于-CODE - {'关键字': 'assert_text_comparators', 'VALUE': '1004', 'EXPECTED': '1004', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:38 INFO -------------------测试用例名称:备份_登录失败-手机号或密码错误用例执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:38 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G0--P13] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:38 INFO 测试结果:passed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:38 INFO 故障表示:None conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:38 INFO 异常:None conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:38 INFO 用例耗时:0.08275990000000011 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:38 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:38 INFO -----------------开始执行测试用例:[{'发送Get请求': {'关键字': 'request_get', 'URL': '{{URL}}/user/userInfo', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..username', 'INDEX': 0, 'VARNAME': 'msg_username'}}, {'断言-等于-响应USERNAME': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_username}}', 'EXPECTED': '{{username}}', 'OP_STR': '=='}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:38 INFO 测试用例名称:备份_查看用户信息,开始执行步骤0:发送Get请求 - {'关键字': 'request_get', 'URL': 'http://120.25.127.201:18001//user/userInfo', 'PARAMS': None, 'HEADERS': {'Authorization': 'eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE3MzEzMjc5MzgsInN1YiI6IntcImlkXCI6MTc5MTA1NjM4NjYzOTg3MjAwMCxcInVzZXJuYW1lXCI6XCIxNTA5NjI2ODAwMVwiLFwibmlja05hbWVcIjpcIuS4gOS6jOS4iVwifSIsImNyZWF0ZWQiOjE3MzA3MjMxMzg3MTJ9.iLS16XWs6xTMI6mmdU0SWaeOLjMOSXugU_6ZasD5tqy3Uf4rS71m-RvXGmYoRr-sWXkiw2qJIY9e54Bcc6pOVw'}} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:38 INFO 测试用例名称:备份_查看用户信息,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:38 INFO 测试用例名称:备份_查看用户信息,开始执行步骤2:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:38 INFO 测试用例名称:备份_查看用户信息,开始执行步骤3:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..username', 'INDEX': 0, 'VARNAME': 'msg_username'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:38 INFO 测试用例名称:备份_查看用户信息,开始执行步骤4:断言-等于-响应USERNAME - {'关键字': 'assert_text_comparators', 'VALUE': '15096268001', 'EXPECTED': '15096268001', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:38 INFO -------------------测试用例名称:备份_查看用户信息执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:38 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G0--P14] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:38 INFO 测试结果:passed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:38 INFO 故障表示:None conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:38 INFO 异常:None conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:38 INFO 用例耗时:0.08612210000000076 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:38 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:38 INFO -----------------开始执行测试用例:[{'发送Post请求-上传图片': {'关键字': 'request_post_form_data', 'URL': '{{URL}}/file/picUpload', 'FILES': '{"file":open("./files/20240725223321.png","rb")}', 'PARAMS': None, 'HEADERS': None}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}, {'通过JSONPATH提取数据-图片路径': {'关键字': 'ex_jsonData', 'EXVALUE': '$..data', 'INDEX': 0, 'VARNAME': 'msg_data'}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:38 INFO 测试用例名称:备份_修改头像-上传头像,开始执行步骤0:发送Post请求-上传图片 - {'关键字': 'request_post_form_data', 'URL': 'http://120.25.127.201:18001//file/picUpload', 'FILES': '{"file":open("./files/20240725223321.png","rb")}', 'PARAMS': None, 'HEADERS': None} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:38 INFO 测试用例名称:备份_修改头像-上传头像,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:38 INFO 测试用例名称:备份_修改头像-上传头像,开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:38 INFO 测试用例名称:备份_修改头像-上传头像,开始执行步骤3:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:38 INFO 测试用例名称:备份_修改头像-上传头像,开始执行步骤4:断言-等于-CODE - {'关键字': 'assert_text_comparators', 'VALUE': '200', 'EXPECTED': '200', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:38 INFO 测试用例名称:备份_修改头像-上传头像,开始执行步骤5:通过JSONPATH提取数据-图片路径 - {'关键字': 'ex_jsonData', 'EXVALUE': '$..data', 'INDEX': 0, 'VARNAME': 'msg_data'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:38 INFO -------------------测试用例名称:备份_修改头像-上传头像执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:38 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G0--P15] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:38 INFO 测试结果:passed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:38 INFO 故障表示:None conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:38 INFO 异常:None conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:38 INFO 用例耗时:0.07912230000000076 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:38 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:39 INFO -----------------开始执行测试用例:[{'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/user/updateUserInfo', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'userPhoto': '{{msg_data}}'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:39 INFO 测试用例名称:备份_修改头像-确定修改头像,开始执行步骤0:发送Post请求 - {'关键字': 'request_post_form_urlencoded', 'URL': 'http://120.25.127.201:18001//user/updateUserInfo', 'PARAMS': None, 'HEADERS': {'Authorization': 'eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE3MzEzMjc5MzgsInN1YiI6IntcImlkXCI6MTc5MTA1NjM4NjYzOTg3MjAwMCxcInVzZXJuYW1lXCI6XCIxNTA5NjI2ODAwMVwiLFwibmlja05hbWVcIjpcIuS4gOS6jOS4iVwifSIsImNyZWF0ZWQiOjE3MzA3MjMxMzg3MTJ9.iLS16XWs6xTMI6mmdU0SWaeOLjMOSXugU_6ZasD5tqy3Uf4rS71m-RvXGmYoRr-sWXkiw2qJIY9e54Bcc6pOVw'}, 'DATA': {'userPhoto': '/localPic/2024/11/04/058a645adf1640e4a9e857d75a4fbb31.png'}} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:39 INFO 测试用例名称:备份_修改头像-确定修改头像,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:39 INFO 测试用例名称:备份_修改头像-确定修改头像,开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:39 INFO 测试用例名称:备份_修改头像-确定修改头像,开始执行步骤3:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:39 INFO 测试用例名称:备份_修改头像-确定修改头像,开始执行步骤4:断言-等于-CODE - {'关键字': 'assert_text_comparators', 'VALUE': '200', 'EXPECTED': '200', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:39 INFO -------------------测试用例名称:备份_修改头像-确定修改头像执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:39 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G0--P16] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:39 INFO 测试结果:passed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:39 INFO 故障表示:None conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:39 INFO 异常:None conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:39 INFO 用例耗时:0.10777579999999976 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:39 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:39 INFO -----------------开始执行测试用例:[{'提取评价的书籍ID': {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}}, {'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': '{{id_1}}', 'commentContent': 'hami的接口自动化'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:39 INFO 测试用例名称:备份_我的书评-发布正常的书评(可能会失败),开始执行步骤0:提取评价的书籍ID - {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:39 INFO -------------------测试用例名称:备份_我的书评-发布正常的书评(可能会失败)执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:39 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G0--P17] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:39 INFO 测试结果:failed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:39 INFO 故障表示:self = <apirun.core.ApiTestRunner.TestRunner object at 0x00000215ADE27280>
+caseinfo = {'_case_name': '备份_我的书评-发布正常的书评(可能会失败)', 'desc': '备份_我的书评-发布正常的书评(可能会失败)', 'featureName': '我的书评', 'process': 'G0--P', ...}
+
+    def test_case_execute(self, caseinfo):
+        casename = caseinfo["_case_name"]
+        # TODO 2-1 : 调用动态生成标题的方法
+        dynamicTitle(caseinfo)
+    
+        # TODO 2-2: 基于我们步骤一步步进行执行
+        try:
+            # 实例化关键字对象
+            keywords = KeyWords()
+    
+            # 获取当前用例变量,方便后续的渲染
+            local_context = caseinfo.get("context",{})
+            context = copy.deepcopy(g_context().show_dict())
+            context.update(local_context)
+    
+            steps = caseinfo.get("steps", None)
+            logger.info(f"-----------------开始执行测试用例:{steps}-------------")
+            for index,step in enumerate(steps):
+                #  提示信息
+                step_name = list(step.keys())[0]
+                step_value = list(step.values())[0]
+                # TODO : 每一个步骤进行变量的渲染
+                context = copy.deepcopy(g_context().show_dict())
+                context.update(local_context)
+                step_value = eval(refresh(step_value, context))
+                logger.info(f"测试用例名称:{casename},开始执行步骤{index}:{step_name} - {step_value}")
+                # 基于每个步骤的关键字,找到对应的方法,然后把参数给它
+                #  通过【反射】的方式去找到对应的方法
+                with allure.step(step_name):
+                    key = step_value["关键字"]  # 具体的方法名, 在 keywords 里面找到这个方法
+                    try:
+                        key_func = keywords.__getattribute__(key)  # 从keywords获取到对应方法
+                    except AttributeError as e:
+                        logger.error(f"测试用例名称:{casename},没有这个关键字方法", e)
+>                   key_func(**step_value)  # 调用方法
+
+core\ApiTestRunner.py:51: 
+_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+extend\keywords.py:183: in ex_mysqlData
+    logger.info("数据库查询结果:", rs)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1446: in info
+    self._log(INFO, msg, args, **kwargs)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1589: in _log
+    self.handle(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1599: in handle
+    self.callHandlers(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1661: in callHandlers
+    hdlr.handle(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:952: in handle
+    self.emit(record)
+..\myenv\lib\site-packages\_pytest\logging.py:380: in emit
+    super().emit(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1091: in emit
+    self.handleError(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1083: in emit
+    msg = self.format(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:927: in format
+    return fmt.format(record)
+..\myenv\lib\site-packages\_pytest\logging.py:140: in format
+    return super().format(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:663: in format
+    record.message = record.getMessage()
+_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+
+self = <LogRecord: testlog, 20, D:\001_zzh\eng\api-engine\apirun\extend\keywords.py, 183, "数据库查询结果:">
+
+    def getMessage(self):
+        """
+        Return the message for this LogRecord.
+    
+        Return the message for this LogRecord after merging any user-supplied
+        arguments with the message.
+        """
+        msg = str(self.msg)
+        if self.args:
+>           msg = msg % self.args
+E           TypeError: not all arguments converted during string formatting
+
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:367: TypeError conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:39 INFO 异常:<ExceptionInfo TypeError('not all arguments converted during string formatting') tblen=43> conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:39 INFO 用例耗时:0.21631909999999976 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:39 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:39 INFO -----------------开始执行测试用例:[{'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': '', 'commentContent': 'hami的接口自动化'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': '书籍ID不存在', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:39 INFO 测试用例名称:备份_我的书评-发布不存在的书籍ID(BUG),开始执行步骤0:发送Post请求 - {'关键字': 'request_post_form_urlencoded', 'URL': 'http://120.25.127.201:18001//book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': 'eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE3MzEzMjc5MzgsInN1YiI6IntcImlkXCI6MTc5MTA1NjM4NjYzOTg3MjAwMCxcInVzZXJuYW1lXCI6XCIxNTA5NjI2ODAwMVwiLFwibmlja05hbWVcIjpcIuS4gOS6jOS4iVwifSIsImNyZWF0ZWQiOjE3MzA3MjMxMzg3MTJ9.iLS16XWs6xTMI6mmdU0SWaeOLjMOSXugU_6ZasD5tqy3Uf4rS71m-RvXGmYoRr-sWXkiw2qJIY9e54Bcc6pOVw'}, 'DATA': {'bookId': '', 'commentContent': 'hami的接口自动化'}} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:39 INFO 测试用例名称:备份_我的书评-发布不存在的书籍ID(BUG),开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:39 INFO 测试用例名称:备份_我的书评-发布不存在的书籍ID(BUG),开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:39 INFO 测试用例名称:备份_我的书评-发布不存在的书籍ID(BUG),开始执行步骤3:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': '书籍ID不存在', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:39 INFO -------------------测试用例名称:备份_我的书评-发布不存在的书籍ID(BUG)执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:39 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G0--P18] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:39 INFO 测试结果:failed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:39 INFO 故障表示:self = <apirun.core.ApiTestRunner.TestRunner object at 0x00000215ADE27DC0>
+caseinfo = {'_case_name': '备份_我的书评-发布不存在的书籍ID(BUG)', 'desc': '备份_我的书评-发布不存在的书籍ID(BUG)', 'featureName': '我的书评', 'process': 'G0--P', ...}
+
+    def test_case_execute(self, caseinfo):
+        casename = caseinfo["_case_name"]
+        # TODO 2-1 : 调用动态生成标题的方法
+        dynamicTitle(caseinfo)
+    
+        # TODO 2-2: 基于我们步骤一步步进行执行
+        try:
+            # 实例化关键字对象
+            keywords = KeyWords()
+    
+            # 获取当前用例变量,方便后续的渲染
+            local_context = caseinfo.get("context",{})
+            context = copy.deepcopy(g_context().show_dict())
+            context.update(local_context)
+    
+            steps = caseinfo.get("steps", None)
+            logger.info(f"-----------------开始执行测试用例:{steps}-------------")
+            for index,step in enumerate(steps):
+                #  提示信息
+                step_name = list(step.keys())[0]
+                step_value = list(step.values())[0]
+                # TODO : 每一个步骤进行变量的渲染
+                context = copy.deepcopy(g_context().show_dict())
+                context.update(local_context)
+                step_value = eval(refresh(step_value, context))
+                logger.info(f"测试用例名称:{casename},开始执行步骤{index}:{step_name} - {step_value}")
+                # 基于每个步骤的关键字,找到对应的方法,然后把参数给它
+                #  通过【反射】的方式去找到对应的方法
+                with allure.step(step_name):
+                    key = step_value["关键字"]  # 具体的方法名, 在 keywords 里面找到这个方法
+                    try:
+                        key_func = keywords.__getattribute__(key)  # 从keywords获取到对应方法
+                    except AttributeError as e:
+                        logger.error(f"测试用例名称:{casename},没有这个关键字方法", e)
+>                   key_func(**step_value)  # 调用方法
+
+core\ApiTestRunner.py:51: 
+_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+
+self = <apirun.extend.keywords.KeyWords object at 0x00000215ADFD67F0>
+kwargs = {'EXPECTED': '书籍ID不存在', 'OP_STR': '==', 'VALUE': 'SUCCESS', '关键字': 'assert_text_comparators'}
+comparators = {'!=': <function KeyWords.assert_text_comparators.<locals>.<lambda> at 0x00000215ADFCBDC0>, '<': <function KeyWords.as...at 0x00000215ADFCB040>, '==': <function KeyWords.assert_text_comparators.<locals>.<lambda> at 0x00000215ADFCB670>, ...}
+message = None
+
+    @allure.step("参数数据:断言当前文本内容")
+    def assert_text_comparators(self, **kwargs):
+        """
+        封装断言以进行不同的比较操作。
+    
+        参数:
+        value (Any): 要比较的值。
+        expected (Any): 预期的值。
+        op_str (str): 操作符的字符串表示(如 '>', '<', '==' 等)。
+        message (str, optional): 自定义的错误消息。
+    
+        返回:
+        None: 如果断言成功,则不返回任何内容。
+    
+        引发:
+        AssertionError: 如果断言失败。
+        """
+        comparators = {
+            '>': lambda a, b: a > b,
+            '<': lambda a, b: a < b,
+            '==': lambda a, b: a == b,
+            '>=': lambda a, b: a >= b,
+            '<=': lambda a, b: a <= b,
+            '!=': lambda a, b: a != b,
+        }
+    
+        message = kwargs.get("MESSAGE", None)
+    
+        if kwargs["OP_STR"] not in comparators:
+            raise ValueError(f"没有该操作方式: {kwargs['OP_STR']}")
+    
+        if not comparators[kwargs['OP_STR']](kwargs['VALUE'], kwargs["EXPECTED"]):
+            if message:
+                raise AssertionError(message)
+            else:
+>               raise AssertionError(f"{kwargs['VALUE']} {kwargs['OP_STR']} {kwargs['EXPECTED']} 失败")
+E               AssertionError: SUCCESS == 书籍ID不存在 失败
+
+extend\keywords.py:228: AssertionError conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:39 INFO 异常:<ExceptionInfo AssertionError('SUCCESS == 书籍ID不存在 失败') tblen=31> conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:39 INFO 用例耗时:0.11749030000000005 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:39 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:39 INFO -----------------开始执行测试用例:[{'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': 118, 'commentContent': 'hami的接口自动化'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': '已评价过该书籍!', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '3001', 'OP_STR': '=='}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:39 INFO 测试用例名称:备份_我的书评-发布已评价的数据,开始执行步骤0:发送Post请求 - {'关键字': 'request_post_form_urlencoded', 'URL': 'http://120.25.127.201:18001//book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': 'eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE3MzEzMjc5MzgsInN1YiI6IntcImlkXCI6MTc5MTA1NjM4NjYzOTg3MjAwMCxcInVzZXJuYW1lXCI6XCIxNTA5NjI2ODAwMVwiLFwibmlja05hbWVcIjpcIuS4gOS6jOS4iVwifSIsImNyZWF0ZWQiOjE3MzA3MjMxMzg3MTJ9.iLS16XWs6xTMI6mmdU0SWaeOLjMOSXugU_6ZasD5tqy3Uf4rS71m-RvXGmYoRr-sWXkiw2qJIY9e54Bcc6pOVw'}, 'DATA': {'bookId': 118, 'commentContent': 'hami的接口自动化'}} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:39 INFO 测试用例名称:备份_我的书评-发布已评价的数据,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:39 INFO 测试用例名称:备份_我的书评-发布已评价的数据,开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:39 INFO 测试用例名称:备份_我的书评-发布已评价的数据,开始执行步骤3:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': '已评价过该书籍!', 'EXPECTED': '已评价过该书籍!', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:39 INFO 测试用例名称:备份_我的书评-发布已评价的数据,开始执行步骤4:断言-等于-CODE - {'关键字': 'assert_text_comparators', 'VALUE': '3001', 'EXPECTED': '3001', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:39 INFO -------------------测试用例名称:备份_我的书评-发布已评价的数据执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:39 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G0--P19] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:39 INFO 测试结果:passed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:39 INFO 故障表示:None conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:39 INFO 异常:None conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:39 INFO 用例耗时:0.10991980000000012 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:39 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:39 INFO -----------------开始执行测试用例:[{'提取评价的书籍ID': {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}}, {'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': '{{id_1}}', 'commentContent': 'ham'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:39 INFO 测试用例名称:备份_我的书评-发布不满五个字的书评(BUG),开始执行步骤0:提取评价的书籍ID - {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:39 INFO -------------------测试用例名称:备份_我的书评-发布不满五个字的书评(BUG)执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:39 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G0--P20] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:39 INFO 测试结果:failed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:39 INFO 故障表示:self = <apirun.core.ApiTestRunner.TestRunner object at 0x00000215ADE27940>
+caseinfo = {'_case_name': '备份_我的书评-发布不满五个字的书评(BUG)', 'desc': '备份_我的书评-发布不满五个字的书评(BUG)', 'featureName': '我的书评', 'process': 'G0--P', ...}
+
+    def test_case_execute(self, caseinfo):
+        casename = caseinfo["_case_name"]
+        # TODO 2-1 : 调用动态生成标题的方法
+        dynamicTitle(caseinfo)
+    
+        # TODO 2-2: 基于我们步骤一步步进行执行
+        try:
+            # 实例化关键字对象
+            keywords = KeyWords()
+    
+            # 获取当前用例变量,方便后续的渲染
+            local_context = caseinfo.get("context",{})
+            context = copy.deepcopy(g_context().show_dict())
+            context.update(local_context)
+    
+            steps = caseinfo.get("steps", None)
+            logger.info(f"-----------------开始执行测试用例:{steps}-------------")
+            for index,step in enumerate(steps):
+                #  提示信息
+                step_name = list(step.keys())[0]
+                step_value = list(step.values())[0]
+                # TODO : 每一个步骤进行变量的渲染
+                context = copy.deepcopy(g_context().show_dict())
+                context.update(local_context)
+                step_value = eval(refresh(step_value, context))
+                logger.info(f"测试用例名称:{casename},开始执行步骤{index}:{step_name} - {step_value}")
+                # 基于每个步骤的关键字,找到对应的方法,然后把参数给它
+                #  通过【反射】的方式去找到对应的方法
+                with allure.step(step_name):
+                    key = step_value["关键字"]  # 具体的方法名, 在 keywords 里面找到这个方法
+                    try:
+                        key_func = keywords.__getattribute__(key)  # 从keywords获取到对应方法
+                    except AttributeError as e:
+                        logger.error(f"测试用例名称:{casename},没有这个关键字方法", e)
+>                   key_func(**step_value)  # 调用方法
+
+core\ApiTestRunner.py:51: 
+_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+extend\keywords.py:183: in ex_mysqlData
+    logger.info("数据库查询结果:", rs)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1446: in info
+    self._log(INFO, msg, args, **kwargs)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1589: in _log
+    self.handle(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1599: in handle
+    self.callHandlers(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1661: in callHandlers
+    hdlr.handle(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:952: in handle
+    self.emit(record)
+..\myenv\lib\site-packages\_pytest\logging.py:380: in emit
+    super().emit(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1091: in emit
+    self.handleError(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1083: in emit
+    msg = self.format(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:927: in format
+    return fmt.format(record)
+..\myenv\lib\site-packages\_pytest\logging.py:140: in format
+    return super().format(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:663: in format
+    record.message = record.getMessage()
+_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+
+self = <LogRecord: testlog, 20, D:\001_zzh\eng\api-engine\apirun\extend\keywords.py, 183, "数据库查询结果:">
+
+    def getMessage(self):
+        """
+        Return the message for this LogRecord.
+    
+        Return the message for this LogRecord after merging any user-supplied
+        arguments with the message.
+        """
+        msg = str(self.msg)
+        if self.args:
+>           msg = msg % self.args
+E           TypeError: not all arguments converted during string formatting
+
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:367: TypeError conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:39 INFO 异常:<ExceptionInfo TypeError('not all arguments converted during string formatting') tblen=43> conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:39 INFO 用例耗时:0.20216299999999965 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:39 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:39 INFO -----------------开始执行测试用例:[{'提取评价的书籍ID': {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}}, {'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': '{{id_1}}', 'commentContent': 'hamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhahamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamham'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': '评价不能超过200字符!', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:39 INFO 测试用例名称:备份_我的书评-发布超过200个字的书评,开始执行步骤0:提取评价的书籍ID - {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:40 INFO -------------------测试用例名称:备份_我的书评-发布超过200个字的书评执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:40 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G0--P21] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:40 INFO 测试结果:failed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:40 INFO 故障表示:self = <apirun.core.ApiTestRunner.TestRunner object at 0x00000215ADE27760>
+caseinfo = {'_case_name': '备份_我的书评-发布超过200个字的书评', 'desc': '备份_我的书评-发布超过200个字的书评', 'featureName': '我的书评', 'process': 'G0--P', ...}
+
+    def test_case_execute(self, caseinfo):
+        casename = caseinfo["_case_name"]
+        # TODO 2-1 : 调用动态生成标题的方法
+        dynamicTitle(caseinfo)
+    
+        # TODO 2-2: 基于我们步骤一步步进行执行
+        try:
+            # 实例化关键字对象
+            keywords = KeyWords()
+    
+            # 获取当前用例变量,方便后续的渲染
+            local_context = caseinfo.get("context",{})
+            context = copy.deepcopy(g_context().show_dict())
+            context.update(local_context)
+    
+            steps = caseinfo.get("steps", None)
+            logger.info(f"-----------------开始执行测试用例:{steps}-------------")
+            for index,step in enumerate(steps):
+                #  提示信息
+                step_name = list(step.keys())[0]
+                step_value = list(step.values())[0]
+                # TODO : 每一个步骤进行变量的渲染
+                context = copy.deepcopy(g_context().show_dict())
+                context.update(local_context)
+                step_value = eval(refresh(step_value, context))
+                logger.info(f"测试用例名称:{casename},开始执行步骤{index}:{step_name} - {step_value}")
+                # 基于每个步骤的关键字,找到对应的方法,然后把参数给它
+                #  通过【反射】的方式去找到对应的方法
+                with allure.step(step_name):
+                    key = step_value["关键字"]  # 具体的方法名, 在 keywords 里面找到这个方法
+                    try:
+                        key_func = keywords.__getattribute__(key)  # 从keywords获取到对应方法
+                    except AttributeError as e:
+                        logger.error(f"测试用例名称:{casename},没有这个关键字方法", e)
+>                   key_func(**step_value)  # 调用方法
+
+core\ApiTestRunner.py:51: 
+_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+extend\keywords.py:183: in ex_mysqlData
+    logger.info("数据库查询结果:", rs)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1446: in info
+    self._log(INFO, msg, args, **kwargs)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1589: in _log
+    self.handle(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1599: in handle
+    self.callHandlers(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1661: in callHandlers
+    hdlr.handle(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:952: in handle
+    self.emit(record)
+..\myenv\lib\site-packages\_pytest\logging.py:380: in emit
+    super().emit(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1091: in emit
+    self.handleError(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1083: in emit
+    msg = self.format(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:927: in format
+    return fmt.format(record)
+..\myenv\lib\site-packages\_pytest\logging.py:140: in format
+    return super().format(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:663: in format
+    record.message = record.getMessage()
+_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+
+self = <LogRecord: testlog, 20, D:\001_zzh\eng\api-engine\apirun\extend\keywords.py, 183, "数据库查询结果:">
+
+    def getMessage(self):
+        """
+        Return the message for this LogRecord.
+    
+        Return the message for this LogRecord after merging any user-supplied
+        arguments with the message.
+        """
+        msg = str(self.msg)
+        if self.args:
+>           msg = msg % self.args
+E           TypeError: not all arguments converted during string formatting
+
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:367: TypeError conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:40 INFO 异常:<ExceptionInfo TypeError('not all arguments converted during string formatting') tblen=43> conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:40 INFO 用例耗时:0.2145910999999998 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:40 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:40 INFO -----------------开始执行测试用例:[{'发送Get请求': {'关键字': 'request_get', 'URL': '{{URL}}/book/listClickRank', 'PARAMS': None, 'HEADERS': None}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': None, 'VARNAME': 'msg_success'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:40 INFO 测试用例名称:备份_点击榜单能够显示对应的数据,开始执行步骤0:发送Get请求 - {'关键字': 'request_get', 'URL': 'http://120.25.127.201:18001//book/listClickRank', 'PARAMS': None, 'HEADERS': None} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:40 INFO 测试用例名称:备份_点击榜单能够显示对应的数据,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': None, 'VARNAME': 'msg_success'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:40 INFO 测试用例名称:备份_点击榜单能够显示对应的数据,开始执行步骤2:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:40 INFO -------------------测试用例名称:备份_点击榜单能够显示对应的数据执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:40 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G0--P22] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:40 INFO 测试结果:passed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:40 INFO 故障表示:None conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:40 INFO 异常:None conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:40 INFO 用例耗时:0.12154480000000056 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:40 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:40 INFO -----------------开始执行测试用例:[{'提取评价的书籍ID': {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}}, {'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': '{{id_1}}', 'commentContent': 'hami的接口自动化'}}}, {'JSON断言-等于-响应MSG': {'关键字': 'assert_json_comparators', 'VALUE': '$..msg', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'JSON断言-等于-CODE': {'关键字': 'assert_json_comparators', 'VALUE': '$..code', 'EXPECTED': '200', 'OP_STR': '=='}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:40 INFO 测试用例名称:备份_我的书评-发布正常的书评(优化-直接Josn断言),开始执行步骤0:提取评价的书籍ID - {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:40 INFO -------------------测试用例名称:备份_我的书评-发布正常的书评(优化-直接Josn断言)执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:40 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G0--P23] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:40 INFO 测试结果:failed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:40 INFO 故障表示:self = <apirun.core.ApiTestRunner.TestRunner object at 0x00000215ADE27B20>
+caseinfo = {'_case_name': '备份_我的书评-发布正常的书评(优化-直接Josn断言)', 'desc': '备份_我的书评-发布正常的书评(优化-直接Josn断言)', 'featureName': '我的书评', 'process': 'G0--P', ...}
+
+    def test_case_execute(self, caseinfo):
+        casename = caseinfo["_case_name"]
+        # TODO 2-1 : 调用动态生成标题的方法
+        dynamicTitle(caseinfo)
+    
+        # TODO 2-2: 基于我们步骤一步步进行执行
+        try:
+            # 实例化关键字对象
+            keywords = KeyWords()
+    
+            # 获取当前用例变量,方便后续的渲染
+            local_context = caseinfo.get("context",{})
+            context = copy.deepcopy(g_context().show_dict())
+            context.update(local_context)
+    
+            steps = caseinfo.get("steps", None)
+            logger.info(f"-----------------开始执行测试用例:{steps}-------------")
+            for index,step in enumerate(steps):
+                #  提示信息
+                step_name = list(step.keys())[0]
+                step_value = list(step.values())[0]
+                # TODO : 每一个步骤进行变量的渲染
+                context = copy.deepcopy(g_context().show_dict())
+                context.update(local_context)
+                step_value = eval(refresh(step_value, context))
+                logger.info(f"测试用例名称:{casename},开始执行步骤{index}:{step_name} - {step_value}")
+                # 基于每个步骤的关键字,找到对应的方法,然后把参数给它
+                #  通过【反射】的方式去找到对应的方法
+                with allure.step(step_name):
+                    key = step_value["关键字"]  # 具体的方法名, 在 keywords 里面找到这个方法
+                    try:
+                        key_func = keywords.__getattribute__(key)  # 从keywords获取到对应方法
+                    except AttributeError as e:
+                        logger.error(f"测试用例名称:{casename},没有这个关键字方法", e)
+>                   key_func(**step_value)  # 调用方法
+
+core\ApiTestRunner.py:51: 
+_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+extend\keywords.py:183: in ex_mysqlData
+    logger.info("数据库查询结果:", rs)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1446: in info
+    self._log(INFO, msg, args, **kwargs)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1589: in _log
+    self.handle(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1599: in handle
+    self.callHandlers(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1661: in callHandlers
+    hdlr.handle(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:952: in handle
+    self.emit(record)
+..\myenv\lib\site-packages\_pytest\logging.py:380: in emit
+    super().emit(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1091: in emit
+    self.handleError(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1083: in emit
+    msg = self.format(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:927: in format
+    return fmt.format(record)
+..\myenv\lib\site-packages\_pytest\logging.py:140: in format
+    return super().format(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:663: in format
+    record.message = record.getMessage()
+_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+
+self = <LogRecord: testlog, 20, D:\001_zzh\eng\api-engine\apirun\extend\keywords.py, 183, "数据库查询结果:">
+
+    def getMessage(self):
+        """
+        Return the message for this LogRecord.
+    
+        Return the message for this LogRecord after merging any user-supplied
+        arguments with the message.
+        """
+        msg = str(self.msg)
+        if self.args:
+>           msg = msg % self.args
+E           TypeError: not all arguments converted during string formatting
+
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:367: TypeError conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:40 INFO 异常:<ExceptionInfo TypeError('not all arguments converted during string formatting') tblen=43> conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:40 INFO 用例耗时:0.2079285999999998 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:40 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:40 INFO -----------------开始执行测试用例:[{'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/user/login', 'PARAMS': None, 'HEADERS': None, 'DATA': {'username': '{{username}}', 'password': '{{password}}'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'通过JSONPATH提取数据-TOKEN': {'关键字': 'ex_jsonData', 'EXVALUE': '$..token', 'INDEX': None, 'VARNAME': 'token'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:40 INFO 测试用例名称:能够正确登录用例,开始执行步骤0:发送Post请求 - {'关键字': 'request_post_form_urlencoded', 'URL': 'http://120.25.127.201:18001//user/login', 'PARAMS': None, 'HEADERS': None, 'DATA': {'username': '15096268001', 'password': '123456'}} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:40 INFO 测试用例名称:能够正确登录用例,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:40 INFO 测试用例名称:能够正确登录用例,开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:40 INFO 测试用例名称:能够正确登录用例,开始执行步骤3:通过JSONPATH提取数据-TOKEN - {'关键字': 'ex_jsonData', 'EXVALUE': '$..token', 'INDEX': None, 'VARNAME': 'token'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:40 INFO 测试用例名称:能够正确登录用例,开始执行步骤4:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:40 INFO 测试用例名称:能够正确登录用例,开始执行步骤5:断言-等于-CODE - {'关键字': 'assert_text_comparators', 'VALUE': '200', 'EXPECTED': '200', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:40 INFO -------------------测试用例名称:能够正确登录用例执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:40 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G1--P0] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:40 INFO 测试结果:passed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:40 INFO 故障表示:None conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:40 INFO 异常:None conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:40 INFO 用例耗时:0.08391579999999976 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:40 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:40 INFO -----------------开始执行测试用例:[{'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/user/login', 'PARAMS': None, 'HEADERS': None, 'DATA': {'username': '15096268001', 'password': '1234562'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': '手机号或密码错误!', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '1004', 'OP_STR': '=='}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:40 INFO 测试用例名称:登录失败-手机号或密码错误用例,开始执行步骤0:发送Post请求 - {'关键字': 'request_post_form_urlencoded', 'URL': 'http://120.25.127.201:18001//user/login', 'PARAMS': None, 'HEADERS': None, 'DATA': {'username': '15096268001', 'password': '1234562'}} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:40 INFO 测试用例名称:登录失败-手机号或密码错误用例,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:40 INFO 测试用例名称:登录失败-手机号或密码错误用例,开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:40 INFO 测试用例名称:登录失败-手机号或密码错误用例,开始执行步骤3:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': '手机号或密码错误!', 'EXPECTED': '手机号或密码错误!', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:40 INFO 测试用例名称:登录失败-手机号或密码错误用例,开始执行步骤4:断言-等于-CODE - {'关键字': 'assert_text_comparators', 'VALUE': '1004', 'EXPECTED': '1004', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:40 INFO -------------------测试用例名称:登录失败-手机号或密码错误用例执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:40 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G1--P1] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:40 INFO 测试结果:passed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:40 INFO 故障表示:None conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:40 INFO 异常:None conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:40 INFO 用例耗时:0.08588750000000012 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:40 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:40 INFO -----------------开始执行测试用例:[{'发送Get请求': {'关键字': 'request_get', 'URL': '{{URL}}/user/userInfo', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..username', 'INDEX': 0, 'VARNAME': 'msg_username'}}, {'断言-等于-响应USERNAME': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_username}}', 'EXPECTED': '{{username}}', 'OP_STR': '=='}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:40 INFO 测试用例名称:查看用户信息,开始执行步骤0:发送Get请求 - {'关键字': 'request_get', 'URL': 'http://120.25.127.201:18001//user/userInfo', 'PARAMS': None, 'HEADERS': {'Authorization': 'eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE3MzEzMjc5NDAsInN1YiI6IntcImlkXCI6MTc5MTA1NjM4NjYzOTg3MjAwMCxcInVzZXJuYW1lXCI6XCIxNTA5NjI2ODAwMVwiLFwibmlja05hbWVcIjpcIuS4gOS6jOS4iVwifSIsImNyZWF0ZWQiOjE3MzA3MjMxNDA4MDd9.SD_JAbmSzzYUHTkOi-Z3eBNl7-3eLJ5-znJJUJgyrm0Bl-vi2HrowFGwpzuBuPZblEJ4XiOMIADyamEEf08QwQ'}} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:41 INFO 测试用例名称:查看用户信息,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:41 INFO 测试用例名称:查看用户信息,开始执行步骤2:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:41 INFO 测试用例名称:查看用户信息,开始执行步骤3:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..username', 'INDEX': 0, 'VARNAME': 'msg_username'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:41 INFO 测试用例名称:查看用户信息,开始执行步骤4:断言-等于-响应USERNAME - {'关键字': 'assert_text_comparators', 'VALUE': '15096268001', 'EXPECTED': '15096268001', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:41 INFO -------------------测试用例名称:查看用户信息执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:41 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G1--P2] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:41 INFO 测试结果:passed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:41 INFO 故障表示:None conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:41 INFO 异常:None conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:41 INFO 用例耗时:0.08128289999999971 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:41 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:41 INFO -----------------开始执行测试用例:[{'发送Post请求-上传图片': {'关键字': 'request_post_form_data', 'URL': '{{URL}}/file/picUpload', 'FILES': '{"file":open("./files/20240725223321.png","rb")}', 'PARAMS': None, 'HEADERS': None}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}, {'通过JSONPATH提取数据-图片路径': {'关键字': 'ex_jsonData', 'EXVALUE': '$..data', 'INDEX': 0, 'VARNAME': 'msg_data'}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:41 INFO 测试用例名称:修改头像-上传头像,开始执行步骤0:发送Post请求-上传图片 - {'关键字': 'request_post_form_data', 'URL': 'http://120.25.127.201:18001//file/picUpload', 'FILES': '{"file":open("./files/20240725223321.png","rb")}', 'PARAMS': None, 'HEADERS': None} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:41 INFO 测试用例名称:修改头像-上传头像,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:41 INFO 测试用例名称:修改头像-上传头像,开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:41 INFO 测试用例名称:修改头像-上传头像,开始执行步骤3:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:41 INFO 测试用例名称:修改头像-上传头像,开始执行步骤4:断言-等于-CODE - {'关键字': 'assert_text_comparators', 'VALUE': '200', 'EXPECTED': '200', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:41 INFO 测试用例名称:修改头像-上传头像,开始执行步骤5:通过JSONPATH提取数据-图片路径 - {'关键字': 'ex_jsonData', 'EXVALUE': '$..data', 'INDEX': 0, 'VARNAME': 'msg_data'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:41 INFO -------------------测试用例名称:修改头像-上传头像执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:41 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G1--P3] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:41 INFO 测试结果:passed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:41 INFO 故障表示:None conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:41 INFO 异常:None conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:41 INFO 用例耗时:0.08287570000000066 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:41 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:41 INFO -----------------开始执行测试用例:[{'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/user/updateUserInfo', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'userPhoto': '{{msg_data}}'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:41 INFO 测试用例名称:修改头像-确定修改头像,开始执行步骤0:发送Post请求 - {'关键字': 'request_post_form_urlencoded', 'URL': 'http://120.25.127.201:18001//user/updateUserInfo', 'PARAMS': None, 'HEADERS': {'Authorization': 'eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE3MzEzMjc5NDAsInN1YiI6IntcImlkXCI6MTc5MTA1NjM4NjYzOTg3MjAwMCxcInVzZXJuYW1lXCI6XCIxNTA5NjI2ODAwMVwiLFwibmlja05hbWVcIjpcIuS4gOS6jOS4iVwifSIsImNyZWF0ZWQiOjE3MzA3MjMxNDA4MDd9.SD_JAbmSzzYUHTkOi-Z3eBNl7-3eLJ5-znJJUJgyrm0Bl-vi2HrowFGwpzuBuPZblEJ4XiOMIADyamEEf08QwQ'}, 'DATA': {'userPhoto': '/localPic/2024/11/04/d56a313d79204bd5a200b6604b6af8ac.png'}} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:41 INFO 测试用例名称:修改头像-确定修改头像,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:41 INFO 测试用例名称:修改头像-确定修改头像,开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:41 INFO 测试用例名称:修改头像-确定修改头像,开始执行步骤3:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:41 INFO 测试用例名称:修改头像-确定修改头像,开始执行步骤4:断言-等于-CODE - {'关键字': 'assert_text_comparators', 'VALUE': '200', 'EXPECTED': '200', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:41 INFO -------------------测试用例名称:修改头像-确定修改头像执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:41 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G1--P4] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:41 INFO 测试结果:passed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:41 INFO 故障表示:None conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:41 INFO 异常:None conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:41 INFO 用例耗时:0.08997049999999973 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:41 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:41 INFO -----------------开始执行测试用例:[{'提取评价的书籍ID': {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}}, {'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': '{{id_1}}', 'commentContent': 'hami的接口自动化'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:41 INFO 测试用例名称:我的书评-发布正常的书评(可能会失败),开始执行步骤0:提取评价的书籍ID - {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:41 INFO -------------------测试用例名称:我的书评-发布正常的书评(可能会失败)执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:41 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G1--P5] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:41 INFO 测试结果:failed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:41 INFO 故障表示:self = <apirun.core.ApiTestRunner.TestRunner object at 0x00000215ADE27100>
+caseinfo = {'_case_name': '我的书评-发布正常的书评(可能会失败)', 'desc': '我的书评-发布正常的书评(可能会失败)', 'featureName': '我的书评', 'process': 'G1--P', ...}
+
+    def test_case_execute(self, caseinfo):
+        casename = caseinfo["_case_name"]
+        # TODO 2-1 : 调用动态生成标题的方法
+        dynamicTitle(caseinfo)
+    
+        # TODO 2-2: 基于我们步骤一步步进行执行
+        try:
+            # 实例化关键字对象
+            keywords = KeyWords()
+    
+            # 获取当前用例变量,方便后续的渲染
+            local_context = caseinfo.get("context",{})
+            context = copy.deepcopy(g_context().show_dict())
+            context.update(local_context)
+    
+            steps = caseinfo.get("steps", None)
+            logger.info(f"-----------------开始执行测试用例:{steps}-------------")
+            for index,step in enumerate(steps):
+                #  提示信息
+                step_name = list(step.keys())[0]
+                step_value = list(step.values())[0]
+                # TODO : 每一个步骤进行变量的渲染
+                context = copy.deepcopy(g_context().show_dict())
+                context.update(local_context)
+                step_value = eval(refresh(step_value, context))
+                logger.info(f"测试用例名称:{casename},开始执行步骤{index}:{step_name} - {step_value}")
+                # 基于每个步骤的关键字,找到对应的方法,然后把参数给它
+                #  通过【反射】的方式去找到对应的方法
+                with allure.step(step_name):
+                    key = step_value["关键字"]  # 具体的方法名, 在 keywords 里面找到这个方法
+                    try:
+                        key_func = keywords.__getattribute__(key)  # 从keywords获取到对应方法
+                    except AttributeError as e:
+                        logger.error(f"测试用例名称:{casename},没有这个关键字方法", e)
+>                   key_func(**step_value)  # 调用方法
+
+core\ApiTestRunner.py:51: 
+_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+extend\keywords.py:183: in ex_mysqlData
+    logger.info("数据库查询结果:", rs)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1446: in info
+    self._log(INFO, msg, args, **kwargs)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1589: in _log
+    self.handle(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1599: in handle
+    self.callHandlers(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1661: in callHandlers
+    hdlr.handle(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:952: in handle
+    self.emit(record)
+..\myenv\lib\site-packages\_pytest\logging.py:380: in emit
+    super().emit(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1091: in emit
+    self.handleError(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1083: in emit
+    msg = self.format(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:927: in format
+    return fmt.format(record)
+..\myenv\lib\site-packages\_pytest\logging.py:140: in format
+    return super().format(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:663: in format
+    record.message = record.getMessage()
+_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+
+self = <LogRecord: testlog, 20, D:\001_zzh\eng\api-engine\apirun\extend\keywords.py, 183, "数据库查询结果:">
+
+    def getMessage(self):
+        """
+        Return the message for this LogRecord.
+    
+        Return the message for this LogRecord after merging any user-supplied
+        arguments with the message.
+        """
+        msg = str(self.msg)
+        if self.args:
+>           msg = msg % self.args
+E           TypeError: not all arguments converted during string formatting
+
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:367: TypeError conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:41 INFO 异常:<ExceptionInfo TypeError('not all arguments converted during string formatting') tblen=43> conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:41 INFO 用例耗时:0.2237430000000007 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:41 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:41 INFO -----------------开始执行测试用例:[{'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': '', 'commentContent': 'hami的接口自动化'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': '书籍ID不存在', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:41 INFO 测试用例名称:我的书评-发布不存在的书籍ID(BUG),开始执行步骤0:发送Post请求 - {'关键字': 'request_post_form_urlencoded', 'URL': 'http://120.25.127.201:18001//book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': 'eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE3MzEzMjc5NDAsInN1YiI6IntcImlkXCI6MTc5MTA1NjM4NjYzOTg3MjAwMCxcInVzZXJuYW1lXCI6XCIxNTA5NjI2ODAwMVwiLFwibmlja05hbWVcIjpcIuS4gOS6jOS4iVwifSIsImNyZWF0ZWQiOjE3MzA3MjMxNDA4MDd9.SD_JAbmSzzYUHTkOi-Z3eBNl7-3eLJ5-znJJUJgyrm0Bl-vi2HrowFGwpzuBuPZblEJ4XiOMIADyamEEf08QwQ'}, 'DATA': {'bookId': '', 'commentContent': 'hami的接口自动化'}} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:41 INFO 测试用例名称:我的书评-发布不存在的书籍ID(BUG),开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:41 INFO 测试用例名称:我的书评-发布不存在的书籍ID(BUG),开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:41 INFO 测试用例名称:我的书评-发布不存在的书籍ID(BUG),开始执行步骤3:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': '书籍ID不存在', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:41 INFO -------------------测试用例名称:我的书评-发布不存在的书籍ID(BUG)执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:41 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G1--P6] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:41 INFO 测试结果:failed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:41 INFO 故障表示:self = <apirun.core.ApiTestRunner.TestRunner object at 0x00000215AD7ED520>
+caseinfo = {'_case_name': '我的书评-发布不存在的书籍ID(BUG)', 'desc': '我的书评-发布不存在的书籍ID(BUG)', 'featureName': '我的书评', 'process': 'G1--P', ...}
+
+    def test_case_execute(self, caseinfo):
+        casename = caseinfo["_case_name"]
+        # TODO 2-1 : 调用动态生成标题的方法
+        dynamicTitle(caseinfo)
+    
+        # TODO 2-2: 基于我们步骤一步步进行执行
+        try:
+            # 实例化关键字对象
+            keywords = KeyWords()
+    
+            # 获取当前用例变量,方便后续的渲染
+            local_context = caseinfo.get("context",{})
+            context = copy.deepcopy(g_context().show_dict())
+            context.update(local_context)
+    
+            steps = caseinfo.get("steps", None)
+            logger.info(f"-----------------开始执行测试用例:{steps}-------------")
+            for index,step in enumerate(steps):
+                #  提示信息
+                step_name = list(step.keys())[0]
+                step_value = list(step.values())[0]
+                # TODO : 每一个步骤进行变量的渲染
+                context = copy.deepcopy(g_context().show_dict())
+                context.update(local_context)
+                step_value = eval(refresh(step_value, context))
+                logger.info(f"测试用例名称:{casename},开始执行步骤{index}:{step_name} - {step_value}")
+                # 基于每个步骤的关键字,找到对应的方法,然后把参数给它
+                #  通过【反射】的方式去找到对应的方法
+                with allure.step(step_name):
+                    key = step_value["关键字"]  # 具体的方法名, 在 keywords 里面找到这个方法
+                    try:
+                        key_func = keywords.__getattribute__(key)  # 从keywords获取到对应方法
+                    except AttributeError as e:
+                        logger.error(f"测试用例名称:{casename},没有这个关键字方法", e)
+>                   key_func(**step_value)  # 调用方法
+
+core\ApiTestRunner.py:51: 
+_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+
+self = <apirun.extend.keywords.KeyWords object at 0x00000215ADF63370>
+kwargs = {'EXPECTED': '书籍ID不存在', 'OP_STR': '==', 'VALUE': 'SUCCESS', '关键字': 'assert_text_comparators'}
+comparators = {'!=': <function KeyWords.assert_text_comparators.<locals>.<lambda> at 0x00000215ADF42160>, '<': <function KeyWords.as...at 0x00000215ADF420D0>, '==': <function KeyWords.assert_text_comparators.<locals>.<lambda> at 0x00000215ADFCB280>, ...}
+message = None
+
+    @allure.step("参数数据:断言当前文本内容")
+    def assert_text_comparators(self, **kwargs):
+        """
+        封装断言以进行不同的比较操作。
+    
+        参数:
+        value (Any): 要比较的值。
+        expected (Any): 预期的值。
+        op_str (str): 操作符的字符串表示(如 '>', '<', '==' 等)。
+        message (str, optional): 自定义的错误消息。
+    
+        返回:
+        None: 如果断言成功,则不返回任何内容。
+    
+        引发:
+        AssertionError: 如果断言失败。
+        """
+        comparators = {
+            '>': lambda a, b: a > b,
+            '<': lambda a, b: a < b,
+            '==': lambda a, b: a == b,
+            '>=': lambda a, b: a >= b,
+            '<=': lambda a, b: a <= b,
+            '!=': lambda a, b: a != b,
+        }
+    
+        message = kwargs.get("MESSAGE", None)
+    
+        if kwargs["OP_STR"] not in comparators:
+            raise ValueError(f"没有该操作方式: {kwargs['OP_STR']}")
+    
+        if not comparators[kwargs['OP_STR']](kwargs['VALUE'], kwargs["EXPECTED"]):
+            if message:
+                raise AssertionError(message)
+            else:
+>               raise AssertionError(f"{kwargs['VALUE']} {kwargs['OP_STR']} {kwargs['EXPECTED']} 失败")
+E               AssertionError: SUCCESS == 书籍ID不存在 失败
+
+extend\keywords.py:228: AssertionError conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:41 INFO 异常:<ExceptionInfo AssertionError('SUCCESS == 书籍ID不存在 失败') tblen=31> conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:41 INFO 用例耗时:0.1314056000000008 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:41 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:41 INFO -----------------开始执行测试用例:[{'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': 118, 'commentContent': 'hami的接口自动化'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': '已评价过该书籍!', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '3001', 'OP_STR': '=='}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:41 INFO 测试用例名称:我的书评-发布已评价的数据,开始执行步骤0:发送Post请求 - {'关键字': 'request_post_form_urlencoded', 'URL': 'http://120.25.127.201:18001//book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': 'eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE3MzEzMjc5NDAsInN1YiI6IntcImlkXCI6MTc5MTA1NjM4NjYzOTg3MjAwMCxcInVzZXJuYW1lXCI6XCIxNTA5NjI2ODAwMVwiLFwibmlja05hbWVcIjpcIuS4gOS6jOS4iVwifSIsImNyZWF0ZWQiOjE3MzA3MjMxNDA4MDd9.SD_JAbmSzzYUHTkOi-Z3eBNl7-3eLJ5-znJJUJgyrm0Bl-vi2HrowFGwpzuBuPZblEJ4XiOMIADyamEEf08QwQ'}, 'DATA': {'bookId': 118, 'commentContent': 'hami的接口自动化'}} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:41 INFO 测试用例名称:我的书评-发布已评价的数据,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:41 INFO 测试用例名称:我的书评-发布已评价的数据,开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:41 INFO 测试用例名称:我的书评-发布已评价的数据,开始执行步骤3:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': '已评价过该书籍!', 'EXPECTED': '已评价过该书籍!', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:41 INFO 测试用例名称:我的书评-发布已评价的数据,开始执行步骤4:断言-等于-CODE - {'关键字': 'assert_text_comparators', 'VALUE': '3001', 'EXPECTED': '3001', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:41 INFO -------------------测试用例名称:我的书评-发布已评价的数据执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:41 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G1--P7] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:41 INFO 测试结果:passed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:41 INFO 故障表示:None conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:41 INFO 异常:None conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:41 INFO 用例耗时:0.09981740000000006 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:41 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:41 INFO -----------------开始执行测试用例:[{'提取评价的书籍ID': {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}}, {'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': '{{id_1}}', 'commentContent': 'ham'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:41 INFO 测试用例名称:我的书评-发布不满五个字的书评(BUG),开始执行步骤0:提取评价的书籍ID - {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:41 INFO -------------------测试用例名称:我的书评-发布不满五个字的书评(BUG)执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:42 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G1--P8] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:42 INFO 测试结果:failed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:42 INFO 故障表示:self = <apirun.core.ApiTestRunner.TestRunner object at 0x00000215AD7ED3D0>
+caseinfo = {'_case_name': '我的书评-发布不满五个字的书评(BUG)', 'desc': '我的书评-发布不满五个字的书评(BUG)', 'featureName': '我的书评', 'process': 'G1--P', ...}
+
+    def test_case_execute(self, caseinfo):
+        casename = caseinfo["_case_name"]
+        # TODO 2-1 : 调用动态生成标题的方法
+        dynamicTitle(caseinfo)
+    
+        # TODO 2-2: 基于我们步骤一步步进行执行
+        try:
+            # 实例化关键字对象
+            keywords = KeyWords()
+    
+            # 获取当前用例变量,方便后续的渲染
+            local_context = caseinfo.get("context",{})
+            context = copy.deepcopy(g_context().show_dict())
+            context.update(local_context)
+    
+            steps = caseinfo.get("steps", None)
+            logger.info(f"-----------------开始执行测试用例:{steps}-------------")
+            for index,step in enumerate(steps):
+                #  提示信息
+                step_name = list(step.keys())[0]
+                step_value = list(step.values())[0]
+                # TODO : 每一个步骤进行变量的渲染
+                context = copy.deepcopy(g_context().show_dict())
+                context.update(local_context)
+                step_value = eval(refresh(step_value, context))
+                logger.info(f"测试用例名称:{casename},开始执行步骤{index}:{step_name} - {step_value}")
+                # 基于每个步骤的关键字,找到对应的方法,然后把参数给它
+                #  通过【反射】的方式去找到对应的方法
+                with allure.step(step_name):
+                    key = step_value["关键字"]  # 具体的方法名, 在 keywords 里面找到这个方法
+                    try:
+                        key_func = keywords.__getattribute__(key)  # 从keywords获取到对应方法
+                    except AttributeError as e:
+                        logger.error(f"测试用例名称:{casename},没有这个关键字方法", e)
+>                   key_func(**step_value)  # 调用方法
+
+core\ApiTestRunner.py:51: 
+_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+extend\keywords.py:183: in ex_mysqlData
+    logger.info("数据库查询结果:", rs)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1446: in info
+    self._log(INFO, msg, args, **kwargs)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1589: in _log
+    self.handle(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1599: in handle
+    self.callHandlers(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1661: in callHandlers
+    hdlr.handle(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:952: in handle
+    self.emit(record)
+..\myenv\lib\site-packages\_pytest\logging.py:380: in emit
+    super().emit(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1091: in emit
+    self.handleError(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1083: in emit
+    msg = self.format(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:927: in format
+    return fmt.format(record)
+..\myenv\lib\site-packages\_pytest\logging.py:140: in format
+    return super().format(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:663: in format
+    record.message = record.getMessage()
+_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+
+self = <LogRecord: testlog, 20, D:\001_zzh\eng\api-engine\apirun\extend\keywords.py, 183, "数据库查询结果:">
+
+    def getMessage(self):
+        """
+        Return the message for this LogRecord.
+    
+        Return the message for this LogRecord after merging any user-supplied
+        arguments with the message.
+        """
+        msg = str(self.msg)
+        if self.args:
+>           msg = msg % self.args
+E           TypeError: not all arguments converted during string formatting
+
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:367: TypeError conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:42 INFO 异常:<ExceptionInfo TypeError('not all arguments converted during string formatting') tblen=43> conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:42 INFO 用例耗时:0.22421609999999959 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:42 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:42 INFO -----------------开始执行测试用例:[{'提取评价的书籍ID': {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}}, {'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': '{{id_1}}', 'commentContent': 'hamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhahamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamham'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': '评价不能超过200字符!', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:42 INFO 测试用例名称:我的书评-发布超过200个字的书评,开始执行步骤0:提取评价的书籍ID - {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:42 INFO -------------------测试用例名称:我的书评-发布超过200个字的书评执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:42 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G1--P9] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:42 INFO 测试结果:failed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:42 INFO 故障表示:self = <apirun.core.ApiTestRunner.TestRunner object at 0x00000215ADD91130>
+caseinfo = {'_case_name': '我的书评-发布超过200个字的书评', 'desc': '我的书评-发布超过200个字的书评', 'featureName': '我的书评', 'process': 'G1--P', ...}
+
+    def test_case_execute(self, caseinfo):
+        casename = caseinfo["_case_name"]
+        # TODO 2-1 : 调用动态生成标题的方法
+        dynamicTitle(caseinfo)
+    
+        # TODO 2-2: 基于我们步骤一步步进行执行
+        try:
+            # 实例化关键字对象
+            keywords = KeyWords()
+    
+            # 获取当前用例变量,方便后续的渲染
+            local_context = caseinfo.get("context",{})
+            context = copy.deepcopy(g_context().show_dict())
+            context.update(local_context)
+    
+            steps = caseinfo.get("steps", None)
+            logger.info(f"-----------------开始执行测试用例:{steps}-------------")
+            for index,step in enumerate(steps):
+                #  提示信息
+                step_name = list(step.keys())[0]
+                step_value = list(step.values())[0]
+                # TODO : 每一个步骤进行变量的渲染
+                context = copy.deepcopy(g_context().show_dict())
+                context.update(local_context)
+                step_value = eval(refresh(step_value, context))
+                logger.info(f"测试用例名称:{casename},开始执行步骤{index}:{step_name} - {step_value}")
+                # 基于每个步骤的关键字,找到对应的方法,然后把参数给它
+                #  通过【反射】的方式去找到对应的方法
+                with allure.step(step_name):
+                    key = step_value["关键字"]  # 具体的方法名, 在 keywords 里面找到这个方法
+                    try:
+                        key_func = keywords.__getattribute__(key)  # 从keywords获取到对应方法
+                    except AttributeError as e:
+                        logger.error(f"测试用例名称:{casename},没有这个关键字方法", e)
+>                   key_func(**step_value)  # 调用方法
+
+core\ApiTestRunner.py:51: 
+_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+extend\keywords.py:183: in ex_mysqlData
+    logger.info("数据库查询结果:", rs)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1446: in info
+    self._log(INFO, msg, args, **kwargs)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1589: in _log
+    self.handle(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1599: in handle
+    self.callHandlers(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1661: in callHandlers
+    hdlr.handle(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:952: in handle
+    self.emit(record)
+..\myenv\lib\site-packages\_pytest\logging.py:380: in emit
+    super().emit(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1091: in emit
+    self.handleError(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1083: in emit
+    msg = self.format(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:927: in format
+    return fmt.format(record)
+..\myenv\lib\site-packages\_pytest\logging.py:140: in format
+    return super().format(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:663: in format
+    record.message = record.getMessage()
+_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+
+self = <LogRecord: testlog, 20, D:\001_zzh\eng\api-engine\apirun\extend\keywords.py, 183, "数据库查询结果:">
+
+    def getMessage(self):
+        """
+        Return the message for this LogRecord.
+    
+        Return the message for this LogRecord after merging any user-supplied
+        arguments with the message.
+        """
+        msg = str(self.msg)
+        if self.args:
+>           msg = msg % self.args
+E           TypeError: not all arguments converted during string formatting
+
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:367: TypeError conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:42 INFO 异常:<ExceptionInfo TypeError('not all arguments converted during string formatting') tblen=43> conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:42 INFO 用例耗时:0.21816670000000027 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:42 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:42 INFO -----------------开始执行测试用例:[{'发送Get请求': {'关键字': 'request_get', 'URL': '{{URL}}/book/listClickRank', 'PARAMS': None, 'HEADERS': None}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': None, 'VARNAME': 'msg_success'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:42 INFO 测试用例名称:点击榜单能够显示对应的数据,开始执行步骤0:发送Get请求 - {'关键字': 'request_get', 'URL': 'http://120.25.127.201:18001//book/listClickRank', 'PARAMS': None, 'HEADERS': None} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:42 INFO 测试用例名称:点击榜单能够显示对应的数据,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': None, 'VARNAME': 'msg_success'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:42 INFO 测试用例名称:点击榜单能够显示对应的数据,开始执行步骤2:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:42 INFO -------------------测试用例名称:点击榜单能够显示对应的数据执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:42 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G1--P10] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:42 INFO 测试结果:passed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:42 INFO 故障表示:None conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:42 INFO 异常:None conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:42 INFO 用例耗时:0.12021320000000024 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:42 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:42 INFO -----------------开始执行测试用例:[{'提取评价的书籍ID': {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}}, {'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': '{{id_1}}', 'commentContent': 'hami的接口自动化'}}}, {'JSON断言-等于-响应MSG': {'关键字': 'assert_json_comparators', 'VALUE': '$..msg', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'JSON断言-等于-CODE': {'关键字': 'assert_json_comparators', 'VALUE': '$..code', 'EXPECTED': '200', 'OP_STR': '=='}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:42 INFO 测试用例名称:我的书评-发布正常的书评(优化-直接Josn断言),开始执行步骤0:提取评价的书籍ID - {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:42 INFO -------------------测试用例名称:我的书评-发布正常的书评(优化-直接Josn断言)执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:42 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G1--P11] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:42 INFO 测试结果:failed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:42 INFO 故障表示:self = <apirun.core.ApiTestRunner.TestRunner object at 0x00000215ADD912B0>
+caseinfo = {'_case_name': '我的书评-发布正常的书评(优化-直接Josn断言)', 'desc': '我的书评-发布正常的书评(优化-直接Josn断言)', 'featureName': '我的书评', 'process': 'G1--P', ...}
+
+    def test_case_execute(self, caseinfo):
+        casename = caseinfo["_case_name"]
+        # TODO 2-1 : 调用动态生成标题的方法
+        dynamicTitle(caseinfo)
+    
+        # TODO 2-2: 基于我们步骤一步步进行执行
+        try:
+            # 实例化关键字对象
+            keywords = KeyWords()
+    
+            # 获取当前用例变量,方便后续的渲染
+            local_context = caseinfo.get("context",{})
+            context = copy.deepcopy(g_context().show_dict())
+            context.update(local_context)
+    
+            steps = caseinfo.get("steps", None)
+            logger.info(f"-----------------开始执行测试用例:{steps}-------------")
+            for index,step in enumerate(steps):
+                #  提示信息
+                step_name = list(step.keys())[0]
+                step_value = list(step.values())[0]
+                # TODO : 每一个步骤进行变量的渲染
+                context = copy.deepcopy(g_context().show_dict())
+                context.update(local_context)
+                step_value = eval(refresh(step_value, context))
+                logger.info(f"测试用例名称:{casename},开始执行步骤{index}:{step_name} - {step_value}")
+                # 基于每个步骤的关键字,找到对应的方法,然后把参数给它
+                #  通过【反射】的方式去找到对应的方法
+                with allure.step(step_name):
+                    key = step_value["关键字"]  # 具体的方法名, 在 keywords 里面找到这个方法
+                    try:
+                        key_func = keywords.__getattribute__(key)  # 从keywords获取到对应方法
+                    except AttributeError as e:
+                        logger.error(f"测试用例名称:{casename},没有这个关键字方法", e)
+>                   key_func(**step_value)  # 调用方法
+
+core\ApiTestRunner.py:51: 
+_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+extend\keywords.py:183: in ex_mysqlData
+    logger.info("数据库查询结果:", rs)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1446: in info
+    self._log(INFO, msg, args, **kwargs)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1589: in _log
+    self.handle(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1599: in handle
+    self.callHandlers(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1661: in callHandlers
+    hdlr.handle(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:952: in handle
+    self.emit(record)
+..\myenv\lib\site-packages\_pytest\logging.py:380: in emit
+    super().emit(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1091: in emit
+    self.handleError(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1083: in emit
+    msg = self.format(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:927: in format
+    return fmt.format(record)
+..\myenv\lib\site-packages\_pytest\logging.py:140: in format
+    return super().format(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:663: in format
+    record.message = record.getMessage()
+_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+
+self = <LogRecord: testlog, 20, D:\001_zzh\eng\api-engine\apirun\extend\keywords.py, 183, "数据库查询结果:">
+
+    def getMessage(self):
+        """
+        Return the message for this LogRecord.
+    
+        Return the message for this LogRecord after merging any user-supplied
+        arguments with the message.
+        """
+        msg = str(self.msg)
+        if self.args:
+>           msg = msg % self.args
+E           TypeError: not all arguments converted during string formatting
+
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:367: TypeError conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:42 INFO 异常:<ExceptionInfo TypeError('not all arguments converted during string formatting') tblen=43> conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:42 INFO 用例耗时:0.2180433000000006 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:42 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:42 INFO -----------------开始执行测试用例:[{'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/user/login', 'PARAMS': None, 'HEADERS': None, 'DATA': {'username': '{{username}}', 'password': '{{password}}'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'通过JSONPATH提取数据-TOKEN': {'关键字': 'ex_jsonData', 'EXVALUE': '$..token', 'INDEX': None, 'VARNAME': 'token'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:42 INFO 测试用例名称:能够正确登录用例,开始执行步骤0:发送Post请求 - {'关键字': 'request_post_form_urlencoded', 'URL': 'http://120.25.127.201:18001//user/login', 'PARAMS': None, 'HEADERS': None, 'DATA': {'username': '15096268001', 'password': '123456'}} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:42 INFO 测试用例名称:能够正确登录用例,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:42 INFO 测试用例名称:能够正确登录用例,开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:42 INFO 测试用例名称:能够正确登录用例,开始执行步骤3:通过JSONPATH提取数据-TOKEN - {'关键字': 'ex_jsonData', 'EXVALUE': '$..token', 'INDEX': None, 'VARNAME': 'token'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:42 INFO 测试用例名称:能够正确登录用例,开始执行步骤4:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:42 INFO 测试用例名称:能够正确登录用例,开始执行步骤5:断言-等于-CODE - {'关键字': 'assert_text_comparators', 'VALUE': '200', 'EXPECTED': '200', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:42 INFO -------------------测试用例名称:能够正确登录用例执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:42 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G3--P0] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:42 INFO 测试结果:passed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:42 INFO 故障表示:None conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:42 INFO 异常:None conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:42 INFO 用例耗时:0.08833190000000002 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:42 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:42 INFO -----------------开始执行测试用例:[{'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/user/login', 'PARAMS': None, 'HEADERS': None, 'DATA': {'username': '15096268001', 'password': '1234562'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': '手机号或密码错误!', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '1004', 'OP_STR': '=='}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:42 INFO 测试用例名称:登录失败-手机号或密码错误用例,开始执行步骤0:发送Post请求 - {'关键字': 'request_post_form_urlencoded', 'URL': 'http://120.25.127.201:18001//user/login', 'PARAMS': None, 'HEADERS': None, 'DATA': {'username': '15096268001', 'password': '1234562'}} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:43 INFO 测试用例名称:登录失败-手机号或密码错误用例,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:43 INFO 测试用例名称:登录失败-手机号或密码错误用例,开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:43 INFO 测试用例名称:登录失败-手机号或密码错误用例,开始执行步骤3:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': '手机号或密码错误!', 'EXPECTED': '手机号或密码错误!', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:43 INFO 测试用例名称:登录失败-手机号或密码错误用例,开始执行步骤4:断言-等于-CODE - {'关键字': 'assert_text_comparators', 'VALUE': '1004', 'EXPECTED': '1004', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:43 INFO -------------------测试用例名称:登录失败-手机号或密码错误用例执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:43 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G3--P1] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:43 INFO 测试结果:passed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:43 INFO 故障表示:None conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:43 INFO 异常:None conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:43 INFO 用例耗时:0.08791390000000021 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:43 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:43 INFO -----------------开始执行测试用例:[{'发送Get请求': {'关键字': 'request_get', 'URL': '{{URL}}/user/userInfo', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..username', 'INDEX': 0, 'VARNAME': 'msg_username'}}, {'断言-等于-响应USERNAME': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_username}}', 'EXPECTED': '{{username}}', 'OP_STR': '=='}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:43 INFO 测试用例名称:查看用户信息,开始执行步骤0:发送Get请求 - {'关键字': 'request_get', 'URL': 'http://120.25.127.201:18001//user/userInfo', 'PARAMS': None, 'HEADERS': {'Authorization': 'eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE3MzEzMjc5NDIsInN1YiI6IntcImlkXCI6MTc5MTA1NjM4NjYzOTg3MjAwMCxcInVzZXJuYW1lXCI6XCIxNTA5NjI2ODAwMVwiLFwibmlja05hbWVcIjpcIuS4gOS6jOS4iVwifSIsImNyZWF0ZWQiOjE3MzA3MjMxNDI5MzJ9.GuTgz0vBHbVprp8aluVjtGeP5Ezeu2CCImLLPRYhH19N2xgzmvbGeDwDgZZ4Mme20rJnfkpZVpF8ThwY5gGslQ'}} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:43 INFO 测试用例名称:查看用户信息,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:43 INFO 测试用例名称:查看用户信息,开始执行步骤2:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:43 INFO 测试用例名称:查看用户信息,开始执行步骤3:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..username', 'INDEX': 0, 'VARNAME': 'msg_username'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:43 INFO 测试用例名称:查看用户信息,开始执行步骤4:断言-等于-响应USERNAME - {'关键字': 'assert_text_comparators', 'VALUE': '15096268001', 'EXPECTED': '15096268001', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:43 INFO -------------------测试用例名称:查看用户信息执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:43 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G3--P2] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:43 INFO 测试结果:passed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:43 INFO 故障表示:None conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:43 INFO 异常:None conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:43 INFO 用例耗时:0.08571500000000043 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:43 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:43 INFO -----------------开始执行测试用例:[{'发送Post请求-上传图片': {'关键字': 'request_post_form_data', 'URL': '{{URL}}/file/picUpload', 'FILES': '{"file":open("./files/20240725223321.png","rb")}', 'PARAMS': None, 'HEADERS': None}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}, {'通过JSONPATH提取数据-图片路径': {'关键字': 'ex_jsonData', 'EXVALUE': '$..data', 'INDEX': 0, 'VARNAME': 'msg_data'}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:43 INFO 测试用例名称:修改头像-上传头像,开始执行步骤0:发送Post请求-上传图片 - {'关键字': 'request_post_form_data', 'URL': 'http://120.25.127.201:18001//file/picUpload', 'FILES': '{"file":open("./files/20240725223321.png","rb")}', 'PARAMS': None, 'HEADERS': None} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:43 INFO 测试用例名称:修改头像-上传头像,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:43 INFO 测试用例名称:修改头像-上传头像,开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:43 INFO 测试用例名称:修改头像-上传头像,开始执行步骤3:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:43 INFO 测试用例名称:修改头像-上传头像,开始执行步骤4:断言-等于-CODE - {'关键字': 'assert_text_comparators', 'VALUE': '200', 'EXPECTED': '200', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:43 INFO 测试用例名称:修改头像-上传头像,开始执行步骤5:通过JSONPATH提取数据-图片路径 - {'关键字': 'ex_jsonData', 'EXVALUE': '$..data', 'INDEX': 0, 'VARNAME': 'msg_data'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:43 INFO -------------------测试用例名称:修改头像-上传头像执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:43 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G3--P3] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:43 INFO 测试结果:passed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:43 INFO 故障表示:None conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:43 INFO 异常:None conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:43 INFO 用例耗时:0.08649390000000068 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:43 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:43 INFO -----------------开始执行测试用例:[{'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/user/updateUserInfo', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'userPhoto': '{{msg_data}}'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:43 INFO 测试用例名称:修改头像-确定修改头像,开始执行步骤0:发送Post请求 - {'关键字': 'request_post_form_urlencoded', 'URL': 'http://120.25.127.201:18001//user/updateUserInfo', 'PARAMS': None, 'HEADERS': {'Authorization': 'eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE3MzEzMjc5NDIsInN1YiI6IntcImlkXCI6MTc5MTA1NjM4NjYzOTg3MjAwMCxcInVzZXJuYW1lXCI6XCIxNTA5NjI2ODAwMVwiLFwibmlja05hbWVcIjpcIuS4gOS6jOS4iVwifSIsImNyZWF0ZWQiOjE3MzA3MjMxNDI5MzJ9.GuTgz0vBHbVprp8aluVjtGeP5Ezeu2CCImLLPRYhH19N2xgzmvbGeDwDgZZ4Mme20rJnfkpZVpF8ThwY5gGslQ'}, 'DATA': {'userPhoto': '/localPic/2024/11/04/570f407f9a3e466caa6f146b4f9b8af4.png'}} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:43 INFO 测试用例名称:修改头像-确定修改头像,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:43 INFO 测试用例名称:修改头像-确定修改头像,开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:43 INFO 测试用例名称:修改头像-确定修改头像,开始执行步骤3:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:43 INFO 测试用例名称:修改头像-确定修改头像,开始执行步骤4:断言-等于-CODE - {'关键字': 'assert_text_comparators', 'VALUE': '200', 'EXPECTED': '200', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:43 INFO -------------------测试用例名称:修改头像-确定修改头像执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:43 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G3--P4] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:43 INFO 测试结果:passed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:43 INFO 故障表示:None conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:43 INFO 异常:None conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:43 INFO 用例耗时:0.09365689999999915 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:43 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:43 INFO -----------------开始执行测试用例:[{'提取评价的书籍ID': {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}}, {'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': '{{id_1}}', 'commentContent': 'hami的接口自动化'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:43 INFO 测试用例名称:我的书评-发布正常的书评(可能会失败),开始执行步骤0:提取评价的书籍ID - {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:43 INFO -------------------测试用例名称:我的书评-发布正常的书评(可能会失败)执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:43 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G3--P5] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:43 INFO 测试结果:failed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:43 INFO 故障表示:self = <apirun.core.ApiTestRunner.TestRunner object at 0x00000215ADD91730>
+caseinfo = {'_case_name': '我的书评-发布正常的书评(可能会失败)', 'desc': '我的书评-发布正常的书评(可能会失败)', 'featureName': '我的书评', 'process': 'G3--P', ...}
+
+    def test_case_execute(self, caseinfo):
+        casename = caseinfo["_case_name"]
+        # TODO 2-1 : 调用动态生成标题的方法
+        dynamicTitle(caseinfo)
+    
+        # TODO 2-2: 基于我们步骤一步步进行执行
+        try:
+            # 实例化关键字对象
+            keywords = KeyWords()
+    
+            # 获取当前用例变量,方便后续的渲染
+            local_context = caseinfo.get("context",{})
+            context = copy.deepcopy(g_context().show_dict())
+            context.update(local_context)
+    
+            steps = caseinfo.get("steps", None)
+            logger.info(f"-----------------开始执行测试用例:{steps}-------------")
+            for index,step in enumerate(steps):
+                #  提示信息
+                step_name = list(step.keys())[0]
+                step_value = list(step.values())[0]
+                # TODO : 每一个步骤进行变量的渲染
+                context = copy.deepcopy(g_context().show_dict())
+                context.update(local_context)
+                step_value = eval(refresh(step_value, context))
+                logger.info(f"测试用例名称:{casename},开始执行步骤{index}:{step_name} - {step_value}")
+                # 基于每个步骤的关键字,找到对应的方法,然后把参数给它
+                #  通过【反射】的方式去找到对应的方法
+                with allure.step(step_name):
+                    key = step_value["关键字"]  # 具体的方法名, 在 keywords 里面找到这个方法
+                    try:
+                        key_func = keywords.__getattribute__(key)  # 从keywords获取到对应方法
+                    except AttributeError as e:
+                        logger.error(f"测试用例名称:{casename},没有这个关键字方法", e)
+>                   key_func(**step_value)  # 调用方法
+
+core\ApiTestRunner.py:51: 
+_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+extend\keywords.py:183: in ex_mysqlData
+    logger.info("数据库查询结果:", rs)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1446: in info
+    self._log(INFO, msg, args, **kwargs)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1589: in _log
+    self.handle(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1599: in handle
+    self.callHandlers(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1661: in callHandlers
+    hdlr.handle(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:952: in handle
+    self.emit(record)
+..\myenv\lib\site-packages\_pytest\logging.py:380: in emit
+    super().emit(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1091: in emit
+    self.handleError(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1083: in emit
+    msg = self.format(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:927: in format
+    return fmt.format(record)
+..\myenv\lib\site-packages\_pytest\logging.py:140: in format
+    return super().format(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:663: in format
+    record.message = record.getMessage()
+_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+
+self = <LogRecord: testlog, 20, D:\001_zzh\eng\api-engine\apirun\extend\keywords.py, 183, "数据库查询结果:">
+
+    def getMessage(self):
+        """
+        Return the message for this LogRecord.
+    
+        Return the message for this LogRecord after merging any user-supplied
+        arguments with the message.
+        """
+        msg = str(self.msg)
+        if self.args:
+>           msg = msg % self.args
+E           TypeError: not all arguments converted during string formatting
+
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:367: TypeError conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:43 INFO 异常:<ExceptionInfo TypeError('not all arguments converted during string formatting') tblen=43> conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:43 INFO 用例耗时:0.22499270000000138 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:43 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:43 INFO -----------------开始执行测试用例:[{'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': '', 'commentContent': 'hami的接口自动化'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': '书籍ID不存在', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:43 INFO 测试用例名称:我的书评-发布不存在的书籍ID(BUG),开始执行步骤0:发送Post请求 - {'关键字': 'request_post_form_urlencoded', 'URL': 'http://120.25.127.201:18001//book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': 'eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE3MzEzMjc5NDIsInN1YiI6IntcImlkXCI6MTc5MTA1NjM4NjYzOTg3MjAwMCxcInVzZXJuYW1lXCI6XCIxNTA5NjI2ODAwMVwiLFwibmlja05hbWVcIjpcIuS4gOS6jOS4iVwifSIsImNyZWF0ZWQiOjE3MzA3MjMxNDI5MzJ9.GuTgz0vBHbVprp8aluVjtGeP5Ezeu2CCImLLPRYhH19N2xgzmvbGeDwDgZZ4Mme20rJnfkpZVpF8ThwY5gGslQ'}, 'DATA': {'bookId': '', 'commentContent': 'hami的接口自动化'}} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:43 INFO 测试用例名称:我的书评-发布不存在的书籍ID(BUG),开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:43 INFO 测试用例名称:我的书评-发布不存在的书籍ID(BUG),开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:43 INFO 测试用例名称:我的书评-发布不存在的书籍ID(BUG),开始执行步骤3:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': '书籍ID不存在', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:43 INFO -------------------测试用例名称:我的书评-发布不存在的书籍ID(BUG)执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:43 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G3--P6] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:43 INFO 测试结果:failed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:43 INFO 故障表示:self = <apirun.core.ApiTestRunner.TestRunner object at 0x00000215ADD917F0>
+caseinfo = {'_case_name': '我的书评-发布不存在的书籍ID(BUG)', 'desc': '我的书评-发布不存在的书籍ID(BUG)', 'featureName': '我的书评', 'process': 'G3--P', ...}
+
+    def test_case_execute(self, caseinfo):
+        casename = caseinfo["_case_name"]
+        # TODO 2-1 : 调用动态生成标题的方法
+        dynamicTitle(caseinfo)
+    
+        # TODO 2-2: 基于我们步骤一步步进行执行
+        try:
+            # 实例化关键字对象
+            keywords = KeyWords()
+    
+            # 获取当前用例变量,方便后续的渲染
+            local_context = caseinfo.get("context",{})
+            context = copy.deepcopy(g_context().show_dict())
+            context.update(local_context)
+    
+            steps = caseinfo.get("steps", None)
+            logger.info(f"-----------------开始执行测试用例:{steps}-------------")
+            for index,step in enumerate(steps):
+                #  提示信息
+                step_name = list(step.keys())[0]
+                step_value = list(step.values())[0]
+                # TODO : 每一个步骤进行变量的渲染
+                context = copy.deepcopy(g_context().show_dict())
+                context.update(local_context)
+                step_value = eval(refresh(step_value, context))
+                logger.info(f"测试用例名称:{casename},开始执行步骤{index}:{step_name} - {step_value}")
+                # 基于每个步骤的关键字,找到对应的方法,然后把参数给它
+                #  通过【反射】的方式去找到对应的方法
+                with allure.step(step_name):
+                    key = step_value["关键字"]  # 具体的方法名, 在 keywords 里面找到这个方法
+                    try:
+                        key_func = keywords.__getattribute__(key)  # 从keywords获取到对应方法
+                    except AttributeError as e:
+                        logger.error(f"测试用例名称:{casename},没有这个关键字方法", e)
+>                   key_func(**step_value)  # 调用方法
+
+core\ApiTestRunner.py:51: 
+_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+
+self = <apirun.extend.keywords.KeyWords object at 0x00000215AE0D9490>
+kwargs = {'EXPECTED': '书籍ID不存在', 'OP_STR': '==', 'VALUE': 'SUCCESS', '关键字': 'assert_text_comparators'}
+comparators = {'!=': <function KeyWords.assert_text_comparators.<locals>.<lambda> at 0x00000215ADF675E0>, '<': <function KeyWords.as...at 0x00000215ADF67550>, '==': <function KeyWords.assert_text_comparators.<locals>.<lambda> at 0x00000215ADF67430>, ...}
+message = None
+
+    @allure.step("参数数据:断言当前文本内容")
+    def assert_text_comparators(self, **kwargs):
+        """
+        封装断言以进行不同的比较操作。
+    
+        参数:
+        value (Any): 要比较的值。
+        expected (Any): 预期的值。
+        op_str (str): 操作符的字符串表示(如 '>', '<', '==' 等)。
+        message (str, optional): 自定义的错误消息。
+    
+        返回:
+        None: 如果断言成功,则不返回任何内容。
+    
+        引发:
+        AssertionError: 如果断言失败。
+        """
+        comparators = {
+            '>': lambda a, b: a > b,
+            '<': lambda a, b: a < b,
+            '==': lambda a, b: a == b,
+            '>=': lambda a, b: a >= b,
+            '<=': lambda a, b: a <= b,
+            '!=': lambda a, b: a != b,
+        }
+    
+        message = kwargs.get("MESSAGE", None)
+    
+        if kwargs["OP_STR"] not in comparators:
+            raise ValueError(f"没有该操作方式: {kwargs['OP_STR']}")
+    
+        if not comparators[kwargs['OP_STR']](kwargs['VALUE'], kwargs["EXPECTED"]):
+            if message:
+                raise AssertionError(message)
+            else:
+>               raise AssertionError(f"{kwargs['VALUE']} {kwargs['OP_STR']} {kwargs['EXPECTED']} 失败")
+E               AssertionError: SUCCESS == 书籍ID不存在 失败
+
+extend\keywords.py:228: AssertionError conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:43 INFO 异常:<ExceptionInfo AssertionError('SUCCESS == 书籍ID不存在 失败') tblen=31> conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:43 INFO 用例耗时:0.1124168000000001 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:43 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:43 INFO -----------------开始执行测试用例:[{'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': 118, 'commentContent': 'hami的接口自动化'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': '已评价过该书籍!', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '3001', 'OP_STR': '=='}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:43 INFO 测试用例名称:我的书评-发布已评价的数据,开始执行步骤0:发送Post请求 - {'关键字': 'request_post_form_urlencoded', 'URL': 'http://120.25.127.201:18001//book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': 'eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE3MzEzMjc5NDIsInN1YiI6IntcImlkXCI6MTc5MTA1NjM4NjYzOTg3MjAwMCxcInVzZXJuYW1lXCI6XCIxNTA5NjI2ODAwMVwiLFwibmlja05hbWVcIjpcIuS4gOS6jOS4iVwifSIsImNyZWF0ZWQiOjE3MzA3MjMxNDI5MzJ9.GuTgz0vBHbVprp8aluVjtGeP5Ezeu2CCImLLPRYhH19N2xgzmvbGeDwDgZZ4Mme20rJnfkpZVpF8ThwY5gGslQ'}, 'DATA': {'bookId': 118, 'commentContent': 'hami的接口自动化'}} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:43 INFO 测试用例名称:我的书评-发布已评价的数据,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:43 INFO 测试用例名称:我的书评-发布已评价的数据,开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:43 INFO 测试用例名称:我的书评-发布已评价的数据,开始执行步骤3:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': '已评价过该书籍!', 'EXPECTED': '已评价过该书籍!', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:43 INFO 测试用例名称:我的书评-发布已评价的数据,开始执行步骤4:断言-等于-CODE - {'关键字': 'assert_text_comparators', 'VALUE': '3001', 'EXPECTED': '3001', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:43 INFO -------------------测试用例名称:我的书评-发布已评价的数据执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:43 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G3--P7] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:43 INFO 测试结果:passed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:43 INFO 故障表示:None conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:43 INFO 异常:None conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:43 INFO 用例耗时:0.09828979999999987 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:43 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:43 INFO -----------------开始执行测试用例:[{'提取评价的书籍ID': {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}}, {'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': '{{id_1}}', 'commentContent': 'ham'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:43 INFO 测试用例名称:我的书评-发布不满五个字的书评(BUG),开始执行步骤0:提取评价的书籍ID - {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:44 INFO -------------------测试用例名称:我的书评-发布不满五个字的书评(BUG)执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:44 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G3--P8] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:44 INFO 测试结果:failed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:44 INFO 故障表示:self = <apirun.core.ApiTestRunner.TestRunner object at 0x00000215ADD91970>
+caseinfo = {'_case_name': '我的书评-发布不满五个字的书评(BUG)', 'desc': '我的书评-发布不满五个字的书评(BUG)', 'featureName': '我的书评', 'process': 'G3--P', ...}
+
+    def test_case_execute(self, caseinfo):
+        casename = caseinfo["_case_name"]
+        # TODO 2-1 : 调用动态生成标题的方法
+        dynamicTitle(caseinfo)
+    
+        # TODO 2-2: 基于我们步骤一步步进行执行
+        try:
+            # 实例化关键字对象
+            keywords = KeyWords()
+    
+            # 获取当前用例变量,方便后续的渲染
+            local_context = caseinfo.get("context",{})
+            context = copy.deepcopy(g_context().show_dict())
+            context.update(local_context)
+    
+            steps = caseinfo.get("steps", None)
+            logger.info(f"-----------------开始执行测试用例:{steps}-------------")
+            for index,step in enumerate(steps):
+                #  提示信息
+                step_name = list(step.keys())[0]
+                step_value = list(step.values())[0]
+                # TODO : 每一个步骤进行变量的渲染
+                context = copy.deepcopy(g_context().show_dict())
+                context.update(local_context)
+                step_value = eval(refresh(step_value, context))
+                logger.info(f"测试用例名称:{casename},开始执行步骤{index}:{step_name} - {step_value}")
+                # 基于每个步骤的关键字,找到对应的方法,然后把参数给它
+                #  通过【反射】的方式去找到对应的方法
+                with allure.step(step_name):
+                    key = step_value["关键字"]  # 具体的方法名, 在 keywords 里面找到这个方法
+                    try:
+                        key_func = keywords.__getattribute__(key)  # 从keywords获取到对应方法
+                    except AttributeError as e:
+                        logger.error(f"测试用例名称:{casename},没有这个关键字方法", e)
+>                   key_func(**step_value)  # 调用方法
+
+core\ApiTestRunner.py:51: 
+_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+extend\keywords.py:183: in ex_mysqlData
+    logger.info("数据库查询结果:", rs)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1446: in info
+    self._log(INFO, msg, args, **kwargs)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1589: in _log
+    self.handle(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1599: in handle
+    self.callHandlers(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1661: in callHandlers
+    hdlr.handle(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:952: in handle
+    self.emit(record)
+..\myenv\lib\site-packages\_pytest\logging.py:380: in emit
+    super().emit(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1091: in emit
+    self.handleError(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1083: in emit
+    msg = self.format(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:927: in format
+    return fmt.format(record)
+..\myenv\lib\site-packages\_pytest\logging.py:140: in format
+    return super().format(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:663: in format
+    record.message = record.getMessage()
+_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+
+self = <LogRecord: testlog, 20, D:\001_zzh\eng\api-engine\apirun\extend\keywords.py, 183, "数据库查询结果:">
+
+    def getMessage(self):
+        """
+        Return the message for this LogRecord.
+    
+        Return the message for this LogRecord after merging any user-supplied
+        arguments with the message.
+        """
+        msg = str(self.msg)
+        if self.args:
+>           msg = msg % self.args
+E           TypeError: not all arguments converted during string formatting
+
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:367: TypeError conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:44 INFO 异常:<ExceptionInfo TypeError('not all arguments converted during string formatting') tblen=43> conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:44 INFO 用例耗时:0.2153898999999999 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:44 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:44 INFO -----------------开始执行测试用例:[{'提取评价的书籍ID': {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}}, {'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': '{{id_1}}', 'commentContent': 'hamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhahamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamham'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': '评价不能超过200字符!', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:44 INFO 测试用例名称:我的书评-发布超过200个字的书评,开始执行步骤0:提取评价的书籍ID - {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:44 INFO -------------------测试用例名称:我的书评-发布超过200个字的书评执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:44 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G3--P9] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:44 INFO 测试结果:failed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:44 INFO 故障表示:self = <apirun.core.ApiTestRunner.TestRunner object at 0x00000215ADD91A30>
+caseinfo = {'_case_name': '我的书评-发布超过200个字的书评', 'desc': '我的书评-发布超过200个字的书评', 'featureName': '我的书评', 'process': 'G3--P', ...}
+
+    def test_case_execute(self, caseinfo):
+        casename = caseinfo["_case_name"]
+        # TODO 2-1 : 调用动态生成标题的方法
+        dynamicTitle(caseinfo)
+    
+        # TODO 2-2: 基于我们步骤一步步进行执行
+        try:
+            # 实例化关键字对象
+            keywords = KeyWords()
+    
+            # 获取当前用例变量,方便后续的渲染
+            local_context = caseinfo.get("context",{})
+            context = copy.deepcopy(g_context().show_dict())
+            context.update(local_context)
+    
+            steps = caseinfo.get("steps", None)
+            logger.info(f"-----------------开始执行测试用例:{steps}-------------")
+            for index,step in enumerate(steps):
+                #  提示信息
+                step_name = list(step.keys())[0]
+                step_value = list(step.values())[0]
+                # TODO : 每一个步骤进行变量的渲染
+                context = copy.deepcopy(g_context().show_dict())
+                context.update(local_context)
+                step_value = eval(refresh(step_value, context))
+                logger.info(f"测试用例名称:{casename},开始执行步骤{index}:{step_name} - {step_value}")
+                # 基于每个步骤的关键字,找到对应的方法,然后把参数给它
+                #  通过【反射】的方式去找到对应的方法
+                with allure.step(step_name):
+                    key = step_value["关键字"]  # 具体的方法名, 在 keywords 里面找到这个方法
+                    try:
+                        key_func = keywords.__getattribute__(key)  # 从keywords获取到对应方法
+                    except AttributeError as e:
+                        logger.error(f"测试用例名称:{casename},没有这个关键字方法", e)
+>                   key_func(**step_value)  # 调用方法
+
+core\ApiTestRunner.py:51: 
+_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+extend\keywords.py:183: in ex_mysqlData
+    logger.info("数据库查询结果:", rs)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1446: in info
+    self._log(INFO, msg, args, **kwargs)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1589: in _log
+    self.handle(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1599: in handle
+    self.callHandlers(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1661: in callHandlers
+    hdlr.handle(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:952: in handle
+    self.emit(record)
+..\myenv\lib\site-packages\_pytest\logging.py:380: in emit
+    super().emit(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1091: in emit
+    self.handleError(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1083: in emit
+    msg = self.format(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:927: in format
+    return fmt.format(record)
+..\myenv\lib\site-packages\_pytest\logging.py:140: in format
+    return super().format(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:663: in format
+    record.message = record.getMessage()
+_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+
+self = <LogRecord: testlog, 20, D:\001_zzh\eng\api-engine\apirun\extend\keywords.py, 183, "数据库查询结果:">
+
+    def getMessage(self):
+        """
+        Return the message for this LogRecord.
+    
+        Return the message for this LogRecord after merging any user-supplied
+        arguments with the message.
+        """
+        msg = str(self.msg)
+        if self.args:
+>           msg = msg % self.args
+E           TypeError: not all arguments converted during string formatting
+
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:367: TypeError conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:44 INFO 异常:<ExceptionInfo TypeError('not all arguments converted during string formatting') tblen=43> conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:44 INFO 用例耗时:0.21632590000000107 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:44 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:44 INFO -----------------开始执行测试用例:[{'发送Get请求': {'关键字': 'request_get', 'URL': '{{URL}}/book/listClickRank', 'PARAMS': None, 'HEADERS': None}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': None, 'VARNAME': 'msg_success'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:44 INFO 测试用例名称:点击榜单能够显示对应的数据,开始执行步骤0:发送Get请求 - {'关键字': 'request_get', 'URL': 'http://120.25.127.201:18001//book/listClickRank', 'PARAMS': None, 'HEADERS': None} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:44 INFO 测试用例名称:点击榜单能够显示对应的数据,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': None, 'VARNAME': 'msg_success'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:44 INFO 测试用例名称:点击榜单能够显示对应的数据,开始执行步骤2:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:44 INFO -------------------测试用例名称:点击榜单能够显示对应的数据执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:44 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G3--P10] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:44 INFO 测试结果:passed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:44 INFO 故障表示:None conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:44 INFO 异常:None conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:44 INFO 用例耗时:0.10466459999999955 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:44 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:44 INFO -----------------开始执行测试用例:[{'提取评价的书籍ID': {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}}, {'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': '{{id_1}}', 'commentContent': 'hami的接口自动化'}}}, {'JSON断言-等于-响应MSG': {'关键字': 'assert_json_comparators', 'VALUE': '$..msg', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'JSON断言-等于-CODE': {'关键字': 'assert_json_comparators', 'VALUE': '$..code', 'EXPECTED': '200', 'OP_STR': '=='}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:44 INFO 测试用例名称:我的书评-发布正常的书评(优化-直接Josn断言),开始执行步骤0:提取评价的书籍ID - {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:44 INFO -------------------测试用例名称:我的书评-发布正常的书评(优化-直接Josn断言)执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:44 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G3--P11] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:44 INFO 测试结果:failed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:44 INFO 故障表示:self = <apirun.core.ApiTestRunner.TestRunner object at 0x00000215ADD91BB0>
+caseinfo = {'_case_name': '我的书评-发布正常的书评(优化-直接Josn断言)', 'desc': '我的书评-发布正常的书评(优化-直接Josn断言)', 'featureName': '我的书评', 'process': 'G3--P', ...}
+
+    def test_case_execute(self, caseinfo):
+        casename = caseinfo["_case_name"]
+        # TODO 2-1 : 调用动态生成标题的方法
+        dynamicTitle(caseinfo)
+    
+        # TODO 2-2: 基于我们步骤一步步进行执行
+        try:
+            # 实例化关键字对象
+            keywords = KeyWords()
+    
+            # 获取当前用例变量,方便后续的渲染
+            local_context = caseinfo.get("context",{})
+            context = copy.deepcopy(g_context().show_dict())
+            context.update(local_context)
+    
+            steps = caseinfo.get("steps", None)
+            logger.info(f"-----------------开始执行测试用例:{steps}-------------")
+            for index,step in enumerate(steps):
+                #  提示信息
+                step_name = list(step.keys())[0]
+                step_value = list(step.values())[0]
+                # TODO : 每一个步骤进行变量的渲染
+                context = copy.deepcopy(g_context().show_dict())
+                context.update(local_context)
+                step_value = eval(refresh(step_value, context))
+                logger.info(f"测试用例名称:{casename},开始执行步骤{index}:{step_name} - {step_value}")
+                # 基于每个步骤的关键字,找到对应的方法,然后把参数给它
+                #  通过【反射】的方式去找到对应的方法
+                with allure.step(step_name):
+                    key = step_value["关键字"]  # 具体的方法名, 在 keywords 里面找到这个方法
+                    try:
+                        key_func = keywords.__getattribute__(key)  # 从keywords获取到对应方法
+                    except AttributeError as e:
+                        logger.error(f"测试用例名称:{casename},没有这个关键字方法", e)
+>                   key_func(**step_value)  # 调用方法
+
+core\ApiTestRunner.py:51: 
+_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+extend\keywords.py:183: in ex_mysqlData
+    logger.info("数据库查询结果:", rs)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1446: in info
+    self._log(INFO, msg, args, **kwargs)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1589: in _log
+    self.handle(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1599: in handle
+    self.callHandlers(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1661: in callHandlers
+    hdlr.handle(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:952: in handle
+    self.emit(record)
+..\myenv\lib\site-packages\_pytest\logging.py:380: in emit
+    super().emit(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1091: in emit
+    self.handleError(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1083: in emit
+    msg = self.format(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:927: in format
+    return fmt.format(record)
+..\myenv\lib\site-packages\_pytest\logging.py:140: in format
+    return super().format(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:663: in format
+    record.message = record.getMessage()
+_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+
+self = <LogRecord: testlog, 20, D:\001_zzh\eng\api-engine\apirun\extend\keywords.py, 183, "数据库查询结果:">
+
+    def getMessage(self):
+        """
+        Return the message for this LogRecord.
+    
+        Return the message for this LogRecord after merging any user-supplied
+        arguments with the message.
+        """
+        msg = str(self.msg)
+        if self.args:
+>           msg = msg % self.args
+E           TypeError: not all arguments converted during string formatting
+
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:367: TypeError conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:44 INFO 异常:<ExceptionInfo TypeError('not all arguments converted during string formatting') tblen=43> conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:44 INFO 用例耗时:0.21585119999999947 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:44 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:44 INFO -----------------开始执行测试用例:[{'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/user/login', 'PARAMS': None, 'HEADERS': None, 'DATA': {'username': '{{username}}', 'password': '{{password}}'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'通过JSONPATH提取数据-TOKEN': {'关键字': 'ex_jsonData', 'EXVALUE': '$..token', 'INDEX': None, 'VARNAME': 'token'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:44 INFO 测试用例名称:能够正确登录用例,开始执行步骤0:发送Post请求 - {'关键字': 'request_post_form_urlencoded', 'URL': 'http://120.25.127.201:18001//user/login', 'PARAMS': None, 'HEADERS': None, 'DATA': {'username': '15096268001', 'password': '123456'}} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:45 INFO 测试用例名称:能够正确登录用例,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:45 INFO 测试用例名称:能够正确登录用例,开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:45 INFO 测试用例名称:能够正确登录用例,开始执行步骤3:通过JSONPATH提取数据-TOKEN - {'关键字': 'ex_jsonData', 'EXVALUE': '$..token', 'INDEX': None, 'VARNAME': 'token'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:45 INFO 测试用例名称:能够正确登录用例,开始执行步骤4:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:45 INFO 测试用例名称:能够正确登录用例,开始执行步骤5:断言-等于-CODE - {'关键字': 'assert_text_comparators', 'VALUE': '200', 'EXPECTED': '200', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:45 INFO -------------------测试用例名称:能够正确登录用例执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:45 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G2--P0] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:45 INFO 测试结果:passed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:45 INFO 故障表示:None conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:45 INFO 异常:None conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:45 INFO 用例耗时:0.08543449999999986 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:45 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:45 INFO -----------------开始执行测试用例:[{'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/user/login', 'PARAMS': None, 'HEADERS': None, 'DATA': {'username': '15096268001', 'password': '1234562'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': '手机号或密码错误!', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '1004', 'OP_STR': '=='}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:45 INFO 测试用例名称:登录失败-手机号或密码错误用例,开始执行步骤0:发送Post请求 - {'关键字': 'request_post_form_urlencoded', 'URL': 'http://120.25.127.201:18001//user/login', 'PARAMS': None, 'HEADERS': None, 'DATA': {'username': '15096268001', 'password': '1234562'}} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:45 INFO 测试用例名称:登录失败-手机号或密码错误用例,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:45 INFO 测试用例名称:登录失败-手机号或密码错误用例,开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:45 INFO 测试用例名称:登录失败-手机号或密码错误用例,开始执行步骤3:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': '手机号或密码错误!', 'EXPECTED': '手机号或密码错误!', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:45 INFO 测试用例名称:登录失败-手机号或密码错误用例,开始执行步骤4:断言-等于-CODE - {'关键字': 'assert_text_comparators', 'VALUE': '1004', 'EXPECTED': '1004', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:45 INFO -------------------测试用例名称:登录失败-手机号或密码错误用例执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:45 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G2--P1] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:45 INFO 测试结果:passed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:45 INFO 故障表示:None conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:45 INFO 异常:None conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:45 INFO 用例耗时:0.09628380000000014 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:45 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:45 INFO -----------------开始执行测试用例:[{'发送Get请求': {'关键字': 'request_get', 'URL': '{{URL}}/user/userInfo', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..username', 'INDEX': 0, 'VARNAME': 'msg_username'}}, {'断言-等于-响应USERNAME': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_username}}', 'EXPECTED': '{{username}}', 'OP_STR': '=='}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:45 INFO 测试用例名称:查看用户信息,开始执行步骤0:发送Get请求 - {'关键字': 'request_get', 'URL': 'http://120.25.127.201:18001//user/userInfo', 'PARAMS': None, 'HEADERS': {'Authorization': 'eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE3MzEzMjc5NDUsInN1YiI6IntcImlkXCI6MTc5MTA1NjM4NjYzOTg3MjAwMCxcInVzZXJuYW1lXCI6XCIxNTA5NjI2ODAwMVwiLFwibmlja05hbWVcIjpcIuS4gOS6jOS4iVwifSIsImNyZWF0ZWQiOjE3MzA3MjMxNDUwMDh9.p8c93ppTDwsZlGT4rDNGu0okJNH4eq0hioc7SgqQ3XxvUHzIINMm6L6eRqFxjY_Bbi0EP4KMSBgDFZUKiDNF5A'}} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:45 INFO 测试用例名称:查看用户信息,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:45 INFO 测试用例名称:查看用户信息,开始执行步骤2:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:45 INFO 测试用例名称:查看用户信息,开始执行步骤3:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..username', 'INDEX': 0, 'VARNAME': 'msg_username'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:45 INFO 测试用例名称:查看用户信息,开始执行步骤4:断言-等于-响应USERNAME - {'关键字': 'assert_text_comparators', 'VALUE': '15096268001', 'EXPECTED': '15096268001', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:45 INFO -------------------测试用例名称:查看用户信息执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:45 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G2--P2] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:45 INFO 测试结果:passed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:45 INFO 故障表示:None conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:45 INFO 异常:None conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:45 INFO 用例耗时:0.08434860000000022 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:45 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:45 INFO -----------------开始执行测试用例:[{'发送Post请求-上传图片': {'关键字': 'request_post_form_data', 'URL': '{{URL}}/file/picUpload', 'FILES': '{"file":open("./files/20240725223321.png","rb")}', 'PARAMS': None, 'HEADERS': None}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}, {'通过JSONPATH提取数据-图片路径': {'关键字': 'ex_jsonData', 'EXVALUE': '$..data', 'INDEX': 0, 'VARNAME': 'msg_data'}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:45 INFO 测试用例名称:修改头像-上传头像,开始执行步骤0:发送Post请求-上传图片 - {'关键字': 'request_post_form_data', 'URL': 'http://120.25.127.201:18001//file/picUpload', 'FILES': '{"file":open("./files/20240725223321.png","rb")}', 'PARAMS': None, 'HEADERS': None} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:45 INFO 测试用例名称:修改头像-上传头像,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:45 INFO 测试用例名称:修改头像-上传头像,开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:45 INFO 测试用例名称:修改头像-上传头像,开始执行步骤3:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:45 INFO 测试用例名称:修改头像-上传头像,开始执行步骤4:断言-等于-CODE - {'关键字': 'assert_text_comparators', 'VALUE': '200', 'EXPECTED': '200', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:45 INFO 测试用例名称:修改头像-上传头像,开始执行步骤5:通过JSONPATH提取数据-图片路径 - {'关键字': 'ex_jsonData', 'EXVALUE': '$..data', 'INDEX': 0, 'VARNAME': 'msg_data'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:45 INFO -------------------测试用例名称:修改头像-上传头像执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:45 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G2--P3] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:45 INFO 测试结果:passed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:45 INFO 故障表示:None conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:45 INFO 异常:None conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:45 INFO 用例耗时:0.08542759999999916 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:45 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:45 INFO -----------------开始执行测试用例:[{'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/user/updateUserInfo', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'userPhoto': '{{msg_data}}'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:45 INFO 测试用例名称:修改头像-确定修改头像,开始执行步骤0:发送Post请求 - {'关键字': 'request_post_form_urlencoded', 'URL': 'http://120.25.127.201:18001//user/updateUserInfo', 'PARAMS': None, 'HEADERS': {'Authorization': 'eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE3MzEzMjc5NDUsInN1YiI6IntcImlkXCI6MTc5MTA1NjM4NjYzOTg3MjAwMCxcInVzZXJuYW1lXCI6XCIxNTA5NjI2ODAwMVwiLFwibmlja05hbWVcIjpcIuS4gOS6jOS4iVwifSIsImNyZWF0ZWQiOjE3MzA3MjMxNDUwMDh9.p8c93ppTDwsZlGT4rDNGu0okJNH4eq0hioc7SgqQ3XxvUHzIINMm6L6eRqFxjY_Bbi0EP4KMSBgDFZUKiDNF5A'}, 'DATA': {'userPhoto': '/localPic/2024/11/04/23464fa16c494ce7a9e26777e98ccf00.png'}} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:45 INFO 测试用例名称:修改头像-确定修改头像,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:45 INFO 测试用例名称:修改头像-确定修改头像,开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:45 INFO 测试用例名称:修改头像-确定修改头像,开始执行步骤3:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:45 INFO 测试用例名称:修改头像-确定修改头像,开始执行步骤4:断言-等于-CODE - {'关键字': 'assert_text_comparators', 'VALUE': '200', 'EXPECTED': '200', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:45 INFO -------------------测试用例名称:修改头像-确定修改头像执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:45 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G2--P4] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:45 INFO 测试结果:passed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:45 INFO 故障表示:None conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:45 INFO 异常:None conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:45 INFO 用例耗时:0.09263550000000009 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:45 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:45 INFO -----------------开始执行测试用例:[{'提取评价的书籍ID': {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}}, {'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': '{{id_1}}', 'commentContent': 'hami的接口自动化'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:45 INFO 测试用例名称:我的书评-发布正常的书评(可能会失败),开始执行步骤0:提取评价的书籍ID - {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:45 INFO -------------------测试用例名称:我的书评-发布正常的书评(可能会失败)执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:45 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G2--P5] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:45 INFO 测试结果:failed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:45 INFO 故障表示:self = <apirun.core.ApiTestRunner.TestRunner object at 0x00000215ADD91FD0>
+caseinfo = {'_case_name': '我的书评-发布正常的书评(可能会失败)', 'desc': '我的书评-发布正常的书评(可能会失败)', 'featureName': '我的书评', 'process': 'G2--P', ...}
+
+    def test_case_execute(self, caseinfo):
+        casename = caseinfo["_case_name"]
+        # TODO 2-1 : 调用动态生成标题的方法
+        dynamicTitle(caseinfo)
+    
+        # TODO 2-2: 基于我们步骤一步步进行执行
+        try:
+            # 实例化关键字对象
+            keywords = KeyWords()
+    
+            # 获取当前用例变量,方便后续的渲染
+            local_context = caseinfo.get("context",{})
+            context = copy.deepcopy(g_context().show_dict())
+            context.update(local_context)
+    
+            steps = caseinfo.get("steps", None)
+            logger.info(f"-----------------开始执行测试用例:{steps}-------------")
+            for index,step in enumerate(steps):
+                #  提示信息
+                step_name = list(step.keys())[0]
+                step_value = list(step.values())[0]
+                # TODO : 每一个步骤进行变量的渲染
+                context = copy.deepcopy(g_context().show_dict())
+                context.update(local_context)
+                step_value = eval(refresh(step_value, context))
+                logger.info(f"测试用例名称:{casename},开始执行步骤{index}:{step_name} - {step_value}")
+                # 基于每个步骤的关键字,找到对应的方法,然后把参数给它
+                #  通过【反射】的方式去找到对应的方法
+                with allure.step(step_name):
+                    key = step_value["关键字"]  # 具体的方法名, 在 keywords 里面找到这个方法
+                    try:
+                        key_func = keywords.__getattribute__(key)  # 从keywords获取到对应方法
+                    except AttributeError as e:
+                        logger.error(f"测试用例名称:{casename},没有这个关键字方法", e)
+>                   key_func(**step_value)  # 调用方法
+
+core\ApiTestRunner.py:51: 
+_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+extend\keywords.py:183: in ex_mysqlData
+    logger.info("数据库查询结果:", rs)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1446: in info
+    self._log(INFO, msg, args, **kwargs)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1589: in _log
+    self.handle(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1599: in handle
+    self.callHandlers(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1661: in callHandlers
+    hdlr.handle(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:952: in handle
+    self.emit(record)
+..\myenv\lib\site-packages\_pytest\logging.py:380: in emit
+    super().emit(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1091: in emit
+    self.handleError(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1083: in emit
+    msg = self.format(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:927: in format
+    return fmt.format(record)
+..\myenv\lib\site-packages\_pytest\logging.py:140: in format
+    return super().format(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:663: in format
+    record.message = record.getMessage()
+_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+
+self = <LogRecord: testlog, 20, D:\001_zzh\eng\api-engine\apirun\extend\keywords.py, 183, "数据库查询结果:">
+
+    def getMessage(self):
+        """
+        Return the message for this LogRecord.
+    
+        Return the message for this LogRecord after merging any user-supplied
+        arguments with the message.
+        """
+        msg = str(self.msg)
+        if self.args:
+>           msg = msg % self.args
+E           TypeError: not all arguments converted during string formatting
+
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:367: TypeError conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:45 INFO 异常:<ExceptionInfo TypeError('not all arguments converted during string formatting') tblen=43> conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:45 INFO 用例耗时:0.21499640000000042 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:45 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:45 INFO -----------------开始执行测试用例:[{'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': '', 'commentContent': 'hami的接口自动化'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': '书籍ID不存在', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:45 INFO 测试用例名称:我的书评-发布不存在的书籍ID(BUG),开始执行步骤0:发送Post请求 - {'关键字': 'request_post_form_urlencoded', 'URL': 'http://120.25.127.201:18001//book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': 'eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE3MzEzMjc5NDUsInN1YiI6IntcImlkXCI6MTc5MTA1NjM4NjYzOTg3MjAwMCxcInVzZXJuYW1lXCI6XCIxNTA5NjI2ODAwMVwiLFwibmlja05hbWVcIjpcIuS4gOS6jOS4iVwifSIsImNyZWF0ZWQiOjE3MzA3MjMxNDUwMDh9.p8c93ppTDwsZlGT4rDNGu0okJNH4eq0hioc7SgqQ3XxvUHzIINMm6L6eRqFxjY_Bbi0EP4KMSBgDFZUKiDNF5A'}, 'DATA': {'bookId': '', 'commentContent': 'hami的接口自动化'}} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:45 INFO 测试用例名称:我的书评-发布不存在的书籍ID(BUG),开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:45 INFO 测试用例名称:我的书评-发布不存在的书籍ID(BUG),开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:45 INFO 测试用例名称:我的书评-发布不存在的书籍ID(BUG),开始执行步骤3:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': '书籍ID不存在', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:45 INFO -------------------测试用例名称:我的书评-发布不存在的书籍ID(BUG)执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:45 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G2--P6] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:45 INFO 测试结果:failed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:45 INFO 故障表示:self = <apirun.core.ApiTestRunner.TestRunner object at 0x00000215ADC8DFA0>
+caseinfo = {'_case_name': '我的书评-发布不存在的书籍ID(BUG)', 'desc': '我的书评-发布不存在的书籍ID(BUG)', 'featureName': '我的书评', 'process': 'G2--P', ...}
+
+    def test_case_execute(self, caseinfo):
+        casename = caseinfo["_case_name"]
+        # TODO 2-1 : 调用动态生成标题的方法
+        dynamicTitle(caseinfo)
+    
+        # TODO 2-2: 基于我们步骤一步步进行执行
+        try:
+            # 实例化关键字对象
+            keywords = KeyWords()
+    
+            # 获取当前用例变量,方便后续的渲染
+            local_context = caseinfo.get("context",{})
+            context = copy.deepcopy(g_context().show_dict())
+            context.update(local_context)
+    
+            steps = caseinfo.get("steps", None)
+            logger.info(f"-----------------开始执行测试用例:{steps}-------------")
+            for index,step in enumerate(steps):
+                #  提示信息
+                step_name = list(step.keys())[0]
+                step_value = list(step.values())[0]
+                # TODO : 每一个步骤进行变量的渲染
+                context = copy.deepcopy(g_context().show_dict())
+                context.update(local_context)
+                step_value = eval(refresh(step_value, context))
+                logger.info(f"测试用例名称:{casename},开始执行步骤{index}:{step_name} - {step_value}")
+                # 基于每个步骤的关键字,找到对应的方法,然后把参数给它
+                #  通过【反射】的方式去找到对应的方法
+                with allure.step(step_name):
+                    key = step_value["关键字"]  # 具体的方法名, 在 keywords 里面找到这个方法
+                    try:
+                        key_func = keywords.__getattribute__(key)  # 从keywords获取到对应方法
+                    except AttributeError as e:
+                        logger.error(f"测试用例名称:{casename},没有这个关键字方法", e)
+>                   key_func(**step_value)  # 调用方法
+
+core\ApiTestRunner.py:51: 
+_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+
+self = <apirun.extend.keywords.KeyWords object at 0x00000215ADFEA310>
+kwargs = {'EXPECTED': '书籍ID不存在', 'OP_STR': '==', 'VALUE': 'SUCCESS', '关键字': 'assert_text_comparators'}
+comparators = {'!=': <function KeyWords.assert_text_comparators.<locals>.<lambda> at 0x00000215AE0B3430>, '<': <function KeyWords.as...at 0x00000215AE0B33A0>, '==': <function KeyWords.assert_text_comparators.<locals>.<lambda> at 0x00000215AE0B3700>, ...}
+message = None
+
+    @allure.step("参数数据:断言当前文本内容")
+    def assert_text_comparators(self, **kwargs):
+        """
+        封装断言以进行不同的比较操作。
+    
+        参数:
+        value (Any): 要比较的值。
+        expected (Any): 预期的值。
+        op_str (str): 操作符的字符串表示(如 '>', '<', '==' 等)。
+        message (str, optional): 自定义的错误消息。
+    
+        返回:
+        None: 如果断言成功,则不返回任何内容。
+    
+        引发:
+        AssertionError: 如果断言失败。
+        """
+        comparators = {
+            '>': lambda a, b: a > b,
+            '<': lambda a, b: a < b,
+            '==': lambda a, b: a == b,
+            '>=': lambda a, b: a >= b,
+            '<=': lambda a, b: a <= b,
+            '!=': lambda a, b: a != b,
+        }
+    
+        message = kwargs.get("MESSAGE", None)
+    
+        if kwargs["OP_STR"] not in comparators:
+            raise ValueError(f"没有该操作方式: {kwargs['OP_STR']}")
+    
+        if not comparators[kwargs['OP_STR']](kwargs['VALUE'], kwargs["EXPECTED"]):
+            if message:
+                raise AssertionError(message)
+            else:
+>               raise AssertionError(f"{kwargs['VALUE']} {kwargs['OP_STR']} {kwargs['EXPECTED']} 失败")
+E               AssertionError: SUCCESS == 书籍ID不存在 失败
+
+extend\keywords.py:228: AssertionError conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:45 INFO 异常:<ExceptionInfo AssertionError('SUCCESS == 书籍ID不存在 失败') tblen=31> conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:45 INFO 用例耗时:0.11337829999999904 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:45 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:45 INFO -----------------开始执行测试用例:[{'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': 118, 'commentContent': 'hami的接口自动化'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': '已评价过该书籍!', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '3001', 'OP_STR': '=='}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:45 INFO 测试用例名称:我的书评-发布已评价的数据,开始执行步骤0:发送Post请求 - {'关键字': 'request_post_form_urlencoded', 'URL': 'http://120.25.127.201:18001//book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': 'eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE3MzEzMjc5NDUsInN1YiI6IntcImlkXCI6MTc5MTA1NjM4NjYzOTg3MjAwMCxcInVzZXJuYW1lXCI6XCIxNTA5NjI2ODAwMVwiLFwibmlja05hbWVcIjpcIuS4gOS6jOS4iVwifSIsImNyZWF0ZWQiOjE3MzA3MjMxNDUwMDh9.p8c93ppTDwsZlGT4rDNGu0okJNH4eq0hioc7SgqQ3XxvUHzIINMm6L6eRqFxjY_Bbi0EP4KMSBgDFZUKiDNF5A'}, 'DATA': {'bookId': 118, 'commentContent': 'hami的接口自动化'}} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:45 INFO 测试用例名称:我的书评-发布已评价的数据,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:45 INFO 测试用例名称:我的书评-发布已评价的数据,开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:45 INFO 测试用例名称:我的书评-发布已评价的数据,开始执行步骤3:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': '已评价过该书籍!', 'EXPECTED': '已评价过该书籍!', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:45 INFO 测试用例名称:我的书评-发布已评价的数据,开始执行步骤4:断言-等于-CODE - {'关键字': 'assert_text_comparators', 'VALUE': '3001', 'EXPECTED': '3001', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:45 INFO -------------------测试用例名称:我的书评-发布已评价的数据执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:45 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G2--P7] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:45 INFO 测试结果:passed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:45 INFO 故障表示:None conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:45 INFO 异常:None conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:45 INFO 用例耗时:0.09990250000000067 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:45 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:45 INFO -----------------开始执行测试用例:[{'提取评价的书籍ID': {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}}, {'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': '{{id_1}}', 'commentContent': 'ham'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:45 INFO 测试用例名称:我的书评-发布不满五个字的书评(BUG),开始执行步骤0:提取评价的书籍ID - {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:46 INFO -------------------测试用例名称:我的书评-发布不满五个字的书评(BUG)执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:46 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G2--P8] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:46 INFO 测试结果:failed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:46 INFO 故障表示:self = <apirun.core.ApiTestRunner.TestRunner object at 0x00000215ADC4B100>
+caseinfo = {'_case_name': '我的书评-发布不满五个字的书评(BUG)', 'desc': '我的书评-发布不满五个字的书评(BUG)', 'featureName': '我的书评', 'process': 'G2--P', ...}
+
+    def test_case_execute(self, caseinfo):
+        casename = caseinfo["_case_name"]
+        # TODO 2-1 : 调用动态生成标题的方法
+        dynamicTitle(caseinfo)
+    
+        # TODO 2-2: 基于我们步骤一步步进行执行
+        try:
+            # 实例化关键字对象
+            keywords = KeyWords()
+    
+            # 获取当前用例变量,方便后续的渲染
+            local_context = caseinfo.get("context",{})
+            context = copy.deepcopy(g_context().show_dict())
+            context.update(local_context)
+    
+            steps = caseinfo.get("steps", None)
+            logger.info(f"-----------------开始执行测试用例:{steps}-------------")
+            for index,step in enumerate(steps):
+                #  提示信息
+                step_name = list(step.keys())[0]
+                step_value = list(step.values())[0]
+                # TODO : 每一个步骤进行变量的渲染
+                context = copy.deepcopy(g_context().show_dict())
+                context.update(local_context)
+                step_value = eval(refresh(step_value, context))
+                logger.info(f"测试用例名称:{casename},开始执行步骤{index}:{step_name} - {step_value}")
+                # 基于每个步骤的关键字,找到对应的方法,然后把参数给它
+                #  通过【反射】的方式去找到对应的方法
+                with allure.step(step_name):
+                    key = step_value["关键字"]  # 具体的方法名, 在 keywords 里面找到这个方法
+                    try:
+                        key_func = keywords.__getattribute__(key)  # 从keywords获取到对应方法
+                    except AttributeError as e:
+                        logger.error(f"测试用例名称:{casename},没有这个关键字方法", e)
+>                   key_func(**step_value)  # 调用方法
+
+core\ApiTestRunner.py:51: 
+_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+extend\keywords.py:183: in ex_mysqlData
+    logger.info("数据库查询结果:", rs)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1446: in info
+    self._log(INFO, msg, args, **kwargs)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1589: in _log
+    self.handle(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1599: in handle
+    self.callHandlers(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1661: in callHandlers
+    hdlr.handle(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:952: in handle
+    self.emit(record)
+..\myenv\lib\site-packages\_pytest\logging.py:380: in emit
+    super().emit(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1091: in emit
+    self.handleError(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1083: in emit
+    msg = self.format(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:927: in format
+    return fmt.format(record)
+..\myenv\lib\site-packages\_pytest\logging.py:140: in format
+    return super().format(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:663: in format
+    record.message = record.getMessage()
+_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+
+self = <LogRecord: testlog, 20, D:\001_zzh\eng\api-engine\apirun\extend\keywords.py, 183, "数据库查询结果:">
+
+    def getMessage(self):
+        """
+        Return the message for this LogRecord.
+    
+        Return the message for this LogRecord after merging any user-supplied
+        arguments with the message.
+        """
+        msg = str(self.msg)
+        if self.args:
+>           msg = msg % self.args
+E           TypeError: not all arguments converted during string formatting
+
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:367: TypeError conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:46 INFO 异常:<ExceptionInfo TypeError('not all arguments converted during string formatting') tblen=43> conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:46 INFO 用例耗时:0.1959156999999987 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:46 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:46 INFO -----------------开始执行测试用例:[{'提取评价的书籍ID': {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}}, {'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': '{{id_1}}', 'commentContent': 'hamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhahamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamham'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': '评价不能超过200字符!', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:46 INFO 测试用例名称:我的书评-发布超过200个字的书评,开始执行步骤0:提取评价的书籍ID - {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:46 INFO -------------------测试用例名称:我的书评-发布超过200个字的书评执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:46 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G2--P9] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:46 INFO 测试结果:failed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:46 INFO 故障表示:self = <apirun.core.ApiTestRunner.TestRunner object at 0x00000215ADCB21F0>
+caseinfo = {'_case_name': '我的书评-发布超过200个字的书评', 'desc': '我的书评-发布超过200个字的书评', 'featureName': '我的书评', 'process': 'G2--P', ...}
+
+    def test_case_execute(self, caseinfo):
+        casename = caseinfo["_case_name"]
+        # TODO 2-1 : 调用动态生成标题的方法
+        dynamicTitle(caseinfo)
+    
+        # TODO 2-2: 基于我们步骤一步步进行执行
+        try:
+            # 实例化关键字对象
+            keywords = KeyWords()
+    
+            # 获取当前用例变量,方便后续的渲染
+            local_context = caseinfo.get("context",{})
+            context = copy.deepcopy(g_context().show_dict())
+            context.update(local_context)
+    
+            steps = caseinfo.get("steps", None)
+            logger.info(f"-----------------开始执行测试用例:{steps}-------------")
+            for index,step in enumerate(steps):
+                #  提示信息
+                step_name = list(step.keys())[0]
+                step_value = list(step.values())[0]
+                # TODO : 每一个步骤进行变量的渲染
+                context = copy.deepcopy(g_context().show_dict())
+                context.update(local_context)
+                step_value = eval(refresh(step_value, context))
+                logger.info(f"测试用例名称:{casename},开始执行步骤{index}:{step_name} - {step_value}")
+                # 基于每个步骤的关键字,找到对应的方法,然后把参数给它
+                #  通过【反射】的方式去找到对应的方法
+                with allure.step(step_name):
+                    key = step_value["关键字"]  # 具体的方法名, 在 keywords 里面找到这个方法
+                    try:
+                        key_func = keywords.__getattribute__(key)  # 从keywords获取到对应方法
+                    except AttributeError as e:
+                        logger.error(f"测试用例名称:{casename},没有这个关键字方法", e)
+>                   key_func(**step_value)  # 调用方法
+
+core\ApiTestRunner.py:51: 
+_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+extend\keywords.py:183: in ex_mysqlData
+    logger.info("数据库查询结果:", rs)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1446: in info
+    self._log(INFO, msg, args, **kwargs)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1589: in _log
+    self.handle(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1599: in handle
+    self.callHandlers(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1661: in callHandlers
+    hdlr.handle(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:952: in handle
+    self.emit(record)
+..\myenv\lib\site-packages\_pytest\logging.py:380: in emit
+    super().emit(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1091: in emit
+    self.handleError(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1083: in emit
+    msg = self.format(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:927: in format
+    return fmt.format(record)
+..\myenv\lib\site-packages\_pytest\logging.py:140: in format
+    return super().format(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:663: in format
+    record.message = record.getMessage()
+_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+
+self = <LogRecord: testlog, 20, D:\001_zzh\eng\api-engine\apirun\extend\keywords.py, 183, "数据库查询结果:">
+
+    def getMessage(self):
+        """
+        Return the message for this LogRecord.
+    
+        Return the message for this LogRecord after merging any user-supplied
+        arguments with the message.
+        """
+        msg = str(self.msg)
+        if self.args:
+>           msg = msg % self.args
+E           TypeError: not all arguments converted during string formatting
+
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:367: TypeError conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:46 INFO 异常:<ExceptionInfo TypeError('not all arguments converted during string formatting') tblen=43> conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:46 INFO 用例耗时:0.20920360000000038 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:46 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:46 INFO -----------------开始执行测试用例:[{'发送Get请求': {'关键字': 'request_get', 'URL': '{{URL}}/book/listClickRank', 'PARAMS': None, 'HEADERS': None}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': None, 'VARNAME': 'msg_success'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:46 INFO 测试用例名称:点击榜单能够显示对应的数据,开始执行步骤0:发送Get请求 - {'关键字': 'request_get', 'URL': 'http://120.25.127.201:18001//book/listClickRank', 'PARAMS': None, 'HEADERS': None} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:46 INFO 测试用例名称:点击榜单能够显示对应的数据,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': None, 'VARNAME': 'msg_success'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:46 INFO 测试用例名称:点击榜单能够显示对应的数据,开始执行步骤2:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:46 INFO -------------------测试用例名称:点击榜单能够显示对应的数据执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:46 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G2--P10] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:46 INFO 测试结果:passed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:46 INFO 故障表示:None conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:46 INFO 异常:None conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:46 INFO 用例耗时:0.11341100000000104 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:46 INFO ************************************** conftest.py pytest_runtest_makereport 73
+2024-11-04 20:25:46 INFO -----------------开始执行测试用例:[{'提取评价的书籍ID': {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}}, {'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': '{{id_1}}', 'commentContent': 'hami的接口自动化'}}}, {'JSON断言-等于-响应MSG': {'关键字': 'assert_json_comparators', 'VALUE': '$..msg', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'JSON断言-等于-CODE': {'关键字': 'assert_json_comparators', 'VALUE': '$..code', 'EXPECTED': '200', 'OP_STR': '=='}}]------------- ApiTestRunner.py test_case_execute 33
+2024-11-04 20:25:46 INFO 测试用例名称:我的书评-发布正常的书评(优化-直接Josn断言),开始执行步骤0:提取评价的书籍ID - {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'} ApiTestRunner.py test_case_execute 42
+2024-11-04 20:25:46 INFO -------------------测试用例名称:我的书评-发布正常的书评(优化-直接Josn断言)执行结束---------------------- ApiTestRunner.py test_case_execute 53
+2024-11-04 20:25:47 INFO 用例ID:core/ApiTestRunner.py::TestRunner::test_case_execute[G2--P11] conftest.py pytest_runtest_makereport 68
+2024-11-04 20:25:47 INFO 测试结果:failed conftest.py pytest_runtest_makereport 69
+2024-11-04 20:25:47 INFO 故障表示:self = <apirun.core.ApiTestRunner.TestRunner object at 0x00000215ADCB22E0>
+caseinfo = {'_case_name': '我的书评-发布正常的书评(优化-直接Josn断言)', 'desc': '我的书评-发布正常的书评(优化-直接Josn断言)', 'featureName': '我的书评', 'process': 'G2--P', ...}
+
+    def test_case_execute(self, caseinfo):
+        casename = caseinfo["_case_name"]
+        # TODO 2-1 : 调用动态生成标题的方法
+        dynamicTitle(caseinfo)
+    
+        # TODO 2-2: 基于我们步骤一步步进行执行
+        try:
+            # 实例化关键字对象
+            keywords = KeyWords()
+    
+            # 获取当前用例变量,方便后续的渲染
+            local_context = caseinfo.get("context",{})
+            context = copy.deepcopy(g_context().show_dict())
+            context.update(local_context)
+    
+            steps = caseinfo.get("steps", None)
+            logger.info(f"-----------------开始执行测试用例:{steps}-------------")
+            for index,step in enumerate(steps):
+                #  提示信息
+                step_name = list(step.keys())[0]
+                step_value = list(step.values())[0]
+                # TODO : 每一个步骤进行变量的渲染
+                context = copy.deepcopy(g_context().show_dict())
+                context.update(local_context)
+                step_value = eval(refresh(step_value, context))
+                logger.info(f"测试用例名称:{casename},开始执行步骤{index}:{step_name} - {step_value}")
+                # 基于每个步骤的关键字,找到对应的方法,然后把参数给它
+                #  通过【反射】的方式去找到对应的方法
+                with allure.step(step_name):
+                    key = step_value["关键字"]  # 具体的方法名, 在 keywords 里面找到这个方法
+                    try:
+                        key_func = keywords.__getattribute__(key)  # 从keywords获取到对应方法
+                    except AttributeError as e:
+                        logger.error(f"测试用例名称:{casename},没有这个关键字方法", e)
+>                   key_func(**step_value)  # 调用方法
+
+core\ApiTestRunner.py:51: 
+_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+extend\keywords.py:183: in ex_mysqlData
+    logger.info("数据库查询结果:", rs)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1446: in info
+    self._log(INFO, msg, args, **kwargs)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1589: in _log
+    self.handle(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1599: in handle
+    self.callHandlers(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1661: in callHandlers
+    hdlr.handle(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:952: in handle
+    self.emit(record)
+..\myenv\lib\site-packages\_pytest\logging.py:380: in emit
+    super().emit(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1091: in emit
+    self.handleError(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:1083: in emit
+    msg = self.format(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:927: in format
+    return fmt.format(record)
+..\myenv\lib\site-packages\_pytest\logging.py:140: in format
+    return super().format(record)
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:663: in format
+    record.message = record.getMessage()
+_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+
+self = <LogRecord: testlog, 20, D:\001_zzh\eng\api-engine\apirun\extend\keywords.py, 183, "数据库查询结果:">
+
+    def getMessage(self):
+        """
+        Return the message for this LogRecord.
+    
+        Return the message for this LogRecord after merging any user-supplied
+        arguments with the message.
+        """
+        msg = str(self.msg)
+        if self.args:
+>           msg = msg % self.args
+E           TypeError: not all arguments converted during string formatting
+
+C:\Users\zhuzhenghui\AppData\Local\Programs\Python\Python39\lib\logging\__init__.py:367: TypeError conftest.py pytest_runtest_makereport 70
+2024-11-04 20:25:47 INFO 异常:<ExceptionInfo TypeError('not all arguments converted during string formatting') tblen=43> conftest.py pytest_runtest_makereport 71
+2024-11-04 20:25:47 INFO 用例耗时:0.22291740000000004 conftest.py pytest_runtest_makereport 72
+2024-11-04 20:25:47 INFO ************************************** conftest.py pytest_runtest_makereport 73

+ 24 - 0
apirun/parse/CaseParser.py

@@ -0,0 +1,24 @@
+# -*- coding: utf-8 -*-
+import os.path
+from apirun.parse.YamlCaseParser import yaml_case_parser
+from apirun.parse.ExcelCaseParser import excel_case_parser
+
+
+def case_parser(case_type, case_dir):
+    """
+
+    :param case_type: 用例的类型:yaml、 excel
+    :param case_dir: 用例所在的文件夹
+    :return: 调用方法是什么返回的格式就是什么:返回 {"case_name":[], "cases_info":[]}
+    """
+
+    config_path = os.path.abspath(case_dir)
+
+    if case_type == "yaml":
+        return yaml_case_parser(config_path)
+    if case_type == "excel":
+        return excel_case_parser(config_path)
+
+    # 如果上面执行完毕,都不满足条件,则返回空
+    return {"case_name": [], "cases_info": []}
+

+ 169 - 0
apirun/parse/ExcelCaseParser.py

@@ -0,0 +1,169 @@
+# -*- coding: utf-8 -*-
+import ast
+import copy
+import json
+import os.path
+
+#  专门用例Excel参数化
+#  导入excel的包:pip install pandas
+# openpyxl是pandas用于读取.xlsx文件的引擎之一
+# pip install pandas openpyxl
+
+# 读取yaml的数据
+import yaml, os, uuid
+import pandas as pd
+from apirun.core.globalContext import g_context
+from apirun.Log.Log import logger
+
+
+def load_context_from_excel(folder_path):
+    """
+    :param folder_path: 文件路径
+    :return:
+    """
+    try:
+        excel_file_path = os.path.join(folder_path, "context.xlsx")  # 把2个文本进行拼接
+        # 读取excel
+        df = pd.read_excel(excel_file_path)
+        # 初始化一个变量进行存储
+        data = {
+            "_database": {}
+        }
+        for index, row in df.iterrows():
+            # 如果是变量我们就直接存在:变量名:value
+            if row["类型"] == "变量":
+                data[row["变量描述"]] = row["变量值"]
+            elif row["类型"] == "数据库":
+                db_name = row["变量描述"]
+                db_config = json.loads(row["变量值"])  # 变成字典格式
+                data["_database"][db_name] = db_config
+        if data: g_context().set_by_dict(data)  # 写入到全局变量
+    except Exception as e:
+        logger.error(f"装载excel文件错误: {str(e)}")
+        return False
+
+
+# 加载我们满足条件的文件及数据
+def load_excel_files(config_path):
+    """
+    返回满足条件的excel文件列表及数据
+    :param config_path: excel存放的路径
+    :return:
+    """
+
+    excel_caseInfos = []  # 存储所有的数据
+
+    suite_folder = os.path.join(config_path)
+    # 存放在该路径的全局变量进行写入
+    load_context_from_excel(suite_folder)
+    # 满足条件的列表
+    file_names = [(int(f.split("_")[0]), f) for f in os.listdir(suite_folder) if
+                  f.endswith(".xlsx") and f.split("_")[0].isdigit()]
+
+    # 排序,排序只保留文件名即可
+    file_names.sort()
+    file_names = [f[-1] for f in file_names]
+    # 读取我们维护的yaml数据,方便后面和值一一对应起来
+    current_dir = os.path.abspath(os.path.dirname(__file__))  # 获取当前文件的绝对路径
+    parent_dir = os.path.dirname(current_dir)  # 基于当前路径获取上一层路径
+    keywords_file_path = os.path.join(parent_dir, "extend/keywords.yaml")  # 进行拼接
+
+    keywords_info = {}
+    with open(keywords_file_path, "r", encoding="utf-8") as f:
+        keywords_info = yaml.full_load(f)  #
+
+    # 加载每个文件的数据给到yaml_caseInfos
+    for file_name in file_names:
+        file_path = os.path.join(suite_folder, file_name)
+
+        # TODO 1: 读取excel
+        lr =[]
+        for i in pd.ExcelFile(file_path).sheet_names: # 遍历excel表格的sheet页名称
+            if i != '关键字说明':
+                data = pd.read_excel(file_path, sheet_name=i) # 获取单个sheet页的全量数据
+                data = data.where(data.notnull(), None)  # 将非空值保留,空数据用None替换
+                data = data.to_dict(orient='records')  # 用一个大列表把没一行编成一个字典元素,存储起来
+                lr.extend(data)
+        # 初始化一个字典,用例存放某一条测试用例
+        current_test_case = None
+
+        for row in lr:
+            # 判断是否有测试标题:如果有的话,代表是我们第一个,直到遇到下一个标题,就从头开头
+            # TODO 1: # 检查当前行是否包含有效的测试用例标题,有则代表对应的起始位
+            if pd.notna(row["测试用例标题"]):
+                # 如果已经构建完毕那么需要当前加进去到对应的测试用例当中
+                if current_test_case is not None:
+                    excel_caseInfos.append(current_test_case)
+
+                # 初始化一个测试用例字典
+                current_test_case = {
+                    "process": row['进程类'],
+                    "desc": row['测试用例标题'],
+                    "featureName": row['一级模块'],
+                    "storyName": row['二级模块'],
+                    "steps": []
+                }
+
+            # TODO 2-1: 初始化步骤的值
+            steps = {
+                row["步骤描述"]: {
+                    "关键字": row["关键字"]
+                }
+            }
+            # TODO 2-2: 考虑步骤当中对应的每个参数。
+            parameter = []
+            for key, value in row.items():
+                if "参数_" in key:
+                    try:
+                        # 尝试将字符串转换为Python对象
+                        value = ast.literal_eval(value)
+                    except:
+                        pass
+                    parameter.append(value)
+
+            # TODO 2-3: 把对应的值和KEY一一对应起来,这样我们才能发送请求 -zip
+            dict_parameter = {k: v for k, v in zip(keywords_info[row["关键字"]], parameter)}
+            steps[row["步骤描述"]].update(dict_parameter)
+
+            # 步骤加到当前测试用例来
+            current_test_case["steps"].append(steps)
+
+        if current_test_case is not None:
+            excel_caseInfos.append(current_test_case)
+    return excel_caseInfos
+
+
+#  把yaml的格式处理成我们规定的格式
+def excel_case_parser(config_path):
+    """
+    返回指定条件的格式
+    :param config_path:  文件的路径
+    :return: {
+            "case_infos": case_infos,  #  所有的测试用例 []
+            "case_names": case_names   #  所有测试用例对应的标题 []
+            }
+    """
+    # TODO 0: 对应固定的格式
+    case_infos = []
+    case_names = []
+    case_process = []
+
+    # TODO 1: 调用对应的方法:拿到所有的用例数据
+    excel_caseInfos = load_excel_files(config_path)
+
+    # TODO 2: 统一处理成一样的格式 (后面excel一样的处理)
+    for caseinfo in excel_caseInfos:
+        caseinfo.update({"_case_name": caseinfo["desc"]})
+        case_infos.append(caseinfo)  # 所有的测试用例 []
+        case_names.append(caseinfo["desc"])  # 所有的用例名称 []
+        case_process.append(caseinfo["process"]) # 所有的用例使用的进程 []
+
+    return {
+        "case_infos": case_infos,
+        "case_names": case_names,
+        "case_process": case_process
+    }
+
+
+# data = excel_case_parser(r"D:\001_zzh\eng\api-engine\examples\examples-dsw")
+# print(data)

+ 133 - 0
apirun/parse/YamlCaseParser.py

@@ -0,0 +1,133 @@
+# -*- coding: utf-8 -*-
+import copy
+import os.path
+
+#  专门用例Yaml参数化
+#  导入yaml的包: pip install pyyaml
+
+# 读取yaml的数据
+import yaml, os, uuid
+from apirun.core.globalContext import g_context
+from apirun.Log.Log import logger
+
+# def traverse_files_name(path): # 遍历文件路径
+#     data = []
+#     for root, dirs, files in os.walk(path):
+#         for file in files:
+#             data.append(os.path.join(root, file))
+#     return data
+#
+# def traverse_files(path): # 遍历文件名称
+#     data = []
+#     for root, dirs, files in os.walk(path):
+#         for file in files:
+#             data.append(file)
+#     return data
+
+def load_context_from_yaml(folder_path):
+    """
+    :param folder_path: 文件路径
+    :return:
+    """
+    try:
+        yaml_file_path = os.path.join(folder_path, "context.yaml")  # 把2个文本进行拼接
+        with open(yaml_file_path, "r", encoding="utf-8") as f:
+            #  加载所有数据
+            data = yaml.load(f, Loader=yaml.FullLoader)
+            # 如果数据不为空,则设置到全局变量当中
+            if data: g_context().set_by_dict(data)
+    except Exception as e:
+        logger.error(f"装载yaml文件错误: {str(e)}")
+        return False
+
+
+# 加载我们满足条件的文件及数据
+def load_yaml_files(config_path):
+    """
+    返回满足条件的yaml文件列表及数据
+    :param config_path: Yaml存放的路径
+    :return:
+    """
+
+    yaml_caseInfos = []  # 存储所有的数据
+
+    suite_folder = os.path.join(config_path)
+    # 存放在该路径的全局变量进行写入
+    load_context_from_yaml(suite_folder)
+    # 满足条件的列表
+    for root, dirs, files in os.walk(suite_folder):
+        file_names = [(int(f.split("_")[0]), f) for f in files if
+                  f.endswith(".yaml") and f.split("_")[0].isdigit()]
+
+        # 排序,排序只保留文件名即可
+        file_names.sort()
+        file_names = [f[-1] for f in file_names]
+
+        # 加载每个文件的数据给到yaml_caseInfos
+        for file_name in file_names:
+            file_path = os.path.join(root, file_name)
+            with open(file_path, "r", encoding="utf-8") as f:
+                #  加载所有数据
+                caseinfo = yaml.full_load(f)
+                if caseinfo is not None:
+                    yaml_caseInfos.append(caseinfo)  # [{yaml里面的数据}]
+    return yaml_caseInfos  # 所有的测试用例
+
+def yaml_case_parser(config_path):
+    """
+    返回指定条件的格式
+    :param config_path:  文件的路径
+    :return: {
+            "case_infos": case_infos,  #  所有的测试用例 []
+            "case_names": case_names   #  所有测试用例对应的标题 []
+            }
+    """
+    # TODO 0: 对应固定的格式
+    case_infos = []
+    case_names = []
+    case_process = []
+
+    # TODO 1: 调用对应的方法:拿到所有的用例数据
+    yaml_caseInfos = load_yaml_files(config_path)
+    # TODO 2: 统一处理成一样的格式 (后面excel一样的处理)
+    for caseinfo in yaml_caseInfos:
+        # TODO 扩展: 获取ddt的数据,得到长度
+        ddts = caseinfo.get("ddts", [])
+        # TODO 扩展: 取到数据之后,我们需要删除ddts这个,避免有后续的影响
+        if len(ddts) > 0:
+            caseinfo.pop("ddts")
+
+        if len(ddts) == 0:
+            # 按照之前逻辑直接处理即可
+            case_name = caseinfo.get("desc", uuid.uuid4().__str__())  # 没有名字,我们自己生成一个,需要把它写到我们测试用例当中
+            caseinfo.update({"_case_name": case_name})  # 需要把它写到我们测试用例当中
+
+            case_infos.append(caseinfo)  # 所有的测试用例 []
+            case_names.append(case_name)  # 所有的用例名称 []
+            case_process.append(caseinfo['process'])  # 所有的用例使用的进程标识
+        else:
+            # 根据ddts的数据生成多组数据
+            for ddt in ddts:
+                new_case = copy.deepcopy(caseinfo)
+                # 给当前这个用例新增一个context对应值,没有的话则是一个空字典
+                context = new_case.get("context", {})
+                ddt.update(context)
+                new_case.update({"context": ddt})
+
+                # 用例值和对应的标题
+                case_name = f'{caseinfo.get("desc", uuid.uuid4().__str__())}-{ddt.get("desc", uuid.uuid4().__str__())}'
+                new_case.update({"_case_name": case_name})  # 需要把它写到我们测试用例当中
+
+                case_infos.append(new_case)  # 所有的测试用例 []
+                case_names.append(case_name)  # 所有的用例名称 []
+                case_process.append(new_case['process']) # 所有的用例使用的进程标识
+
+    return {
+        "case_infos": case_infos,
+        "case_names": case_names,
+        "case_process": case_process
+    }
+
+
+# data = yaml_case_parser(r"E:\1_A_TEST\zhoke\api-engine\examples\examples-ds")
+# print(data)

+ 1 - 0
apirun/parse/__init__.py

@@ -0,0 +1 @@
+# -*- coding: utf-8 -*-

BIN=BIN
apirun/parse/__pycache__/CaseParser.cpython-39.pyc


BIN=BIN
apirun/parse/__pycache__/ExcelCaseParser.cpython-39.pyc


BIN=BIN
apirun/parse/__pycache__/YamlCaseParser.cpython-39.pyc


BIN=BIN
apirun/parse/__pycache__/__init__.cpython-39.pyc


+ 0 - 0
apirun/parse/testlog.log


+ 10 - 0
apirun/pytest.ini

@@ -0,0 +1,10 @@
+[pytest]
+log_cli=false
+log_level=NOTSET
+log_format = %(asctime)s %(levelname)s %(message)s %(filename)s %(funcName)s %(lineno)d
+log_date_format = %Y-%m-%d %H:%M:%S
+
+log_file = ./logdata.log
+log_file_level = info
+log_file_format = %(asctime)s %(levelname)s %(message)s %(filename)s %(funcName)s %(lineno)d
+log_file_date_format = %Y-%m-%d %H:%M:%S

+ 335 - 0
apirun/testlog.log

@@ -0,0 +1,335 @@
+[2024-11-04 20:25:36,168] INFO -----------------开始执行测试用例:[{'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/user/login', 'PARAMS': None, 'HEADERS': None, 'DATA': {'username': '{{username}}', 'password': '{{password}}'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'通过JSONPATH提取数据-TOKEN': {'关键字': 'ex_jsonData', 'EXVALUE': '$..token', 'INDEX': None, 'VARNAME': 'token'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]-------------
+[2024-11-04 20:25:36,170] INFO 测试用例名称:能够正确登录用例,开始执行步骤0:发送Post请求 - {'关键字': 'request_post_form_urlencoded', 'URL': 'http://120.25.127.201:18001//user/login', 'PARAMS': None, 'HEADERS': None, 'DATA': {'username': '15096268001', 'password': '123456'}}
+[2024-11-04 20:25:36,255] INFO 测试用例名称:能够正确登录用例,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}
+[2024-11-04 20:25:36,260] INFO 测试用例名称:能够正确登录用例,开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}
+[2024-11-04 20:25:36,264] INFO 测试用例名称:能够正确登录用例,开始执行步骤3:通过JSONPATH提取数据-TOKEN - {'关键字': 'ex_jsonData', 'EXVALUE': '$..token', 'INDEX': None, 'VARNAME': 'token'}
+[2024-11-04 20:25:36,268] INFO 测试用例名称:能够正确登录用例,开始执行步骤4:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}
+[2024-11-04 20:25:36,270] INFO 测试用例名称:能够正确登录用例,开始执行步骤5:断言-等于-CODE - {'关键字': 'assert_text_comparators', 'VALUE': '200', 'EXPECTED': '200', 'OP_STR': '=='}
+[2024-11-04 20:25:36,272] INFO -------------------测试用例名称:能够正确登录用例执行结束----------------------
+[2024-11-04 20:25:36,282] INFO -----------------开始执行测试用例:[{'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/user/login', 'PARAMS': None, 'HEADERS': None, 'DATA': {'username': '15096268001', 'password': '1234562'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': '手机号或密码错误!', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '1004', 'OP_STR': '=='}}]-------------
+[2024-11-04 20:25:36,284] INFO 测试用例名称:登录失败-手机号或密码错误用例,开始执行步骤0:发送Post请求 - {'关键字': 'request_post_form_urlencoded', 'URL': 'http://120.25.127.201:18001//user/login', 'PARAMS': None, 'HEADERS': None, 'DATA': {'username': '15096268001', 'password': '1234562'}}
+[2024-11-04 20:25:36,362] INFO 测试用例名称:登录失败-手机号或密码错误用例,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}
+[2024-11-04 20:25:36,363] INFO 测试用例名称:登录失败-手机号或密码错误用例,开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}
+[2024-11-04 20:25:36,364] INFO 测试用例名称:登录失败-手机号或密码错误用例,开始执行步骤3:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': '手机号或密码错误!', 'EXPECTED': '手机号或密码错误!', 'OP_STR': '=='}
+[2024-11-04 20:25:36,365] INFO 测试用例名称:登录失败-手机号或密码错误用例,开始执行步骤4:断言-等于-CODE - {'关键字': 'assert_text_comparators', 'VALUE': '1004', 'EXPECTED': '1004', 'OP_STR': '=='}
+[2024-11-04 20:25:36,365] INFO -------------------测试用例名称:登录失败-手机号或密码错误用例执行结束----------------------
+[2024-11-04 20:25:36,369] INFO -----------------开始执行测试用例:[{'发送Get请求': {'关键字': 'request_get', 'URL': '{{URL}}/user/userInfo', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..username', 'INDEX': 0, 'VARNAME': 'msg_username'}}, {'断言-等于-响应USERNAME': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_username}}', 'EXPECTED': '{{username}}', 'OP_STR': '=='}}]-------------
+[2024-11-04 20:25:36,370] INFO 测试用例名称:查看用户信息,开始执行步骤0:发送Get请求 - {'关键字': 'request_get', 'URL': 'http://120.25.127.201:18001//user/userInfo', 'PARAMS': None, 'HEADERS': {'Authorization': 'eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE3MzEzMjc5MzYsInN1YiI6IntcImlkXCI6MTc5MTA1NjM4NjYzOTg3MjAwMCxcInVzZXJuYW1lXCI6XCIxNTA5NjI2ODAwMVwiLFwibmlja05hbWVcIjpcIuS4gOS6jOS4iVwifSIsImNyZWF0ZWQiOjE3MzA3MjMxMzYyMzN9.mrpQ6h4-izAgP-HbalIICX7HU8gSPH7xTJkjVrzLJGPv2X5e0mpRRg1-8elFCs_pn8yjdwolXOYALYsb-E1n1Q'}}
+[2024-11-04 20:25:36,453] INFO 测试用例名称:查看用户信息,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}
+[2024-11-04 20:25:36,458] INFO 测试用例名称:查看用户信息,开始执行步骤2:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}
+[2024-11-04 20:25:36,461] INFO 测试用例名称:查看用户信息,开始执行步骤3:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..username', 'INDEX': 0, 'VARNAME': 'msg_username'}
+[2024-11-04 20:25:36,466] INFO 测试用例名称:查看用户信息,开始执行步骤4:断言-等于-响应USERNAME - {'关键字': 'assert_text_comparators', 'VALUE': '15096268001', 'EXPECTED': '15096268001', 'OP_STR': '=='}
+[2024-11-04 20:25:36,468] INFO -------------------测试用例名称:查看用户信息执行结束----------------------
+[2024-11-04 20:25:36,473] INFO -----------------开始执行测试用例:[{'发送Post请求-上传图片': {'关键字': 'request_post_form_data', 'URL': '{{URL}}/file/picUpload', 'FILES': '{"file":open("./files/20240725223321.png","rb")}', 'PARAMS': None, 'HEADERS': None}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}, {'通过JSONPATH提取数据-图片路径': {'关键字': 'ex_jsonData', 'EXVALUE': '$..data', 'INDEX': 0, 'VARNAME': 'msg_data'}}]-------------
+[2024-11-04 20:25:36,474] INFO 测试用例名称:修改头像-上传头像,开始执行步骤0:发送Post请求-上传图片 - {'关键字': 'request_post_form_data', 'URL': 'http://120.25.127.201:18001//file/picUpload', 'FILES': '{"file":open("./files/20240725223321.png","rb")}', 'PARAMS': None, 'HEADERS': None}
+[2024-11-04 20:25:36,552] INFO 测试用例名称:修改头像-上传头像,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}
+[2024-11-04 20:25:36,553] INFO 测试用例名称:修改头像-上传头像,开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}
+[2024-11-04 20:25:36,554] INFO 测试用例名称:修改头像-上传头像,开始执行步骤3:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}
+[2024-11-04 20:25:36,555] INFO 测试用例名称:修改头像-上传头像,开始执行步骤4:断言-等于-CODE - {'关键字': 'assert_text_comparators', 'VALUE': '200', 'EXPECTED': '200', 'OP_STR': '=='}
+[2024-11-04 20:25:36,556] INFO 测试用例名称:修改头像-上传头像,开始执行步骤5:通过JSONPATH提取数据-图片路径 - {'关键字': 'ex_jsonData', 'EXVALUE': '$..data', 'INDEX': 0, 'VARNAME': 'msg_data'}
+[2024-11-04 20:25:36,556] INFO -------------------测试用例名称:修改头像-上传头像执行结束----------------------
+[2024-11-04 20:25:36,561] INFO -----------------开始执行测试用例:[{'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/user/updateUserInfo', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'userPhoto': '{{msg_data}}'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]-------------
+[2024-11-04 20:25:36,562] INFO 测试用例名称:修改头像-确定修改头像,开始执行步骤0:发送Post请求 - {'关键字': 'request_post_form_urlencoded', 'URL': 'http://120.25.127.201:18001//user/updateUserInfo', 'PARAMS': None, 'HEADERS': {'Authorization': 'eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE3MzEzMjc5MzYsInN1YiI6IntcImlkXCI6MTc5MTA1NjM4NjYzOTg3MjAwMCxcInVzZXJuYW1lXCI6XCIxNTA5NjI2ODAwMVwiLFwibmlja05hbWVcIjpcIuS4gOS6jOS4iVwifSIsImNyZWF0ZWQiOjE3MzA3MjMxMzYyMzN9.mrpQ6h4-izAgP-HbalIICX7HU8gSPH7xTJkjVrzLJGPv2X5e0mpRRg1-8elFCs_pn8yjdwolXOYALYsb-E1n1Q'}, 'DATA': {'userPhoto': '/localPic/2024/11/04/aa51dc43ea3448bb91f269fb9c489aa3.png'}}
+[2024-11-04 20:25:36,658] INFO 测试用例名称:修改头像-确定修改头像,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}
+[2024-11-04 20:25:36,662] INFO 测试用例名称:修改头像-确定修改头像,开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}
+[2024-11-04 20:25:36,666] INFO 测试用例名称:修改头像-确定修改头像,开始执行步骤3:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}
+[2024-11-04 20:25:36,670] INFO 测试用例名称:修改头像-确定修改头像,开始执行步骤4:断言-等于-CODE - {'关键字': 'assert_text_comparators', 'VALUE': '200', 'EXPECTED': '200', 'OP_STR': '=='}
+[2024-11-04 20:25:36,672] INFO -------------------测试用例名称:修改头像-确定修改头像执行结束----------------------
+[2024-11-04 20:25:36,681] INFO -----------------开始执行测试用例:[{'提取评价的书籍ID': {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}}, {'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': '{{id_1}}', 'commentContent': 'hami的接口自动化'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]-------------
+[2024-11-04 20:25:36,682] INFO 测试用例名称:我的书评-发布正常的书评(可能会失败),开始执行步骤0:提取评价的书籍ID - {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}
+[2024-11-04 20:25:36,928] INFO -------------------测试用例名称:我的书评-发布正常的书评(可能会失败)执行结束----------------------
+[2024-11-04 20:25:37,331] INFO -----------------开始执行测试用例:[{'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': '', 'commentContent': 'hami的接口自动化'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': '书籍ID不存在', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]-------------
+[2024-11-04 20:25:37,332] INFO 测试用例名称:我的书评-发布不存在的书籍ID(BUG),开始执行步骤0:发送Post请求 - {'关键字': 'request_post_form_urlencoded', 'URL': 'http://120.25.127.201:18001//book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': 'eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE3MzEzMjc5MzYsInN1YiI6IntcImlkXCI6MTc5MTA1NjM4NjYzOTg3MjAwMCxcInVzZXJuYW1lXCI6XCIxNTA5NjI2ODAwMVwiLFwibmlja05hbWVcIjpcIuS4gOS6jOS4iVwifSIsImNyZWF0ZWQiOjE3MzA3MjMxMzYyMzN9.mrpQ6h4-izAgP-HbalIICX7HU8gSPH7xTJkjVrzLJGPv2X5e0mpRRg1-8elFCs_pn8yjdwolXOYALYsb-E1n1Q'}, 'DATA': {'bookId': '', 'commentContent': 'hami的接口自动化'}}
+[2024-11-04 20:25:37,438] INFO 测试用例名称:我的书评-发布不存在的书籍ID(BUG),开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}
+[2024-11-04 20:25:37,440] INFO 测试用例名称:我的书评-发布不存在的书籍ID(BUG),开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}
+[2024-11-04 20:25:37,441] INFO 测试用例名称:我的书评-发布不存在的书籍ID(BUG),开始执行步骤3:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': '书籍ID不存在', 'OP_STR': '=='}
+[2024-11-04 20:25:37,442] INFO -------------------测试用例名称:我的书评-发布不存在的书籍ID(BUG)执行结束----------------------
+[2024-11-04 20:25:37,455] INFO -----------------开始执行测试用例:[{'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': 118, 'commentContent': 'hami的接口自动化'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': '已评价过该书籍!', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '3001', 'OP_STR': '=='}}]-------------
+[2024-11-04 20:25:37,456] INFO 测试用例名称:我的书评-发布已评价的数据,开始执行步骤0:发送Post请求 - {'关键字': 'request_post_form_urlencoded', 'URL': 'http://120.25.127.201:18001//book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': 'eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE3MzEzMjc5MzYsInN1YiI6IntcImlkXCI6MTc5MTA1NjM4NjYzOTg3MjAwMCxcInVzZXJuYW1lXCI6XCIxNTA5NjI2ODAwMVwiLFwibmlja05hbWVcIjpcIuS4gOS6jOS4iVwifSIsImNyZWF0ZWQiOjE3MzA3MjMxMzYyMzN9.mrpQ6h4-izAgP-HbalIICX7HU8gSPH7xTJkjVrzLJGPv2X5e0mpRRg1-8elFCs_pn8yjdwolXOYALYsb-E1n1Q'}, 'DATA': {'bookId': 118, 'commentContent': 'hami的接口自动化'}}
+[2024-11-04 20:25:37,544] INFO 测试用例名称:我的书评-发布已评价的数据,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}
+[2024-11-04 20:25:37,545] INFO 测试用例名称:我的书评-发布已评价的数据,开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}
+[2024-11-04 20:25:37,546] INFO 测试用例名称:我的书评-发布已评价的数据,开始执行步骤3:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': '已评价过该书籍!', 'EXPECTED': '已评价过该书籍!', 'OP_STR': '=='}
+[2024-11-04 20:25:37,547] INFO 测试用例名称:我的书评-发布已评价的数据,开始执行步骤4:断言-等于-CODE - {'关键字': 'assert_text_comparators', 'VALUE': '3001', 'EXPECTED': '3001', 'OP_STR': '=='}
+[2024-11-04 20:25:37,547] INFO -------------------测试用例名称:我的书评-发布已评价的数据执行结束----------------------
+[2024-11-04 20:25:37,552] INFO -----------------开始执行测试用例:[{'提取评价的书籍ID': {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}}, {'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': '{{id_1}}', 'commentContent': 'ham'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]-------------
+[2024-11-04 20:25:37,553] INFO 测试用例名称:我的书评-发布不满五个字的书评(BUG),开始执行步骤0:提取评价的书籍ID - {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}
+[2024-11-04 20:25:37,775] INFO -------------------测试用例名称:我的书评-发布不满五个字的书评(BUG)执行结束----------------------
+[2024-11-04 20:25:37,889] INFO -----------------开始执行测试用例:[{'提取评价的书籍ID': {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}}, {'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': '{{id_1}}', 'commentContent': 'hamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhahamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamham'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': '评价不能超过200字符!', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]-------------
+[2024-11-04 20:25:37,890] INFO 测试用例名称:我的书评-发布超过200个字的书评,开始执行步骤0:提取评价的书籍ID - {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}
+[2024-11-04 20:25:38,100] INFO -------------------测试用例名称:我的书评-发布超过200个字的书评执行结束----------------------
+[2024-11-04 20:25:38,197] INFO -----------------开始执行测试用例:[{'发送Get请求': {'关键字': 'request_get', 'URL': '{{URL}}/book/listClickRank', 'PARAMS': None, 'HEADERS': None}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': None, 'VARNAME': 'msg_success'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}]-------------
+[2024-11-04 20:25:38,198] INFO 测试用例名称:点击榜单能够显示对应的数据,开始执行步骤0:发送Get请求 - {'关键字': 'request_get', 'URL': 'http://120.25.127.201:18001//book/listClickRank', 'PARAMS': None, 'HEADERS': None}
+[2024-11-04 20:25:38,308] INFO 测试用例名称:点击榜单能够显示对应的数据,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': None, 'VARNAME': 'msg_success'}
+[2024-11-04 20:25:38,316] INFO 测试用例名称:点击榜单能够显示对应的数据,开始执行步骤2:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}
+[2024-11-04 20:25:38,318] INFO -------------------测试用例名称:点击榜单能够显示对应的数据执行结束----------------------
+[2024-11-04 20:25:38,331] INFO -----------------开始执行测试用例:[{'提取评价的书籍ID': {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}}, {'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': '{{id_1}}', 'commentContent': 'hami的接口自动化'}}}, {'JSON断言-等于-响应MSG': {'关键字': 'assert_json_comparators', 'VALUE': '$..msg', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'JSON断言-等于-CODE': {'关键字': 'assert_json_comparators', 'VALUE': '$..code', 'EXPECTED': '200', 'OP_STR': '=='}}]-------------
+[2024-11-04 20:25:38,333] INFO 测试用例名称:我的书评-发布正常的书评(优化-直接Josn断言),开始执行步骤0:提取评价的书籍ID - {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}
+[2024-11-04 20:25:38,537] INFO -------------------测试用例名称:我的书评-发布正常的书评(优化-直接Josn断言)执行结束----------------------
+[2024-11-04 20:25:38,654] INFO -----------------开始执行测试用例:[{'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/user/login', 'PARAMS': None, 'HEADERS': None, 'DATA': {'username': '{{username}}', 'password': '{{password}}'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'通过JSONPATH提取数据-TOKEN': {'关键字': 'ex_jsonData', 'EXVALUE': '$..token', 'INDEX': None, 'VARNAME': 'token'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]-------------
+[2024-11-04 20:25:38,655] INFO 测试用例名称:备份_能够正确登录用例,开始执行步骤0:发送Post请求 - {'关键字': 'request_post_form_urlencoded', 'URL': 'http://120.25.127.201:18001//user/login', 'PARAMS': None, 'HEADERS': None, 'DATA': {'username': '15096268001', 'password': '123456'}}
+[2024-11-04 20:25:38,730] INFO 测试用例名称:备份_能够正确登录用例,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}
+[2024-11-04 20:25:38,731] INFO 测试用例名称:备份_能够正确登录用例,开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}
+[2024-11-04 20:25:38,732] INFO 测试用例名称:备份_能够正确登录用例,开始执行步骤3:通过JSONPATH提取数据-TOKEN - {'关键字': 'ex_jsonData', 'EXVALUE': '$..token', 'INDEX': None, 'VARNAME': 'token'}
+[2024-11-04 20:25:38,733] INFO 测试用例名称:备份_能够正确登录用例,开始执行步骤4:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}
+[2024-11-04 20:25:38,734] INFO 测试用例名称:备份_能够正确登录用例,开始执行步骤5:断言-等于-CODE - {'关键字': 'assert_text_comparators', 'VALUE': '200', 'EXPECTED': '200', 'OP_STR': '=='}
+[2024-11-04 20:25:38,734] INFO -------------------测试用例名称:备份_能够正确登录用例执行结束----------------------
+[2024-11-04 20:25:38,739] INFO -----------------开始执行测试用例:[{'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/user/login', 'PARAMS': None, 'HEADERS': None, 'DATA': {'username': '15096268001', 'password': '1234562'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': '手机号或密码错误!', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '1004', 'OP_STR': '=='}}]-------------
+[2024-11-04 20:25:38,740] INFO 测试用例名称:备份_登录失败-手机号或密码错误用例,开始执行步骤0:发送Post请求 - {'关键字': 'request_post_form_urlencoded', 'URL': 'http://120.25.127.201:18001//user/login', 'PARAMS': None, 'HEADERS': None, 'DATA': {'username': '15096268001', 'password': '1234562'}}
+[2024-11-04 20:25:38,817] INFO 测试用例名称:备份_登录失败-手机号或密码错误用例,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}
+[2024-11-04 20:25:38,818] INFO 测试用例名称:备份_登录失败-手机号或密码错误用例,开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}
+[2024-11-04 20:25:38,820] INFO 测试用例名称:备份_登录失败-手机号或密码错误用例,开始执行步骤3:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': '手机号或密码错误!', 'EXPECTED': '手机号或密码错误!', 'OP_STR': '=='}
+[2024-11-04 20:25:38,821] INFO 测试用例名称:备份_登录失败-手机号或密码错误用例,开始执行步骤4:断言-等于-CODE - {'关键字': 'assert_text_comparators', 'VALUE': '1004', 'EXPECTED': '1004', 'OP_STR': '=='}
+[2024-11-04 20:25:38,821] INFO -------------------测试用例名称:备份_登录失败-手机号或密码错误用例执行结束----------------------
+[2024-11-04 20:25:38,827] INFO -----------------开始执行测试用例:[{'发送Get请求': {'关键字': 'request_get', 'URL': '{{URL}}/user/userInfo', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..username', 'INDEX': 0, 'VARNAME': 'msg_username'}}, {'断言-等于-响应USERNAME': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_username}}', 'EXPECTED': '{{username}}', 'OP_STR': '=='}}]-------------
+[2024-11-04 20:25:38,828] INFO 测试用例名称:备份_查看用户信息,开始执行步骤0:发送Get请求 - {'关键字': 'request_get', 'URL': 'http://120.25.127.201:18001//user/userInfo', 'PARAMS': None, 'HEADERS': {'Authorization': 'eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE3MzEzMjc5MzgsInN1YiI6IntcImlkXCI6MTc5MTA1NjM4NjYzOTg3MjAwMCxcInVzZXJuYW1lXCI6XCIxNTA5NjI2ODAwMVwiLFwibmlja05hbWVcIjpcIuS4gOS6jOS4iVwifSIsImNyZWF0ZWQiOjE3MzA3MjMxMzg3MTJ9.iLS16XWs6xTMI6mmdU0SWaeOLjMOSXugU_6ZasD5tqy3Uf4rS71m-RvXGmYoRr-sWXkiw2qJIY9e54Bcc6pOVw'}}
+[2024-11-04 20:25:38,909] INFO 测试用例名称:备份_查看用户信息,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}
+[2024-11-04 20:25:38,910] INFO 测试用例名称:备份_查看用户信息,开始执行步骤2:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}
+[2024-11-04 20:25:38,911] INFO 测试用例名称:备份_查看用户信息,开始执行步骤3:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..username', 'INDEX': 0, 'VARNAME': 'msg_username'}
+[2024-11-04 20:25:38,912] INFO 测试用例名称:备份_查看用户信息,开始执行步骤4:断言-等于-响应USERNAME - {'关键字': 'assert_text_comparators', 'VALUE': '15096268001', 'EXPECTED': '15096268001', 'OP_STR': '=='}
+[2024-11-04 20:25:38,912] INFO -------------------测试用例名称:备份_查看用户信息执行结束----------------------
+[2024-11-04 20:25:38,918] INFO -----------------开始执行测试用例:[{'发送Post请求-上传图片': {'关键字': 'request_post_form_data', 'URL': '{{URL}}/file/picUpload', 'FILES': '{"file":open("./files/20240725223321.png","rb")}', 'PARAMS': None, 'HEADERS': None}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}, {'通过JSONPATH提取数据-图片路径': {'关键字': 'ex_jsonData', 'EXVALUE': '$..data', 'INDEX': 0, 'VARNAME': 'msg_data'}}]-------------
+[2024-11-04 20:25:38,918] INFO 测试用例名称:备份_修改头像-上传头像,开始执行步骤0:发送Post请求-上传图片 - {'关键字': 'request_post_form_data', 'URL': 'http://120.25.127.201:18001//file/picUpload', 'FILES': '{"file":open("./files/20240725223321.png","rb")}', 'PARAMS': None, 'HEADERS': None}
+[2024-11-04 20:25:38,991] INFO 测试用例名称:备份_修改头像-上传头像,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}
+[2024-11-04 20:25:38,992] INFO 测试用例名称:备份_修改头像-上传头像,开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}
+[2024-11-04 20:25:38,993] INFO 测试用例名称:备份_修改头像-上传头像,开始执行步骤3:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}
+[2024-11-04 20:25:38,994] INFO 测试用例名称:备份_修改头像-上传头像,开始执行步骤4:断言-等于-CODE - {'关键字': 'assert_text_comparators', 'VALUE': '200', 'EXPECTED': '200', 'OP_STR': '=='}
+[2024-11-04 20:25:38,995] INFO 测试用例名称:备份_修改头像-上传头像,开始执行步骤5:通过JSONPATH提取数据-图片路径 - {'关键字': 'ex_jsonData', 'EXVALUE': '$..data', 'INDEX': 0, 'VARNAME': 'msg_data'}
+[2024-11-04 20:25:38,995] INFO -------------------测试用例名称:备份_修改头像-上传头像执行结束----------------------
+[2024-11-04 20:25:39,000] INFO -----------------开始执行测试用例:[{'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/user/updateUserInfo', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'userPhoto': '{{msg_data}}'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]-------------
+[2024-11-04 20:25:39,001] INFO 测试用例名称:备份_修改头像-确定修改头像,开始执行步骤0:发送Post请求 - {'关键字': 'request_post_form_urlencoded', 'URL': 'http://120.25.127.201:18001//user/updateUserInfo', 'PARAMS': None, 'HEADERS': {'Authorization': 'eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE3MzEzMjc5MzgsInN1YiI6IntcImlkXCI6MTc5MTA1NjM4NjYzOTg3MjAwMCxcInVzZXJuYW1lXCI6XCIxNTA5NjI2ODAwMVwiLFwibmlja05hbWVcIjpcIuS4gOS6jOS4iVwifSIsImNyZWF0ZWQiOjE3MzA3MjMxMzg3MTJ9.iLS16XWs6xTMI6mmdU0SWaeOLjMOSXugU_6ZasD5tqy3Uf4rS71m-RvXGmYoRr-sWXkiw2qJIY9e54Bcc6pOVw'}, 'DATA': {'userPhoto': '/localPic/2024/11/04/058a645adf1640e4a9e857d75a4fbb31.png'}}
+[2024-11-04 20:25:39,093] INFO 测试用例名称:备份_修改头像-确定修改头像,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}
+[2024-11-04 20:25:39,097] INFO 测试用例名称:备份_修改头像-确定修改头像,开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}
+[2024-11-04 20:25:39,100] INFO 测试用例名称:备份_修改头像-确定修改头像,开始执行步骤3:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}
+[2024-11-04 20:25:39,105] INFO 测试用例名称:备份_修改头像-确定修改头像,开始执行步骤4:断言-等于-CODE - {'关键字': 'assert_text_comparators', 'VALUE': '200', 'EXPECTED': '200', 'OP_STR': '=='}
+[2024-11-04 20:25:39,107] INFO -------------------测试用例名称:备份_修改头像-确定修改头像执行结束----------------------
+[2024-11-04 20:25:39,118] INFO -----------------开始执行测试用例:[{'提取评价的书籍ID': {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}}, {'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': '{{id_1}}', 'commentContent': 'hami的接口自动化'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]-------------
+[2024-11-04 20:25:39,120] INFO 测试用例名称:备份_我的书评-发布正常的书评(可能会失败),开始执行步骤0:提取评价的书籍ID - {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}
+[2024-11-04 20:25:39,334] INFO -------------------测试用例名称:备份_我的书评-发布正常的书评(可能会失败)执行结束----------------------
+[2024-11-04 20:25:39,434] INFO -----------------开始执行测试用例:[{'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': '', 'commentContent': 'hami的接口自动化'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': '书籍ID不存在', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]-------------
+[2024-11-04 20:25:39,435] INFO 测试用例名称:备份_我的书评-发布不存在的书籍ID(BUG),开始执行步骤0:发送Post请求 - {'关键字': 'request_post_form_urlencoded', 'URL': 'http://120.25.127.201:18001//book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': 'eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE3MzEzMjc5MzgsInN1YiI6IntcImlkXCI6MTc5MTA1NjM4NjYzOTg3MjAwMCxcInVzZXJuYW1lXCI6XCIxNTA5NjI2ODAwMVwiLFwibmlja05hbWVcIjpcIuS4gOS6jOS4iVwifSIsImNyZWF0ZWQiOjE3MzA3MjMxMzg3MTJ9.iLS16XWs6xTMI6mmdU0SWaeOLjMOSXugU_6ZasD5tqy3Uf4rS71m-RvXGmYoRr-sWXkiw2qJIY9e54Bcc6pOVw'}, 'DATA': {'bookId': '', 'commentContent': 'hami的接口自动化'}}
+[2024-11-04 20:25:39,547] INFO 测试用例名称:备份_我的书评-发布不存在的书籍ID(BUG),开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}
+[2024-11-04 20:25:39,548] INFO 测试用例名称:备份_我的书评-发布不存在的书籍ID(BUG),开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}
+[2024-11-04 20:25:39,549] INFO 测试用例名称:备份_我的书评-发布不存在的书籍ID(BUG),开始执行步骤3:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': '书籍ID不存在', 'OP_STR': '=='}
+[2024-11-04 20:25:39,550] INFO -------------------测试用例名称:备份_我的书评-发布不存在的书籍ID(BUG)执行结束----------------------
+[2024-11-04 20:25:39,563] INFO -----------------开始执行测试用例:[{'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': 118, 'commentContent': 'hami的接口自动化'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': '已评价过该书籍!', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '3001', 'OP_STR': '=='}}]-------------
+[2024-11-04 20:25:39,564] INFO 测试用例名称:备份_我的书评-发布已评价的数据,开始执行步骤0:发送Post请求 - {'关键字': 'request_post_form_urlencoded', 'URL': 'http://120.25.127.201:18001//book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': 'eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE3MzEzMjc5MzgsInN1YiI6IntcImlkXCI6MTc5MTA1NjM4NjYzOTg3MjAwMCxcInVzZXJuYW1lXCI6XCIxNTA5NjI2ODAwMVwiLFwibmlja05hbWVcIjpcIuS4gOS6jOS4iVwifSIsImNyZWF0ZWQiOjE3MzA3MjMxMzg3MTJ9.iLS16XWs6xTMI6mmdU0SWaeOLjMOSXugU_6ZasD5tqy3Uf4rS71m-RvXGmYoRr-sWXkiw2qJIY9e54Bcc6pOVw'}, 'DATA': {'bookId': 118, 'commentContent': 'hami的接口自动化'}}
+[2024-11-04 20:25:39,659] INFO 测试用例名称:备份_我的书评-发布已评价的数据,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}
+[2024-11-04 20:25:39,663] INFO 测试用例名称:备份_我的书评-发布已评价的数据,开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}
+[2024-11-04 20:25:39,667] INFO 测试用例名称:备份_我的书评-发布已评价的数据,开始执行步骤3:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': '已评价过该书籍!', 'EXPECTED': '已评价过该书籍!', 'OP_STR': '=='}
+[2024-11-04 20:25:39,671] INFO 测试用例名称:备份_我的书评-发布已评价的数据,开始执行步骤4:断言-等于-CODE - {'关键字': 'assert_text_comparators', 'VALUE': '3001', 'EXPECTED': '3001', 'OP_STR': '=='}
+[2024-11-04 20:25:39,672] INFO -------------------测试用例名称:备份_我的书评-发布已评价的数据执行结束----------------------
+[2024-11-04 20:25:39,683] INFO -----------------开始执行测试用例:[{'提取评价的书籍ID': {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}}, {'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': '{{id_1}}', 'commentContent': 'ham'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]-------------
+[2024-11-04 20:25:39,684] INFO 测试用例名称:备份_我的书评-发布不满五个字的书评(BUG),开始执行步骤0:提取评价的书籍ID - {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}
+[2024-11-04 20:25:39,884] INFO -------------------测试用例名称:备份_我的书评-发布不满五个字的书评(BUG)执行结束----------------------
+[2024-11-04 20:25:39,984] INFO -----------------开始执行测试用例:[{'提取评价的书籍ID': {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}}, {'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': '{{id_1}}', 'commentContent': 'hamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhahamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamham'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': '评价不能超过200字符!', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]-------------
+[2024-11-04 20:25:39,984] INFO 测试用例名称:备份_我的书评-发布超过200个字的书评,开始执行步骤0:提取评价的书籍ID - {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}
+[2024-11-04 20:25:40,197] INFO -------------------测试用例名称:备份_我的书评-发布超过200个字的书评执行结束----------------------
+[2024-11-04 20:25:40,296] INFO -----------------开始执行测试用例:[{'发送Get请求': {'关键字': 'request_get', 'URL': '{{URL}}/book/listClickRank', 'PARAMS': None, 'HEADERS': None}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': None, 'VARNAME': 'msg_success'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}]-------------
+[2024-11-04 20:25:40,296] INFO 测试用例名称:备份_点击榜单能够显示对应的数据,开始执行步骤0:发送Get请求 - {'关键字': 'request_get', 'URL': 'http://120.25.127.201:18001//book/listClickRank', 'PARAMS': None, 'HEADERS': None}
+[2024-11-04 20:25:40,406] INFO 测试用例名称:备份_点击榜单能够显示对应的数据,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': None, 'VARNAME': 'msg_success'}
+[2024-11-04 20:25:40,414] INFO 测试用例名称:备份_点击榜单能够显示对应的数据,开始执行步骤2:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}
+[2024-11-04 20:25:40,416] INFO -------------------测试用例名称:备份_点击榜单能够显示对应的数据执行结束----------------------
+[2024-11-04 20:25:40,422] INFO -----------------开始执行测试用例:[{'提取评价的书籍ID': {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}}, {'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': '{{id_1}}', 'commentContent': 'hami的接口自动化'}}}, {'JSON断言-等于-响应MSG': {'关键字': 'assert_json_comparators', 'VALUE': '$..msg', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'JSON断言-等于-CODE': {'关键字': 'assert_json_comparators', 'VALUE': '$..code', 'EXPECTED': '200', 'OP_STR': '=='}}]-------------
+[2024-11-04 20:25:40,422] INFO 测试用例名称:备份_我的书评-发布正常的书评(优化-直接Josn断言),开始执行步骤0:提取评价的书籍ID - {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}
+[2024-11-04 20:25:40,629] INFO -------------------测试用例名称:备份_我的书评-发布正常的书评(优化-直接Josn断言)执行结束----------------------
+[2024-11-04 20:25:40,748] INFO -----------------开始执行测试用例:[{'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/user/login', 'PARAMS': None, 'HEADERS': None, 'DATA': {'username': '{{username}}', 'password': '{{password}}'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'通过JSONPATH提取数据-TOKEN': {'关键字': 'ex_jsonData', 'EXVALUE': '$..token', 'INDEX': None, 'VARNAME': 'token'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]-------------
+[2024-11-04 20:25:40,749] INFO 测试用例名称:能够正确登录用例,开始执行步骤0:发送Post请求 - {'关键字': 'request_post_form_urlencoded', 'URL': 'http://120.25.127.201:18001//user/login', 'PARAMS': None, 'HEADERS': None, 'DATA': {'username': '15096268001', 'password': '123456'}}
+[2024-11-04 20:25:40,825] INFO 测试用例名称:能够正确登录用例,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}
+[2024-11-04 20:25:40,826] INFO 测试用例名称:能够正确登录用例,开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}
+[2024-11-04 20:25:40,827] INFO 测试用例名称:能够正确登录用例,开始执行步骤3:通过JSONPATH提取数据-TOKEN - {'关键字': 'ex_jsonData', 'EXVALUE': '$..token', 'INDEX': None, 'VARNAME': 'token'}
+[2024-11-04 20:25:40,828] INFO 测试用例名称:能够正确登录用例,开始执行步骤4:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}
+[2024-11-04 20:25:40,830] INFO 测试用例名称:能够正确登录用例,开始执行步骤5:断言-等于-CODE - {'关键字': 'assert_text_comparators', 'VALUE': '200', 'EXPECTED': '200', 'OP_STR': '=='}
+[2024-11-04 20:25:40,830] INFO -------------------测试用例名称:能够正确登录用例执行结束----------------------
+[2024-11-04 20:25:40,836] INFO -----------------开始执行测试用例:[{'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/user/login', 'PARAMS': None, 'HEADERS': None, 'DATA': {'username': '15096268001', 'password': '1234562'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': '手机号或密码错误!', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '1004', 'OP_STR': '=='}}]-------------
+[2024-11-04 20:25:40,837] INFO 测试用例名称:登录失败-手机号或密码错误用例,开始执行步骤0:发送Post请求 - {'关键字': 'request_post_form_urlencoded', 'URL': 'http://120.25.127.201:18001//user/login', 'PARAMS': None, 'HEADERS': None, 'DATA': {'username': '15096268001', 'password': '1234562'}}
+[2024-11-04 20:25:40,917] INFO 测试用例名称:登录失败-手机号或密码错误用例,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}
+[2024-11-04 20:25:40,919] INFO 测试用例名称:登录失败-手机号或密码错误用例,开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}
+[2024-11-04 20:25:40,920] INFO 测试用例名称:登录失败-手机号或密码错误用例,开始执行步骤3:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': '手机号或密码错误!', 'EXPECTED': '手机号或密码错误!', 'OP_STR': '=='}
+[2024-11-04 20:25:40,921] INFO 测试用例名称:登录失败-手机号或密码错误用例,开始执行步骤4:断言-等于-CODE - {'关键字': 'assert_text_comparators', 'VALUE': '1004', 'EXPECTED': '1004', 'OP_STR': '=='}
+[2024-11-04 20:25:40,921] INFO -------------------测试用例名称:登录失败-手机号或密码错误用例执行结束----------------------
+[2024-11-04 20:25:40,926] INFO -----------------开始执行测试用例:[{'发送Get请求': {'关键字': 'request_get', 'URL': '{{URL}}/user/userInfo', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..username', 'INDEX': 0, 'VARNAME': 'msg_username'}}, {'断言-等于-响应USERNAME': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_username}}', 'EXPECTED': '{{username}}', 'OP_STR': '=='}}]-------------
+[2024-11-04 20:25:40,926] INFO 测试用例名称:查看用户信息,开始执行步骤0:发送Get请求 - {'关键字': 'request_get', 'URL': 'http://120.25.127.201:18001//user/userInfo', 'PARAMS': None, 'HEADERS': {'Authorization': 'eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE3MzEzMjc5NDAsInN1YiI6IntcImlkXCI6MTc5MTA1NjM4NjYzOTg3MjAwMCxcInVzZXJuYW1lXCI6XCIxNTA5NjI2ODAwMVwiLFwibmlja05hbWVcIjpcIuS4gOS6jOS4iVwifSIsImNyZWF0ZWQiOjE3MzA3MjMxNDA4MDd9.SD_JAbmSzzYUHTkOi-Z3eBNl7-3eLJ5-znJJUJgyrm0Bl-vi2HrowFGwpzuBuPZblEJ4XiOMIADyamEEf08QwQ'}}
+[2024-11-04 20:25:41,003] INFO 测试用例名称:查看用户信息,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}
+[2024-11-04 20:25:41,004] INFO 测试用例名称:查看用户信息,开始执行步骤2:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}
+[2024-11-04 20:25:41,005] INFO 测试用例名称:查看用户信息,开始执行步骤3:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..username', 'INDEX': 0, 'VARNAME': 'msg_username'}
+[2024-11-04 20:25:41,006] INFO 测试用例名称:查看用户信息,开始执行步骤4:断言-等于-响应USERNAME - {'关键字': 'assert_text_comparators', 'VALUE': '15096268001', 'EXPECTED': '15096268001', 'OP_STR': '=='}
+[2024-11-04 20:25:41,006] INFO -------------------测试用例名称:查看用户信息执行结束----------------------
+[2024-11-04 20:25:41,011] INFO -----------------开始执行测试用例:[{'发送Post请求-上传图片': {'关键字': 'request_post_form_data', 'URL': '{{URL}}/file/picUpload', 'FILES': '{"file":open("./files/20240725223321.png","rb")}', 'PARAMS': None, 'HEADERS': None}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}, {'通过JSONPATH提取数据-图片路径': {'关键字': 'ex_jsonData', 'EXVALUE': '$..data', 'INDEX': 0, 'VARNAME': 'msg_data'}}]-------------
+[2024-11-04 20:25:41,012] INFO 测试用例名称:修改头像-上传头像,开始执行步骤0:发送Post请求-上传图片 - {'关键字': 'request_post_form_data', 'URL': 'http://120.25.127.201:18001//file/picUpload', 'FILES': '{"file":open("./files/20240725223321.png","rb")}', 'PARAMS': None, 'HEADERS': None}
+[2024-11-04 20:25:41,087] INFO 测试用例名称:修改头像-上传头像,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}
+[2024-11-04 20:25:41,090] INFO 测试用例名称:修改头像-上传头像,开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}
+[2024-11-04 20:25:41,091] INFO 测试用例名称:修改头像-上传头像,开始执行步骤3:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}
+[2024-11-04 20:25:41,092] INFO 测试用例名称:修改头像-上传头像,开始执行步骤4:断言-等于-CODE - {'关键字': 'assert_text_comparators', 'VALUE': '200', 'EXPECTED': '200', 'OP_STR': '=='}
+[2024-11-04 20:25:41,093] INFO 测试用例名称:修改头像-上传头像,开始执行步骤5:通过JSONPATH提取数据-图片路径 - {'关键字': 'ex_jsonData', 'EXVALUE': '$..data', 'INDEX': 0, 'VARNAME': 'msg_data'}
+[2024-11-04 20:25:41,093] INFO -------------------测试用例名称:修改头像-上传头像执行结束----------------------
+[2024-11-04 20:25:41,097] INFO -----------------开始执行测试用例:[{'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/user/updateUserInfo', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'userPhoto': '{{msg_data}}'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]-------------
+[2024-11-04 20:25:41,098] INFO 测试用例名称:修改头像-确定修改头像,开始执行步骤0:发送Post请求 - {'关键字': 'request_post_form_urlencoded', 'URL': 'http://120.25.127.201:18001//user/updateUserInfo', 'PARAMS': None, 'HEADERS': {'Authorization': 'eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE3MzEzMjc5NDAsInN1YiI6IntcImlkXCI6MTc5MTA1NjM4NjYzOTg3MjAwMCxcInVzZXJuYW1lXCI6XCIxNTA5NjI2ODAwMVwiLFwibmlja05hbWVcIjpcIuS4gOS6jOS4iVwifSIsImNyZWF0ZWQiOjE3MzA3MjMxNDA4MDd9.SD_JAbmSzzYUHTkOi-Z3eBNl7-3eLJ5-znJJUJgyrm0Bl-vi2HrowFGwpzuBuPZblEJ4XiOMIADyamEEf08QwQ'}, 'DATA': {'userPhoto': '/localPic/2024/11/04/d56a313d79204bd5a200b6604b6af8ac.png'}}
+[2024-11-04 20:25:41,184] INFO 测试用例名称:修改头像-确定修改头像,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}
+[2024-11-04 20:25:41,185] INFO 测试用例名称:修改头像-确定修改头像,开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}
+[2024-11-04 20:25:41,185] INFO 测试用例名称:修改头像-确定修改头像,开始执行步骤3:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}
+[2024-11-04 20:25:41,187] INFO 测试用例名称:修改头像-确定修改头像,开始执行步骤4:断言-等于-CODE - {'关键字': 'assert_text_comparators', 'VALUE': '200', 'EXPECTED': '200', 'OP_STR': '=='}
+[2024-11-04 20:25:41,187] INFO -------------------测试用例名称:修改头像-确定修改头像执行结束----------------------
+[2024-11-04 20:25:41,191] INFO -----------------开始执行测试用例:[{'提取评价的书籍ID': {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}}, {'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': '{{id_1}}', 'commentContent': 'hami的接口自动化'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]-------------
+[2024-11-04 20:25:41,192] INFO 测试用例名称:我的书评-发布正常的书评(可能会失败),开始执行步骤0:提取评价的书籍ID - {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}
+[2024-11-04 20:25:41,415] INFO -------------------测试用例名称:我的书评-发布正常的书评(可能会失败)执行结束----------------------
+[2024-11-04 20:25:41,512] INFO -----------------开始执行测试用例:[{'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': '', 'commentContent': 'hami的接口自动化'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': '书籍ID不存在', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]-------------
+[2024-11-04 20:25:41,513] INFO 测试用例名称:我的书评-发布不存在的书籍ID(BUG),开始执行步骤0:发送Post请求 - {'关键字': 'request_post_form_urlencoded', 'URL': 'http://120.25.127.201:18001//book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': 'eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE3MzEzMjc5NDAsInN1YiI6IntcImlkXCI6MTc5MTA1NjM4NjYzOTg3MjAwMCxcInVzZXJuYW1lXCI6XCIxNTA5NjI2ODAwMVwiLFwibmlja05hbWVcIjpcIuS4gOS6jOS4iVwifSIsImNyZWF0ZWQiOjE3MzA3MjMxNDA4MDd9.SD_JAbmSzzYUHTkOi-Z3eBNl7-3eLJ5-znJJUJgyrm0Bl-vi2HrowFGwpzuBuPZblEJ4XiOMIADyamEEf08QwQ'}, 'DATA': {'bookId': '', 'commentContent': 'hami的接口自动化'}}
+[2024-11-04 20:25:41,631] INFO 测试用例名称:我的书评-发布不存在的书籍ID(BUG),开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}
+[2024-11-04 20:25:41,635] INFO 测试用例名称:我的书评-发布不存在的书籍ID(BUG),开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}
+[2024-11-04 20:25:41,639] INFO 测试用例名称:我的书评-发布不存在的书籍ID(BUG),开始执行步骤3:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': '书籍ID不存在', 'OP_STR': '=='}
+[2024-11-04 20:25:41,642] INFO -------------------测试用例名称:我的书评-发布不存在的书籍ID(BUG)执行结束----------------------
+[2024-11-04 20:25:41,667] INFO -----------------开始执行测试用例:[{'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': 118, 'commentContent': 'hami的接口自动化'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': '已评价过该书籍!', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '3001', 'OP_STR': '=='}}]-------------
+[2024-11-04 20:25:41,668] INFO 测试用例名称:我的书评-发布已评价的数据,开始执行步骤0:发送Post请求 - {'关键字': 'request_post_form_urlencoded', 'URL': 'http://120.25.127.201:18001//book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': 'eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE3MzEzMjc5NDAsInN1YiI6IntcImlkXCI6MTc5MTA1NjM4NjYzOTg3MjAwMCxcInVzZXJuYW1lXCI6XCIxNTA5NjI2ODAwMVwiLFwibmlja05hbWVcIjpcIuS4gOS6jOS4iVwifSIsImNyZWF0ZWQiOjE3MzA3MjMxNDA4MDd9.SD_JAbmSzzYUHTkOi-Z3eBNl7-3eLJ5-znJJUJgyrm0Bl-vi2HrowFGwpzuBuPZblEJ4XiOMIADyamEEf08QwQ'}, 'DATA': {'bookId': 118, 'commentContent': 'hami的接口自动化'}}
+[2024-11-04 20:25:41,762] INFO 测试用例名称:我的书评-发布已评价的数据,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}
+[2024-11-04 20:25:41,763] INFO 测试用例名称:我的书评-发布已评价的数据,开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}
+[2024-11-04 20:25:41,764] INFO 测试用例名称:我的书评-发布已评价的数据,开始执行步骤3:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': '已评价过该书籍!', 'EXPECTED': '已评价过该书籍!', 'OP_STR': '=='}
+[2024-11-04 20:25:41,765] INFO 测试用例名称:我的书评-发布已评价的数据,开始执行步骤4:断言-等于-CODE - {'关键字': 'assert_text_comparators', 'VALUE': '3001', 'EXPECTED': '3001', 'OP_STR': '=='}
+[2024-11-04 20:25:41,766] INFO -------------------测试用例名称:我的书评-发布已评价的数据执行结束----------------------
+[2024-11-04 20:25:41,772] INFO -----------------开始执行测试用例:[{'提取评价的书籍ID': {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}}, {'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': '{{id_1}}', 'commentContent': 'ham'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]-------------
+[2024-11-04 20:25:41,773] INFO 测试用例名称:我的书评-发布不满五个字的书评(BUG),开始执行步骤0:提取评价的书籍ID - {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}
+[2024-11-04 20:25:41,995] INFO -------------------测试用例名称:我的书评-发布不满五个字的书评(BUG)执行结束----------------------
+[2024-11-04 20:25:42,093] INFO -----------------开始执行测试用例:[{'提取评价的书籍ID': {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}}, {'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': '{{id_1}}', 'commentContent': 'hamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhahamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamham'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': '评价不能超过200字符!', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]-------------
+[2024-11-04 20:25:42,094] INFO 测试用例名称:我的书评-发布超过200个字的书评,开始执行步骤0:提取评价的书籍ID - {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}
+[2024-11-04 20:25:42,310] INFO -------------------测试用例名称:我的书评-发布超过200个字的书评执行结束----------------------
+[2024-11-04 20:25:42,409] INFO -----------------开始执行测试用例:[{'发送Get请求': {'关键字': 'request_get', 'URL': '{{URL}}/book/listClickRank', 'PARAMS': None, 'HEADERS': None}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': None, 'VARNAME': 'msg_success'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}]-------------
+[2024-11-04 20:25:42,410] INFO 测试用例名称:点击榜单能够显示对应的数据,开始执行步骤0:发送Get请求 - {'关键字': 'request_get', 'URL': 'http://120.25.127.201:18001//book/listClickRank', 'PARAMS': None, 'HEADERS': None}
+[2024-11-04 20:25:42,526] INFO 测试用例名称:点击榜单能够显示对应的数据,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': None, 'VARNAME': 'msg_success'}
+[2024-11-04 20:25:42,528] INFO 测试用例名称:点击榜单能够显示对应的数据,开始执行步骤2:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}
+[2024-11-04 20:25:42,529] INFO -------------------测试用例名称:点击榜单能够显示对应的数据执行结束----------------------
+[2024-11-04 20:25:42,534] INFO -----------------开始执行测试用例:[{'提取评价的书籍ID': {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}}, {'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': '{{id_1}}', 'commentContent': 'hami的接口自动化'}}}, {'JSON断言-等于-响应MSG': {'关键字': 'assert_json_comparators', 'VALUE': '$..msg', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'JSON断言-等于-CODE': {'关键字': 'assert_json_comparators', 'VALUE': '$..code', 'EXPECTED': '200', 'OP_STR': '=='}}]-------------
+[2024-11-04 20:25:42,534] INFO 测试用例名称:我的书评-发布正常的书评(优化-直接Josn断言),开始执行步骤0:提取评价的书籍ID - {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}
+[2024-11-04 20:25:42,751] INFO -------------------测试用例名称:我的书评-发布正常的书评(优化-直接Josn断言)执行结束----------------------
+[2024-11-04 20:25:42,868] INFO -----------------开始执行测试用例:[{'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/user/login', 'PARAMS': None, 'HEADERS': None, 'DATA': {'username': '{{username}}', 'password': '{{password}}'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'通过JSONPATH提取数据-TOKEN': {'关键字': 'ex_jsonData', 'EXVALUE': '$..token', 'INDEX': None, 'VARNAME': 'token'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]-------------
+[2024-11-04 20:25:42,869] INFO 测试用例名称:能够正确登录用例,开始执行步骤0:发送Post请求 - {'关键字': 'request_post_form_urlencoded', 'URL': 'http://120.25.127.201:18001//user/login', 'PARAMS': None, 'HEADERS': None, 'DATA': {'username': '15096268001', 'password': '123456'}}
+[2024-11-04 20:25:42,952] INFO 测试用例名称:能够正确登录用例,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}
+[2024-11-04 20:25:42,953] INFO 测试用例名称:能够正确登录用例,开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}
+[2024-11-04 20:25:42,954] INFO 测试用例名称:能够正确登录用例,开始执行步骤3:通过JSONPATH提取数据-TOKEN - {'关键字': 'ex_jsonData', 'EXVALUE': '$..token', 'INDEX': None, 'VARNAME': 'token'}
+[2024-11-04 20:25:42,955] INFO 测试用例名称:能够正确登录用例,开始执行步骤4:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}
+[2024-11-04 20:25:42,956] INFO 测试用例名称:能够正确登录用例,开始执行步骤5:断言-等于-CODE - {'关键字': 'assert_text_comparators', 'VALUE': '200', 'EXPECTED': '200', 'OP_STR': '=='}
+[2024-11-04 20:25:42,956] INFO -------------------测试用例名称:能够正确登录用例执行结束----------------------
+[2024-11-04 20:25:42,960] INFO -----------------开始执行测试用例:[{'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/user/login', 'PARAMS': None, 'HEADERS': None, 'DATA': {'username': '15096268001', 'password': '1234562'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': '手机号或密码错误!', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '1004', 'OP_STR': '=='}}]-------------
+[2024-11-04 20:25:42,961] INFO 测试用例名称:登录失败-手机号或密码错误用例,开始执行步骤0:发送Post请求 - {'关键字': 'request_post_form_urlencoded', 'URL': 'http://120.25.127.201:18001//user/login', 'PARAMS': None, 'HEADERS': None, 'DATA': {'username': '15096268001', 'password': '1234562'}}
+[2024-11-04 20:25:43,044] INFO 测试用例名称:登录失败-手机号或密码错误用例,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}
+[2024-11-04 20:25:43,045] INFO 测试用例名称:登录失败-手机号或密码错误用例,开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}
+[2024-11-04 20:25:43,046] INFO 测试用例名称:登录失败-手机号或密码错误用例,开始执行步骤3:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': '手机号或密码错误!', 'EXPECTED': '手机号或密码错误!', 'OP_STR': '=='}
+[2024-11-04 20:25:43,047] INFO 测试用例名称:登录失败-手机号或密码错误用例,开始执行步骤4:断言-等于-CODE - {'关键字': 'assert_text_comparators', 'VALUE': '1004', 'EXPECTED': '1004', 'OP_STR': '=='}
+[2024-11-04 20:25:43,047] INFO -------------------测试用例名称:登录失败-手机号或密码错误用例执行结束----------------------
+[2024-11-04 20:25:43,052] INFO -----------------开始执行测试用例:[{'发送Get请求': {'关键字': 'request_get', 'URL': '{{URL}}/user/userInfo', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..username', 'INDEX': 0, 'VARNAME': 'msg_username'}}, {'断言-等于-响应USERNAME': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_username}}', 'EXPECTED': '{{username}}', 'OP_STR': '=='}}]-------------
+[2024-11-04 20:25:43,052] INFO 测试用例名称:查看用户信息,开始执行步骤0:发送Get请求 - {'关键字': 'request_get', 'URL': 'http://120.25.127.201:18001//user/userInfo', 'PARAMS': None, 'HEADERS': {'Authorization': 'eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE3MzEzMjc5NDIsInN1YiI6IntcImlkXCI6MTc5MTA1NjM4NjYzOTg3MjAwMCxcInVzZXJuYW1lXCI6XCIxNTA5NjI2ODAwMVwiLFwibmlja05hbWVcIjpcIuS4gOS6jOS4iVwifSIsImNyZWF0ZWQiOjE3MzA3MjMxNDI5MzJ9.GuTgz0vBHbVprp8aluVjtGeP5Ezeu2CCImLLPRYhH19N2xgzmvbGeDwDgZZ4Mme20rJnfkpZVpF8ThwY5gGslQ'}}
+[2024-11-04 20:25:43,133] INFO 测试用例名称:查看用户信息,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}
+[2024-11-04 20:25:43,135] INFO 测试用例名称:查看用户信息,开始执行步骤2:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}
+[2024-11-04 20:25:43,135] INFO 测试用例名称:查看用户信息,开始执行步骤3:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..username', 'INDEX': 0, 'VARNAME': 'msg_username'}
+[2024-11-04 20:25:43,137] INFO 测试用例名称:查看用户信息,开始执行步骤4:断言-等于-响应USERNAME - {'关键字': 'assert_text_comparators', 'VALUE': '15096268001', 'EXPECTED': '15096268001', 'OP_STR': '=='}
+[2024-11-04 20:25:43,137] INFO -------------------测试用例名称:查看用户信息执行结束----------------------
+[2024-11-04 20:25:43,142] INFO -----------------开始执行测试用例:[{'发送Post请求-上传图片': {'关键字': 'request_post_form_data', 'URL': '{{URL}}/file/picUpload', 'FILES': '{"file":open("./files/20240725223321.png","rb")}', 'PARAMS': None, 'HEADERS': None}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}, {'通过JSONPATH提取数据-图片路径': {'关键字': 'ex_jsonData', 'EXVALUE': '$..data', 'INDEX': 0, 'VARNAME': 'msg_data'}}]-------------
+[2024-11-04 20:25:43,143] INFO 测试用例名称:修改头像-上传头像,开始执行步骤0:发送Post请求-上传图片 - {'关键字': 'request_post_form_data', 'URL': 'http://120.25.127.201:18001//file/picUpload', 'FILES': '{"file":open("./files/20240725223321.png","rb")}', 'PARAMS': None, 'HEADERS': None}
+[2024-11-04 20:25:43,223] INFO 测试用例名称:修改头像-上传头像,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}
+[2024-11-04 20:25:43,224] INFO 测试用例名称:修改头像-上传头像,开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}
+[2024-11-04 20:25:43,225] INFO 测试用例名称:修改头像-上传头像,开始执行步骤3:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}
+[2024-11-04 20:25:43,226] INFO 测试用例名称:修改头像-上传头像,开始执行步骤4:断言-等于-CODE - {'关键字': 'assert_text_comparators', 'VALUE': '200', 'EXPECTED': '200', 'OP_STR': '=='}
+[2024-11-04 20:25:43,227] INFO 测试用例名称:修改头像-上传头像,开始执行步骤5:通过JSONPATH提取数据-图片路径 - {'关键字': 'ex_jsonData', 'EXVALUE': '$..data', 'INDEX': 0, 'VARNAME': 'msg_data'}
+[2024-11-04 20:25:43,227] INFO -------------------测试用例名称:修改头像-上传头像执行结束----------------------
+[2024-11-04 20:25:43,232] INFO -----------------开始执行测试用例:[{'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/user/updateUserInfo', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'userPhoto': '{{msg_data}}'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]-------------
+[2024-11-04 20:25:43,233] INFO 测试用例名称:修改头像-确定修改头像,开始执行步骤0:发送Post请求 - {'关键字': 'request_post_form_urlencoded', 'URL': 'http://120.25.127.201:18001//user/updateUserInfo', 'PARAMS': None, 'HEADERS': {'Authorization': 'eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE3MzEzMjc5NDIsInN1YiI6IntcImlkXCI6MTc5MTA1NjM4NjYzOTg3MjAwMCxcInVzZXJuYW1lXCI6XCIxNTA5NjI2ODAwMVwiLFwibmlja05hbWVcIjpcIuS4gOS6jOS4iVwifSIsImNyZWF0ZWQiOjE3MzA3MjMxNDI5MzJ9.GuTgz0vBHbVprp8aluVjtGeP5Ezeu2CCImLLPRYhH19N2xgzmvbGeDwDgZZ4Mme20rJnfkpZVpF8ThwY5gGslQ'}, 'DATA': {'userPhoto': '/localPic/2024/11/04/570f407f9a3e466caa6f146b4f9b8af4.png'}}
+[2024-11-04 20:25:43,321] INFO 测试用例名称:修改头像-确定修改头像,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}
+[2024-11-04 20:25:43,322] INFO 测试用例名称:修改头像-确定修改头像,开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}
+[2024-11-04 20:25:43,323] INFO 测试用例名称:修改头像-确定修改头像,开始执行步骤3:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}
+[2024-11-04 20:25:43,324] INFO 测试用例名称:修改头像-确定修改头像,开始执行步骤4:断言-等于-CODE - {'关键字': 'assert_text_comparators', 'VALUE': '200', 'EXPECTED': '200', 'OP_STR': '=='}
+[2024-11-04 20:25:43,325] INFO -------------------测试用例名称:修改头像-确定修改头像执行结束----------------------
+[2024-11-04 20:25:43,329] INFO -----------------开始执行测试用例:[{'提取评价的书籍ID': {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}}, {'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': '{{id_1}}', 'commentContent': 'hami的接口自动化'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]-------------
+[2024-11-04 20:25:43,330] INFO 测试用例名称:我的书评-发布正常的书评(可能会失败),开始执行步骤0:提取评价的书籍ID - {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}
+[2024-11-04 20:25:43,553] INFO -------------------测试用例名称:我的书评-发布正常的书评(可能会失败)执行结束----------------------
+[2024-11-04 20:25:43,652] INFO -----------------开始执行测试用例:[{'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': '', 'commentContent': 'hami的接口自动化'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': '书籍ID不存在', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]-------------
+[2024-11-04 20:25:43,653] INFO 测试用例名称:我的书评-发布不存在的书籍ID(BUG),开始执行步骤0:发送Post请求 - {'关键字': 'request_post_form_urlencoded', 'URL': 'http://120.25.127.201:18001//book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': 'eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE3MzEzMjc5NDIsInN1YiI6IntcImlkXCI6MTc5MTA1NjM4NjYzOTg3MjAwMCxcInVzZXJuYW1lXCI6XCIxNTA5NjI2ODAwMVwiLFwibmlja05hbWVcIjpcIuS4gOS6jOS4iVwifSIsImNyZWF0ZWQiOjE3MzA3MjMxNDI5MzJ9.GuTgz0vBHbVprp8aluVjtGeP5Ezeu2CCImLLPRYhH19N2xgzmvbGeDwDgZZ4Mme20rJnfkpZVpF8ThwY5gGslQ'}, 'DATA': {'bookId': '', 'commentContent': 'hami的接口自动化'}}
+[2024-11-04 20:25:43,761] INFO 测试用例名称:我的书评-发布不存在的书籍ID(BUG),开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}
+[2024-11-04 20:25:43,762] INFO 测试用例名称:我的书评-发布不存在的书籍ID(BUG),开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}
+[2024-11-04 20:25:43,763] INFO 测试用例名称:我的书评-发布不存在的书籍ID(BUG),开始执行步骤3:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': '书籍ID不存在', 'OP_STR': '=='}
+[2024-11-04 20:25:43,764] INFO -------------------测试用例名称:我的书评-发布不存在的书籍ID(BUG)执行结束----------------------
+[2024-11-04 20:25:43,778] INFO -----------------开始执行测试用例:[{'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': 118, 'commentContent': 'hami的接口自动化'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': '已评价过该书籍!', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '3001', 'OP_STR': '=='}}]-------------
+[2024-11-04 20:25:43,779] INFO 测试用例名称:我的书评-发布已评价的数据,开始执行步骤0:发送Post请求 - {'关键字': 'request_post_form_urlencoded', 'URL': 'http://120.25.127.201:18001//book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': 'eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE3MzEzMjc5NDIsInN1YiI6IntcImlkXCI6MTc5MTA1NjM4NjYzOTg3MjAwMCxcInVzZXJuYW1lXCI6XCIxNTA5NjI2ODAwMVwiLFwibmlja05hbWVcIjpcIuS4gOS6jOS4iVwifSIsImNyZWF0ZWQiOjE3MzA3MjMxNDI5MzJ9.GuTgz0vBHbVprp8aluVjtGeP5Ezeu2CCImLLPRYhH19N2xgzmvbGeDwDgZZ4Mme20rJnfkpZVpF8ThwY5gGslQ'}, 'DATA': {'bookId': 118, 'commentContent': 'hami的接口自动化'}}
+[2024-11-04 20:25:43,871] INFO 测试用例名称:我的书评-发布已评价的数据,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}
+[2024-11-04 20:25:43,873] INFO 测试用例名称:我的书评-发布已评价的数据,开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}
+[2024-11-04 20:25:43,874] INFO 测试用例名称:我的书评-发布已评价的数据,开始执行步骤3:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': '已评价过该书籍!', 'EXPECTED': '已评价过该书籍!', 'OP_STR': '=='}
+[2024-11-04 20:25:43,874] INFO 测试用例名称:我的书评-发布已评价的数据,开始执行步骤4:断言-等于-CODE - {'关键字': 'assert_text_comparators', 'VALUE': '3001', 'EXPECTED': '3001', 'OP_STR': '=='}
+[2024-11-04 20:25:43,875] INFO -------------------测试用例名称:我的书评-发布已评价的数据执行结束----------------------
+[2024-11-04 20:25:43,879] INFO -----------------开始执行测试用例:[{'提取评价的书籍ID': {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}}, {'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': '{{id_1}}', 'commentContent': 'ham'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]-------------
+[2024-11-04 20:25:43,880] INFO 测试用例名称:我的书评-发布不满五个字的书评(BUG),开始执行步骤0:提取评价的书籍ID - {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}
+[2024-11-04 20:25:44,094] INFO -------------------测试用例名称:我的书评-发布不满五个字的书评(BUG)执行结束----------------------
+[2024-11-04 20:25:44,193] INFO -----------------开始执行测试用例:[{'提取评价的书籍ID': {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}}, {'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': '{{id_1}}', 'commentContent': 'hamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhahamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamham'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': '评价不能超过200字符!', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]-------------
+[2024-11-04 20:25:44,193] INFO 测试用例名称:我的书评-发布超过200个字的书评,开始执行步骤0:提取评价的书籍ID - {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}
+[2024-11-04 20:25:44,408] INFO -------------------测试用例名称:我的书评-发布超过200个字的书评执行结束----------------------
+[2024-11-04 20:25:44,506] INFO -----------------开始执行测试用例:[{'发送Get请求': {'关键字': 'request_get', 'URL': '{{URL}}/book/listClickRank', 'PARAMS': None, 'HEADERS': None}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': None, 'VARNAME': 'msg_success'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}]-------------
+[2024-11-04 20:25:44,507] INFO 测试用例名称:点击榜单能够显示对应的数据,开始执行步骤0:发送Get请求 - {'关键字': 'request_get', 'URL': 'http://120.25.127.201:18001//book/listClickRank', 'PARAMS': None, 'HEADERS': None}
+[2024-11-04 20:25:44,607] INFO 测试用例名称:点击榜单能够显示对应的数据,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': None, 'VARNAME': 'msg_success'}
+[2024-11-04 20:25:44,610] INFO 测试用例名称:点击榜单能够显示对应的数据,开始执行步骤2:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}
+[2024-11-04 20:25:44,610] INFO -------------------测试用例名称:点击榜单能够显示对应的数据执行结束----------------------
+[2024-11-04 20:25:44,615] INFO -----------------开始执行测试用例:[{'提取评价的书籍ID': {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}}, {'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': '{{id_1}}', 'commentContent': 'hami的接口自动化'}}}, {'JSON断言-等于-响应MSG': {'关键字': 'assert_json_comparators', 'VALUE': '$..msg', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'JSON断言-等于-CODE': {'关键字': 'assert_json_comparators', 'VALUE': '$..code', 'EXPECTED': '200', 'OP_STR': '=='}}]-------------
+[2024-11-04 20:25:44,616] INFO 测试用例名称:我的书评-发布正常的书评(优化-直接Josn断言),开始执行步骤0:提取评价的书籍ID - {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}
+[2024-11-04 20:25:44,831] INFO -------------------测试用例名称:我的书评-发布正常的书评(优化-直接Josn断言)执行结束----------------------
+[2024-11-04 20:25:44,947] INFO -----------------开始执行测试用例:[{'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/user/login', 'PARAMS': None, 'HEADERS': None, 'DATA': {'username': '{{username}}', 'password': '{{password}}'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'通过JSONPATH提取数据-TOKEN': {'关键字': 'ex_jsonData', 'EXVALUE': '$..token', 'INDEX': None, 'VARNAME': 'token'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]-------------
+[2024-11-04 20:25:44,948] INFO 测试用例名称:能够正确登录用例,开始执行步骤0:发送Post请求 - {'关键字': 'request_post_form_urlencoded', 'URL': 'http://120.25.127.201:18001//user/login', 'PARAMS': None, 'HEADERS': None, 'DATA': {'username': '15096268001', 'password': '123456'}}
+[2024-11-04 20:25:45,027] INFO 测试用例名称:能够正确登录用例,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}
+[2024-11-04 20:25:45,028] INFO 测试用例名称:能够正确登录用例,开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}
+[2024-11-04 20:25:45,029] INFO 测试用例名称:能够正确登录用例,开始执行步骤3:通过JSONPATH提取数据-TOKEN - {'关键字': 'ex_jsonData', 'EXVALUE': '$..token', 'INDEX': None, 'VARNAME': 'token'}
+[2024-11-04 20:25:45,030] INFO 测试用例名称:能够正确登录用例,开始执行步骤4:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}
+[2024-11-04 20:25:45,031] INFO 测试用例名称:能够正确登录用例,开始执行步骤5:断言-等于-CODE - {'关键字': 'assert_text_comparators', 'VALUE': '200', 'EXPECTED': '200', 'OP_STR': '=='}
+[2024-11-04 20:25:45,031] INFO -------------------测试用例名称:能够正确登录用例执行结束----------------------
+[2024-11-04 20:25:45,036] INFO -----------------开始执行测试用例:[{'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/user/login', 'PARAMS': None, 'HEADERS': None, 'DATA': {'username': '15096268001', 'password': '1234562'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': '手机号或密码错误!', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '1004', 'OP_STR': '=='}}]-------------
+[2024-11-04 20:25:45,036] INFO 测试用例名称:登录失败-手机号或密码错误用例,开始执行步骤0:发送Post请求 - {'关键字': 'request_post_form_urlencoded', 'URL': 'http://120.25.127.201:18001//user/login', 'PARAMS': None, 'HEADERS': None, 'DATA': {'username': '15096268001', 'password': '1234562'}}
+[2024-11-04 20:25:45,117] INFO 测试用例名称:登录失败-手机号或密码错误用例,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}
+[2024-11-04 20:25:45,120] INFO 测试用例名称:登录失败-手机号或密码错误用例,开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}
+[2024-11-04 20:25:45,125] INFO 测试用例名称:登录失败-手机号或密码错误用例,开始执行步骤3:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': '手机号或密码错误!', 'EXPECTED': '手机号或密码错误!', 'OP_STR': '=='}
+[2024-11-04 20:25:45,129] INFO 测试用例名称:登录失败-手机号或密码错误用例,开始执行步骤4:断言-等于-CODE - {'关键字': 'assert_text_comparators', 'VALUE': '1004', 'EXPECTED': '1004', 'OP_STR': '=='}
+[2024-11-04 20:25:45,130] INFO -------------------测试用例名称:登录失败-手机号或密码错误用例执行结束----------------------
+[2024-11-04 20:25:45,142] INFO -----------------开始执行测试用例:[{'发送Get请求': {'关键字': 'request_get', 'URL': '{{URL}}/user/userInfo', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..username', 'INDEX': 0, 'VARNAME': 'msg_username'}}, {'断言-等于-响应USERNAME': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_username}}', 'EXPECTED': '{{username}}', 'OP_STR': '=='}}]-------------
+[2024-11-04 20:25:45,143] INFO 测试用例名称:查看用户信息,开始执行步骤0:发送Get请求 - {'关键字': 'request_get', 'URL': 'http://120.25.127.201:18001//user/userInfo', 'PARAMS': None, 'HEADERS': {'Authorization': 'eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE3MzEzMjc5NDUsInN1YiI6IntcImlkXCI6MTc5MTA1NjM4NjYzOTg3MjAwMCxcInVzZXJuYW1lXCI6XCIxNTA5NjI2ODAwMVwiLFwibmlja05hbWVcIjpcIuS4gOS6jOS4iVwifSIsImNyZWF0ZWQiOjE3MzA3MjMxNDUwMDh9.p8c93ppTDwsZlGT4rDNGu0okJNH4eq0hioc7SgqQ3XxvUHzIINMm6L6eRqFxjY_Bbi0EP4KMSBgDFZUKiDNF5A'}}
+[2024-11-04 20:25:45,222] INFO 测试用例名称:查看用户信息,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}
+[2024-11-04 20:25:45,223] INFO 测试用例名称:查看用户信息,开始执行步骤2:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}
+[2024-11-04 20:25:45,223] INFO 测试用例名称:查看用户信息,开始执行步骤3:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..username', 'INDEX': 0, 'VARNAME': 'msg_username'}
+[2024-11-04 20:25:45,225] INFO 测试用例名称:查看用户信息,开始执行步骤4:断言-等于-响应USERNAME - {'关键字': 'assert_text_comparators', 'VALUE': '15096268001', 'EXPECTED': '15096268001', 'OP_STR': '=='}
+[2024-11-04 20:25:45,225] INFO -------------------测试用例名称:查看用户信息执行结束----------------------
+[2024-11-04 20:25:45,229] INFO -----------------开始执行测试用例:[{'发送Post请求-上传图片': {'关键字': 'request_post_form_data', 'URL': '{{URL}}/file/picUpload', 'FILES': '{"file":open("./files/20240725223321.png","rb")}', 'PARAMS': None, 'HEADERS': None}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}, {'通过JSONPATH提取数据-图片路径': {'关键字': 'ex_jsonData', 'EXVALUE': '$..data', 'INDEX': 0, 'VARNAME': 'msg_data'}}]-------------
+[2024-11-04 20:25:45,230] INFO 测试用例名称:修改头像-上传头像,开始执行步骤0:发送Post请求-上传图片 - {'关键字': 'request_post_form_data', 'URL': 'http://120.25.127.201:18001//file/picUpload', 'FILES': '{"file":open("./files/20240725223321.png","rb")}', 'PARAMS': None, 'HEADERS': None}
+[2024-11-04 20:25:45,311] INFO 测试用例名称:修改头像-上传头像,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}
+[2024-11-04 20:25:45,312] INFO 测试用例名称:修改头像-上传头像,开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}
+[2024-11-04 20:25:45,313] INFO 测试用例名称:修改头像-上传头像,开始执行步骤3:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}
+[2024-11-04 20:25:45,313] INFO 测试用例名称:修改头像-上传头像,开始执行步骤4:断言-等于-CODE - {'关键字': 'assert_text_comparators', 'VALUE': '200', 'EXPECTED': '200', 'OP_STR': '=='}
+[2024-11-04 20:25:45,314] INFO 测试用例名称:修改头像-上传头像,开始执行步骤5:通过JSONPATH提取数据-图片路径 - {'关键字': 'ex_jsonData', 'EXVALUE': '$..data', 'INDEX': 0, 'VARNAME': 'msg_data'}
+[2024-11-04 20:25:45,315] INFO -------------------测试用例名称:修改头像-上传头像执行结束----------------------
+[2024-11-04 20:25:45,319] INFO -----------------开始执行测试用例:[{'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/user/updateUserInfo', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'userPhoto': '{{msg_data}}'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]-------------
+[2024-11-04 20:25:45,320] INFO 测试用例名称:修改头像-确定修改头像,开始执行步骤0:发送Post请求 - {'关键字': 'request_post_form_urlencoded', 'URL': 'http://120.25.127.201:18001//user/updateUserInfo', 'PARAMS': None, 'HEADERS': {'Authorization': 'eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE3MzEzMjc5NDUsInN1YiI6IntcImlkXCI6MTc5MTA1NjM4NjYzOTg3MjAwMCxcInVzZXJuYW1lXCI6XCIxNTA5NjI2ODAwMVwiLFwibmlja05hbWVcIjpcIuS4gOS6jOS4iVwifSIsImNyZWF0ZWQiOjE3MzA3MjMxNDUwMDh9.p8c93ppTDwsZlGT4rDNGu0okJNH4eq0hioc7SgqQ3XxvUHzIINMm6L6eRqFxjY_Bbi0EP4KMSBgDFZUKiDNF5A'}, 'DATA': {'userPhoto': '/localPic/2024/11/04/23464fa16c494ce7a9e26777e98ccf00.png'}}
+[2024-11-04 20:25:45,408] INFO 测试用例名称:修改头像-确定修改头像,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}
+[2024-11-04 20:25:45,409] INFO 测试用例名称:修改头像-确定修改头像,开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}
+[2024-11-04 20:25:45,410] INFO 测试用例名称:修改头像-确定修改头像,开始执行步骤3:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}
+[2024-11-04 20:25:45,411] INFO 测试用例名称:修改头像-确定修改头像,开始执行步骤4:断言-等于-CODE - {'关键字': 'assert_text_comparators', 'VALUE': '200', 'EXPECTED': '200', 'OP_STR': '=='}
+[2024-11-04 20:25:45,411] INFO -------------------测试用例名称:修改头像-确定修改头像执行结束----------------------
+[2024-11-04 20:25:45,415] INFO -----------------开始执行测试用例:[{'提取评价的书籍ID': {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}}, {'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': '{{id_1}}', 'commentContent': 'hami的接口自动化'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]-------------
+[2024-11-04 20:25:45,416] INFO 测试用例名称:我的书评-发布正常的书评(可能会失败),开始执行步骤0:提取评价的书籍ID - {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}
+[2024-11-04 20:25:45,629] INFO -------------------测试用例名称:我的书评-发布正常的书评(可能会失败)执行结束----------------------
+[2024-11-04 20:25:45,729] INFO -----------------开始执行测试用例:[{'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': '', 'commentContent': 'hami的接口自动化'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': '书籍ID不存在', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]-------------
+[2024-11-04 20:25:45,730] INFO 测试用例名称:我的书评-发布不存在的书籍ID(BUG),开始执行步骤0:发送Post请求 - {'关键字': 'request_post_form_urlencoded', 'URL': 'http://120.25.127.201:18001//book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': 'eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE3MzEzMjc5NDUsInN1YiI6IntcImlkXCI6MTc5MTA1NjM4NjYzOTg3MjAwMCxcInVzZXJuYW1lXCI6XCIxNTA5NjI2ODAwMVwiLFwibmlja05hbWVcIjpcIuS4gOS6jOS4iVwifSIsImNyZWF0ZWQiOjE3MzA3MjMxNDUwMDh9.p8c93ppTDwsZlGT4rDNGu0okJNH4eq0hioc7SgqQ3XxvUHzIINMm6L6eRqFxjY_Bbi0EP4KMSBgDFZUKiDNF5A'}, 'DATA': {'bookId': '', 'commentContent': 'hami的接口自动化'}}
+[2024-11-04 20:25:45,838] INFO 测试用例名称:我的书评-发布不存在的书籍ID(BUG),开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}
+[2024-11-04 20:25:45,839] INFO 测试用例名称:我的书评-发布不存在的书籍ID(BUG),开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}
+[2024-11-04 20:25:45,840] INFO 测试用例名称:我的书评-发布不存在的书籍ID(BUG),开始执行步骤3:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': '书籍ID不存在', 'OP_STR': '=='}
+[2024-11-04 20:25:45,841] INFO -------------------测试用例名称:我的书评-发布不存在的书籍ID(BUG)执行结束----------------------
+[2024-11-04 20:25:45,855] INFO -----------------开始执行测试用例:[{'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': 118, 'commentContent': 'hami的接口自动化'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': '已评价过该书籍!', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '3001', 'OP_STR': '=='}}]-------------
+[2024-11-04 20:25:45,856] INFO 测试用例名称:我的书评-发布已评价的数据,开始执行步骤0:发送Post请求 - {'关键字': 'request_post_form_urlencoded', 'URL': 'http://120.25.127.201:18001//book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': 'eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE3MzEzMjc5NDUsInN1YiI6IntcImlkXCI6MTc5MTA1NjM4NjYzOTg3MjAwMCxcInVzZXJuYW1lXCI6XCIxNTA5NjI2ODAwMVwiLFwibmlja05hbWVcIjpcIuS4gOS6jOS4iVwifSIsImNyZWF0ZWQiOjE3MzA3MjMxNDUwMDh9.p8c93ppTDwsZlGT4rDNGu0okJNH4eq0hioc7SgqQ3XxvUHzIINMm6L6eRqFxjY_Bbi0EP4KMSBgDFZUKiDNF5A'}, 'DATA': {'bookId': 118, 'commentContent': 'hami的接口自动化'}}
+[2024-11-04 20:25:45,951] INFO 测试用例名称:我的书评-发布已评价的数据,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}
+[2024-11-04 20:25:45,952] INFO 测试用例名称:我的书评-发布已评价的数据,开始执行步骤2:通过JSONPATH提取数据-Code - {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}
+[2024-11-04 20:25:45,953] INFO 测试用例名称:我的书评-发布已评价的数据,开始执行步骤3:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': '已评价过该书籍!', 'EXPECTED': '已评价过该书籍!', 'OP_STR': '=='}
+[2024-11-04 20:25:45,954] INFO 测试用例名称:我的书评-发布已评价的数据,开始执行步骤4:断言-等于-CODE - {'关键字': 'assert_text_comparators', 'VALUE': '3001', 'EXPECTED': '3001', 'OP_STR': '=='}
+[2024-11-04 20:25:45,954] INFO -------------------测试用例名称:我的书评-发布已评价的数据执行结束----------------------
+[2024-11-04 20:25:45,959] INFO -----------------开始执行测试用例:[{'提取评价的书籍ID': {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}}, {'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': '{{id_1}}', 'commentContent': 'ham'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]-------------
+[2024-11-04 20:25:45,960] INFO 测试用例名称:我的书评-发布不满五个字的书评(BUG),开始执行步骤0:提取评价的书籍ID - {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}
+[2024-11-04 20:25:46,154] INFO -------------------测试用例名称:我的书评-发布不满五个字的书评(BUG)执行结束----------------------
+[2024-11-04 20:25:46,255] INFO -----------------开始执行测试用例:[{'提取评价的书籍ID': {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}}, {'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': '{{id_1}}', 'commentContent': 'hamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhahamhamhamhamhamhamhamhamhamhamhamhamhamhamhamhamham'}}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': 0, 'VARNAME': 'msg_success'}}, {'通过JSONPATH提取数据-Code': {'关键字': 'ex_jsonData', 'EXVALUE': '$..code', 'INDEX': 0, 'VARNAME': 'msg_code'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': '评价不能超过200字符!', 'OP_STR': '=='}}, {'断言-等于-CODE': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_code}}', 'EXPECTED': '200', 'OP_STR': '=='}}]-------------
+[2024-11-04 20:25:46,256] INFO 测试用例名称:我的书评-发布超过200个字的书评,开始执行步骤0:提取评价的书籍ID - {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}
+[2024-11-04 20:25:46,464] INFO -------------------测试用例名称:我的书评-发布超过200个字的书评执行结束----------------------
+[2024-11-04 20:25:46,564] INFO -----------------开始执行测试用例:[{'发送Get请求': {'关键字': 'request_get', 'URL': '{{URL}}/book/listClickRank', 'PARAMS': None, 'HEADERS': None}}, {'通过JSONPATH提取数据-MSG': {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': None, 'VARNAME': 'msg_success'}}, {'断言-等于-响应MSG': {'关键字': 'assert_text_comparators', 'VALUE': '{{msg_success}}', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}]-------------
+[2024-11-04 20:25:46,565] INFO 测试用例名称:点击榜单能够显示对应的数据,开始执行步骤0:发送Get请求 - {'关键字': 'request_get', 'URL': 'http://120.25.127.201:18001//book/listClickRank', 'PARAMS': None, 'HEADERS': None}
+[2024-11-04 20:25:46,674] INFO 测试用例名称:点击榜单能够显示对应的数据,开始执行步骤1:通过JSONPATH提取数据-MSG - {'关键字': 'ex_jsonData', 'EXVALUE': '$..msg', 'INDEX': None, 'VARNAME': 'msg_success'}
+[2024-11-04 20:25:46,676] INFO 测试用例名称:点击榜单能够显示对应的数据,开始执行步骤2:断言-等于-响应MSG - {'关键字': 'assert_text_comparators', 'VALUE': 'SUCCESS', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}
+[2024-11-04 20:25:46,677] INFO -------------------测试用例名称:点击榜单能够显示对应的数据执行结束----------------------
+[2024-11-04 20:25:46,681] INFO -----------------开始执行测试用例:[{'提取评价的书籍ID': {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}}, {'发送Post请求': {'关键字': 'request_post_form_urlencoded', 'URL': '{{URL}}/book/addBookComment', 'PARAMS': None, 'HEADERS': {'Authorization': '{{token}}'}, 'DATA': {'bookId': '{{id_1}}', 'commentContent': 'hami的接口自动化'}}}, {'JSON断言-等于-响应MSG': {'关键字': 'assert_json_comparators', 'VALUE': '$..msg', 'EXPECTED': 'SUCCESS', 'OP_STR': '=='}}, {'JSON断言-等于-CODE': {'关键字': 'assert_json_comparators', 'VALUE': '$..code', 'EXPECTED': '200', 'OP_STR': '=='}}]-------------
+[2024-11-04 20:25:46,682] INFO 测试用例名称:我的书评-发布正常的书评(优化-直接Josn断言),开始执行步骤0:提取评价的书籍ID - {'关键字': 'ex_mysqlData', '数据库': 'dsw_mysql', 'SQL': 'SELECT id FROM `book`  ORDER BY RAND() LIMIT 1', '引用变量': 'id'}
+[2024-11-04 20:25:46,903] INFO -------------------测试用例名称:我的书评-发布正常的书评(优化-直接Josn断言)执行结束----------------------

+ 31 - 0
apirun/utils/DynamicTitle.py

@@ -0,0 +1,31 @@
+# -*- coding: utf-8 -*-
+
+# 动态生成标题
+import allure
+
+def dynamicTitle(CaseData):
+
+    # pip install allure-pytest==2.13.5
+    # 注意 这个caseinfo 是你参数化的数据给到的变量值。
+    allure.dynamic.parameter("caseinfo", "")
+
+    # 如果存在自定义标题
+    if CaseData.get("_case_name", None) is not None:
+        # 动态生成标题
+        allure.dynamic.title(CaseData["_case_name"])
+
+    if CaseData.get("storyName", None) is not None:
+        # 动态获取story模块名
+        allure.dynamic.story(CaseData["storyName"])
+
+    if CaseData.get("featureName", None) is not None:
+        # 动态获取feature模块名
+        allure.dynamic.feature(CaseData["featureName"])
+
+    if CaseData.get("remark", None) is not None:
+        # 动态获取备注信息
+        allure.dynamic.description(CaseData["remark"])
+
+    if CaseData.get("rank", None) is not None:
+        # 动态获取级别信息(blocker、critical、normal、minor、trivial)
+        allure.dynamic.severity(CaseData["rank"])

+ 44 - 0
apirun/utils/VarRender.py

@@ -0,0 +1,44 @@
+# -*- coding: utf-8 -*-
+import json
+
+# 变量渲染
+# 字符串模板进行参数渲染
+# 使用 jinja2 模板引擎 (类似 flask的模板)
+# https://docs.jinkan.org/docs/jinja2/templates.html
+
+from jinja2 import Template
+
+
+def refresh(target, context):
+    """
+    把你初始数据中需要渲染的数据变成context当中的值
+    :param target: 你的初始数据,用 {{变量名}} -- 请求数据
+    :param context: 你的初始数据渲染的值 -- 全局变量
+    :return:
+    """
+    if target is None: return None
+    return Template(str(target)).render(context)
+
+
+# 测试方法
+# def t_Refresh():
+#     target = "hello {{name}}, {{niasd}},{{token}}"
+#     context = {"name": "张三", "token": [
+# 				{
+# 					"type": "套餐",
+# 					"value": "套餐二"
+# 				},
+# 				{
+# 					"type": "颜色",
+# 					"value": "银色"
+# 				},
+# 				{
+# 					"type": "容量",
+# 					"value": "64G"
+# 				}
+# 			]}
+#     res = refresh(target, context)
+#     print(res)
+# t_Refresh()
+
+

+ 1 - 0
apirun/utils/__init__.py

@@ -0,0 +1 @@
+# -*- coding: utf-8 -*-

BIN=BIN
apirun/utils/__pycache__/DynamicTitle.cpython-39.pyc


BIN=BIN
apirun/utils/__pycache__/VarRender.cpython-39.pyc


BIN=BIN
apirun/utils/__pycache__/__init__.cpython-39.pyc


+ 41 - 0
cli.py

@@ -0,0 +1,41 @@
+# -*- coding: utf-8 -*-
+
+import pytest
+import os, sys
+
+from allure_combine import combine_allure
+
+def run():
+    # 获取 python运行参数
+    # 读取命令行传入的参数
+    pytest_cmd_config = []
+    for arg in sys.argv:
+        if arg.startswith("-"):
+            pytest_cmd_config.append(arg)
+
+    # 2. 构建pytest参数
+    pytest_args = ["-v", "-s", "--capture=sys","--clean-alluredir","--alluredir=allure-results",os.path.join(os.path.dirname(__file__), "apirun/core/ApiTestRunner.py")]
+    pytest_args.extend(pytest_cmd_config)
+    os.system(r"allure generate -c -o allure-report")
+    combine_allure(r"./allure-report")
+
+if __name__ == '__main__':
+    pytest_args = ["-v", "-s", "--capture=sys", '-n=1',
+                   "./apirun/core/ApiTestRunner.py",
+                   "--clean-alluredir",
+                   "--alluredir=allure-results",
+                   # "--type=yaml",
+                   # r"--cases=./examples/examples-ds"
+                   "--type=excel",
+                   r"--cases=./examples/examples-dsw"
+                   ]
+
+    pytest.main(pytest_args)
+    # TODO 代码参考如下:生成allure测试报告
+    os.system(r"allure generate -c -o allure-report")  # 等于你在命令行里面执行 allure
+
+    # TODO 3: 代码参考如下:生成allure测试报告,双击打开直接查看 combine_allure(测试报告的路径)
+    combine_allure(r"./allure-report")
+
+
+

+ 32 - 0
examples/examples-ds/0_用户注册驱动.yaml

@@ -0,0 +1,32 @@
+#process: G0--P
+#desc: 用户注册用例
+#featureName: 注册模块
+#storyName: 用户模块
+#remark: 注册模块备注
+#steps:
+#  - 生成注册的用户名:
+#      关键字: generate_name
+#      VARNAME: username
+#  - 发送Post请求:
+#      关键字: request_post_form_urlencoded
+#      URL: "{{URL}}"
+#      PARAMS:
+#        s: api/user/reg
+#      DATA:
+#        accounts: "{{username}}"
+#        pwd: "{{password}}"
+#        type: username
+#  - 通过JSONPATH提取数据-MSG:
+#      关键字: ex_jsonData
+#      EXVALUE: $..msg
+#      INDEX: 0
+#      VARNAME: msg_success
+#  - 断言-文本断言-等于:
+#      关键字: assert_text_comparators
+#      VALUE: "{{msg_success}}"
+#      EXPECTED: "{{expected}}"
+#      OP_STR: ==
+#ddts:
+#  - password: '123456'
+#    expected: '注册成功'
+#    desc: "生成用户名能生成成功"

+ 29 - 0
examples/examples-ds/10_提交订单-购物车_json.yaml

@@ -0,0 +1,29 @@
+process: G0--P
+desc: 提交订单-购物车
+featureName: 提交订单模块
+storyName: 订单模块
+remark: 提交订单模块备注
+steps:
+- 发送Post请求:
+    关键字: request_post_row_json
+    URL: "{{URL}}"
+    PARAMS:
+      s: /api/buy/add
+      application: app
+      token: "{{msg_token}}"
+    DATA:
+      buy_type: "cart"
+      address_id: "{{add_id}}"
+      ids: "{{card_id_2}}"
+      payment_id: 4
+      user_note: 通过购物车进行下单
+- 通过JSONPATH提取数据-MSG:
+     关键字: ex_jsonData
+     EXVALUE: $..msg
+     INDEX: 0
+     VARNAME: msg_success
+- 断言-文本断言-等于:
+    关键字: assert_text_comparators
+    VALUE: "{{msg_success}}"
+    EXPECTED: 提交成功
+    OP_STR: ==

+ 33 - 0
examples/examples-ds/11_提交订单-商品详情_json.yaml

@@ -0,0 +1,33 @@
+process: G0--P
+desc: 提交订单-商品详情
+featureName: 提交订单模块
+storyName: 订单模块
+remark: 提交订单模块备注
+steps:
+- 发送Post请求:
+    关键字: request_post_row_json
+    URL: "{{URL}}"
+    PARAMS:
+      s: /api/buy/add
+      application: app
+      token: "{{msg_token}}"
+    DATA:
+      buy_type: "goods"
+      goods_id: 11
+      stock: 2
+      spec:
+        - type: 尺寸
+          value: M
+      address_id: "{{add_id}}"
+      payment_id: 4
+      user_note: 通过商品详情进行下单
+- 通过JSONPATH提取数据-MSG:
+     关键字: ex_jsonData
+     EXVALUE: $..msg
+     INDEX: 0
+     VARNAME: msg_success
+- 断言-文本断言-等于:
+    关键字: assert_text_comparators
+    VALUE: "{{msg_success}}"
+    EXPECTED: 提交成功
+    OP_STR: ==

+ 27 - 0
examples/examples-ds/12_加密接口.yaml

@@ -0,0 +1,27 @@
+process: G0--P
+desc: 加密接口
+storyName: 加密项目
+featureName: 登录模块
+remark: 登录模块备注
+steps:
+  - 进行数据加密 - 用户名:
+      关键字: encrypt_aes
+      data: "{{username}}"
+      VARNAME: aes_username
+  - 进行数据加密 - 密码:
+      关键字: encrypt_aes
+      data: "{{password}}"
+      VARNAME: aes_password
+  - 发送Post请求:
+      关键字: request_post_form_urlencoded
+      URL: http://127.0.0.1:8080/login_safe
+      DATA:
+        password: "{{aes_username}}"
+        username: "{{aes_password}}"
+ddts:
+  - username: tony
+    password: '123456'
+    desc: "正确的用户名和密码"
+  - username: hami
+    password: '1234567'
+    desc: "错误的用户名和密码"

BIN=BIN
examples/examples-ds/1_测试用例.xlsx


+ 60 - 0
examples/examples-ds/1_登录接口数据驱动.yaml

@@ -0,0 +1,60 @@
+process: G0--P
+desc: T2-登录用例
+featureName: 登录模块
+storyName: 用户模块
+remark: 登录模块备注
+steps:
+  - 发送Post请求:
+      关键字: request_post_form_urlencoded
+      URL: "{{URL}}"
+      PARAMS:
+        s: /api/user/login
+        application: app
+      DATA:
+        accounts: "{{username}}"
+        pwd: "{{password}}"
+        type: username
+  - 通过JSONPATH提取数据-MSG:
+      关键字: ex_jsonData
+      EXVALUE: $..msg
+      INDEX: 0
+      VARNAME: msg_success
+  #- 通过JSONPATH提取数据-TOKEN:
+  #     关键字: ex_jsonData
+  #     EXVALUE: $..token
+  #     INDEX: 0
+  #     VARNAME: msg_token
+  - 断言-文本断言-等于:
+      关键字: assert_text_comparators
+      VALUE: "{{msg_success}}"
+      EXPECTED: "{{expected}}"
+      OP_STR: ==
+  - 断言-全量断言-等于:
+      关键字: assert_json_DeepDiff
+      json1: { "name": "hami","age": 18 }
+      json2: { "name": "hami","age": 18 }
+  #  - 断言-全量断言-不等于:
+  #      关键字: assert_json_DeepDiff
+  #      json1: { "name": "hami","age": 18 }
+  #      json2: { "name": "hami","age": 20 }
+  - 断言-全量断言-过滤字段:
+      关键字: assert_json_DeepDiff
+      json1: { "name": "hami","age": 18 , "city": 长沙 }
+      json2: { "name": "hami","age": 18 }
+      过滤字段: {city}
+  - 断言-全量断言-不等于:
+      关键字: assert_json_DeepDiff
+      json1: [ 1,2,3 ]
+      json2: [ 1,3,2 ]
+      忽略顺序: True
+ddts:
+  - username: hami
+    password: '123456'
+    expected: '登录成功'
+    desc: "正确的用户名和密码"
+  - username: hami
+    password: '1234567'
+    expected: '密码错误'
+    desc: "错误的用户名和密码"
+
+

+ 37 - 0
examples/examples-ds/2_登录成功测试用例.yaml

@@ -0,0 +1,37 @@
+process: G0--P
+desc: T2-登录用例
+featureName: 登录模块
+storyName: 用户模块
+remark: 登录模块备注
+steps:
+  - 发送Post请求:
+      关键字: request_post_form_urlencoded
+      URL: "{{URL}}"
+      PARAMS:
+        s: /api/user/login
+        application: app
+      DATA:
+        accounts: "{{username}}"
+        pwd: "{{password}}"
+        type: username
+  - 通过JSONPATH提取数据-MSG:
+      关键字: ex_jsonData
+      EXVALUE: $..msg
+      INDEX: 0
+      VARNAME: msg_success
+  - 通过JSONPATH提取数据-TOKEN:
+       关键字: ex_jsonData
+       EXVALUE: $..token
+       INDEX: 0
+       VARNAME: msg_token
+  - 断言-文本断言-等于:
+      关键字: assert_text_comparators
+      VALUE: "{{msg_success}}"
+      EXPECTED: "{{expected}}"
+      OP_STR: ==
+ddts:
+  - username: zzh124
+    password: '123456'
+    expected: '登录成功'
+    desc: "正确的用户名和密码"
+

+ 33 - 0
examples/examples-ds/3_加入购物车成功-表单.yaml

@@ -0,0 +1,33 @@
+process: G0--P
+desc: 加入购物车成功-表单格式
+featureName: 购物车模块
+storyName: 订单模块
+remark: 加入购物车模块备注
+steps:
+- 发送Post请求:
+    关键字: request_post_form_urlencoded
+    URL: "{{URL}}"
+    PARAMS:
+      s: api/cart/save
+      application: app
+      token: "{{msg_token}}"
+    DATA:
+      goods_id: "2"
+      spec:
+        - type: 套餐
+          value: 套餐二
+        - type: 颜色
+          value: 银色
+        - type: 容量
+          value: 64G
+      stock: 2
+- 通过JSONPATH提取数据-MSG:
+     关键字: ex_jsonData
+     EXVALUE: $..msg
+     INDEX: 0
+     VARNAME: msg_success
+- 断言-文本断言-等于:
+    关键字: assert_text_comparators
+    VALUE: "{{msg_success}}"
+    EXPECTED: 加入成功
+    OP_STR: ==

+ 33 - 0
examples/examples-ds/3_加入购物车成功_json.yaml

@@ -0,0 +1,33 @@
+process: G0--P
+desc: 加入购物车成功-JSON格式
+featureName: 购物车模块
+storyName: 订单模块
+remark: 加入购物车模块备注
+steps:
+- 发送Post请求:
+    关键字: request_post_row_json
+    URL: "{{URL}}"
+    PARAMS:
+      s: api/cart/save
+      application: app
+      token: "{{msg_token}}"
+    DATA:
+      goods_id: "2"
+      spec:
+        - type: 套餐
+          value: 套餐二
+        - type: 颜色
+          value: 银色
+        - type: 容量
+          value: 64G
+      stock: 2
+- 通过JSONPATH提取数据-MSG:
+     关键字: ex_jsonData
+     EXVALUE: $..msg
+     INDEX: 0
+     VARNAME: msg_success
+- 断言-文本断言-等于:
+    关键字: assert_text_comparators
+    VALUE: "{{msg_success}}"
+    EXPECTED: 加入成功
+    OP_STR: ==

+ 33 - 0
examples/examples-ds/4_查询购物车列表_get.yaml

@@ -0,0 +1,33 @@
+process: G0--P
+desc: 查询购物车列表数据
+featureName: 购物车模块
+storyName: 订单模块
+remark: 查看购物车模块备注
+steps:
+- 发送Post请求:
+    关键字: request_get
+    URL: "{{URL}}"
+    PARAMS:
+      s: api/cart/index
+      application: app
+      token: "{{msg_token}}"
+- 通过JSONPATH提取数据-MSG:
+     关键字: ex_jsonData
+     EXVALUE: $..msg
+     INDEX: 0
+     VARNAME: msg_success
+- 断言-文本断言-等于:
+    关键字: assert_text_comparators
+    VALUE: "{{msg_success}}"
+    EXPECTED: success
+    OP_STR: ==
+- 通过JSONPATH提取数据-购物车ID,用来删除:
+     关键字: ex_jsonData
+     EXVALUE: $..id
+     INDEX: 0
+     VARNAME: card_id_1
+- 通过JSONPATH提取数据--购物车ID,用来提交订单:
+     关键字: ex_jsonData
+     EXVALUE: $..id
+     INDEX: 1
+     VARNAME: card_id_2

+ 25 - 0
examples/examples-ds/5_删除购物车列表.yaml

@@ -0,0 +1,25 @@
+process: G0--P
+desc: 删除购物车成功
+featureName: 购物车模块
+storyName: 订单模块
+remark: 查看购物车模块备注
+steps:
+- 发送Post请求:
+    关键字: request_post_form_urlencoded
+    URL: "{{URL}}"
+    PARAMS:
+      s: api/cart/delete
+      application: app
+      token: "{{msg_token}}"
+    DATA:
+      id: "{{card_id_1}}"
+- 通过JSONPATH提取数据-MSG:
+     关键字: ex_jsonData
+     EXVALUE: $..msg
+     INDEX: 0
+     VARNAME: msg_success
+- 断言-文本断言-等于:
+    关键字: assert_text_comparators
+    VALUE: "{{msg_success}}"
+    EXPECTED: 删除成功
+    OP_STR: ==

+ 30 - 0
examples/examples-ds/6_添加地址接口.yaml

@@ -0,0 +1,30 @@
+process: G0--P
+desc: 添加地址接口
+featureName: 地址模块
+storyName: 地址模块
+remark: 添加地址模块备注
+steps:
+- 发送Post请求:
+    关键字: request_post_row_json
+    URL: "{{URL}}"
+    PARAMS:
+      s: api/useraddress/save
+      application: app
+      token: "{{msg_token}}"
+    DATA:
+      name: 李文静
+      tel: 15096964646
+      province: 18
+      city: 27
+      county: 2916
+      address: 2栋403室
+- 通过JSONPATH提取数据-MSG:
+     关键字: ex_jsonData
+     EXVALUE: $..msg
+     INDEX: 0
+     VARNAME: msg_success
+- 断言-文本断言-等于:
+    关键字: assert_text_comparators
+    VALUE: "{{msg_success}}"
+    EXPECTED: 新增成功
+    OP_STR: ==

+ 28 - 0
examples/examples-ds/7_查询地址列表接口_get.yaml

@@ -0,0 +1,28 @@
+process: G0--P
+desc: 查询地址列表
+featureName: 地址模块
+storyName: 地址模块
+remark: 地址列表模块备注
+steps:
+- 发送Post请求:
+    关键字: request_get
+    URL: "{{URL}}"
+    PARAMS:
+      s: api/useraddress/index
+      application: app
+      token: "{{msg_token}}"
+- 通过JSONPATH提取数据-MSG:
+     关键字: ex_jsonData
+     EXVALUE: $..msg
+     INDEX: 0
+     VARNAME: msg_success
+- 断言-文本断言-等于:
+    关键字: assert_text_comparators
+    VALUE: "{{msg_success}}"
+    EXPECTED: success
+    OP_STR: ==
+- 通过JSONPATH提取数据-add_id:
+     关键字: ex_jsonData
+     EXVALUE: $..id
+     INDEX: 0
+     VARNAME: add_id

+ 25 - 0
examples/examples-ds/8_删除地址列表接口.yaml

@@ -0,0 +1,25 @@
+process: G0--P
+desc: 删除地址列表
+featureName: 地址模块
+storyName: 地址模块
+remark: 地址删除模块备注
+steps:
+- 发送Post请求:
+    关键字: request_post_row_json
+    URL: "{{URL}}"
+    PARAMS:
+      s: api/useraddress/delete
+      application: app
+      token: "{{msg_token}}"
+    DATA:
+      id: "{{add_id}}"
+- 通过JSONPATH提取数据-MSG:
+     关键字: ex_jsonData
+     EXVALUE: $..msg
+     INDEX: 0
+     VARNAME: msg_success
+- 断言-文本断言-等于:
+    关键字: assert_text_comparators
+    VALUE: "{{msg_success}}"
+    EXPECTED: 删除成功
+    OP_STR: ==

+ 28 - 0
examples/examples-ds/9_查询地址列表接口.yaml

@@ -0,0 +1,28 @@
+process: G0--P
+desc: 查询地址列表-提交订单用
+featureName: 地址模块
+storyName: 地址模块
+remark: 地址列表模块备注
+steps:
+- 发送Post请求:
+    关键字: request_get
+    URL: "{{URL}}"
+    PARAMS:
+      s: api/useraddress/index
+      application: app
+      token: "{{msg_token}}"
+- 通过JSONPATH提取数据-MSG:
+     关键字: ex_jsonData
+     EXVALUE: $..msg
+     INDEX: 0
+     VARNAME: msg_success
+- 断言-文本断言-等于:
+    关键字: assert_text_comparators
+    VALUE: "{{msg_success}}"
+    EXPECTED: success
+    OP_STR: ==
+- 通过JSONPATH提取数据-add_id:
+     关键字: ex_jsonData
+     EXVALUE: $..id
+     INDEX: 0
+     VARNAME: add_id

+ 8 - 0
examples/examples-ds/context.yaml

@@ -0,0 +1,8 @@
+URL: http://shop-xo.hctestedu.com
+_database:
+  mysql001:
+    host: shop-xo.hctestedu.com
+    port: 3306
+    user: api_test
+    password: 'Aa9999!'
+    db: shopxo_hctested

+ 32 - 0
examples/examples-ds/haidun_pj/20_用户注册驱动.yaml

@@ -0,0 +1,32 @@
+#process: G1--P
+#desc: 用户注册用例
+#featureName: 注册模块
+#storyName: 用户模块
+#remark: 注册模块备注
+#steps:
+#  - 生成注册的用户名:
+#      关键字: generate_name
+#      VARNAME: username
+#  - 发送Post请求:
+#      关键字: request_post_form_urlencoded
+#      URL: "{{URL}}"
+#      PARAMS:
+#        s: api/user/reg
+#      DATA:
+#        accounts: "{{username}}"
+#        pwd: "{{password}}"
+#        type: username
+#  - 通过JSONPATH提取数据-MSG:
+#      关键字: ex_jsonData
+#      EXVALUE: $..msg
+#      INDEX: 0
+#      VARNAME: msg_success
+#  - 断言-文本断言-等于:
+#      关键字: assert_text_comparators
+#      VALUE: "{{msg_success}}"
+#      EXPECTED: "{{expected}}"
+#      OP_STR: ==
+#ddts:
+#  - password: '123456'
+#    expected: '注册成功'
+#    desc: "生成用户名能生成成功"

+ 60 - 0
examples/examples-ds/haidun_pj/21_登录接口数据驱动.yaml

@@ -0,0 +1,60 @@
+process: G1--P
+desc: T2-登录用例
+featureName: 登录模块
+storyName: 用户模块
+remark: 登录模块备注
+steps:
+  - 发送Post请求:
+      关键字: request_post_form_urlencoded
+      URL: "{{URL}}"
+      PARAMS:
+        s: /api/user/login
+        application: app
+      DATA:
+        accounts: "{{username}}"
+        pwd: "{{password}}"
+        type: username
+  - 通过JSONPATH提取数据-MSG:
+      关键字: ex_jsonData
+      EXVALUE: $..msg
+      INDEX: 0
+      VARNAME: msg_success
+  #- 通过JSONPATH提取数据-TOKEN:
+  #     关键字: ex_jsonData
+  #     EXVALUE: $..token
+  #     INDEX: 0
+  #     VARNAME: msg_token
+  - 断言-文本断言-等于:
+      关键字: assert_text_comparators
+      VALUE: "{{msg_success}}"
+      EXPECTED: "{{expected}}"
+      OP_STR: ==
+  - 断言-全量断言-等于:
+      关键字: assert_json_DeepDiff
+      json1: { "name": "hami","age": 18 }
+      json2: { "name": "hami","age": 18 }
+  #  - 断言-全量断言-不等于:
+  #      关键字: assert_json_DeepDiff
+  #      json1: { "name": "hami","age": 18 }
+  #      json2: { "name": "hami","age": 20 }
+  - 断言-全量断言-过滤字段:
+      关键字: assert_json_DeepDiff
+      json1: { "name": "hami","age": 18 , "city": 长沙 }
+      json2: { "name": "hami","age": 18 }
+      过滤字段: {city}
+  - 断言-全量断言-不等于:
+      关键字: assert_json_DeepDiff
+      json1: [ 1,2,3 ]
+      json2: [ 1,3,2 ]
+      忽略顺序: True
+ddts:
+  - username: hami
+    password: '123456'
+    expected: '登录成功'
+    desc: "正确的用户名和密码"
+  - username: hami
+    password: '1234567'
+    expected: '密码错误'
+    desc: "错误的用户名和密码"
+
+

+ 37 - 0
examples/examples-ds/haidun_pj/22_登录成功测试用例.yaml

@@ -0,0 +1,37 @@
+process: G1--P
+desc: T2-登录用例
+featureName: 登录模块
+storyName: 用户模块
+remark: 登录模块备注
+steps:
+  - 发送Post请求:
+      关键字: request_post_form_urlencoded
+      URL: "{{URL}}"
+      PARAMS:
+        s: /api/user/login
+        application: app
+      DATA:
+        accounts: "{{username}}"
+        pwd: "{{password}}"
+        type: username
+  - 通过JSONPATH提取数据-MSG:
+      关键字: ex_jsonData
+      EXVALUE: $..msg
+      INDEX: 0
+      VARNAME: msg_success
+  - 通过JSONPATH提取数据-TOKEN:
+       关键字: ex_jsonData
+       EXVALUE: $..token
+       INDEX: 0
+       VARNAME: msg_token
+  - 断言-文本断言-等于:
+      关键字: assert_text_comparators
+      VALUE: "{{msg_success}}"
+      EXPECTED: "{{expected}}"
+      OP_STR: ==
+ddts:
+  - username: zzh125
+    password: '123456'
+    expected: '登录成功'
+    desc: "正确的用户名和密码"
+

+ 33 - 0
examples/examples-ds/haidun_pj/23_加入购物车成功-表单.yaml

@@ -0,0 +1,33 @@
+process: G1--P
+desc: 加入购物车成功-表单格式
+featureName: 购物车模块
+storyName: 订单模块
+remark: 加入购物车模块备注
+steps:
+- 发送Post请求:
+    关键字: request_post_form_urlencoded
+    URL: "{{URL}}"
+    PARAMS:
+      s: api/cart/save
+      application: app
+      token: "{{msg_token}}"
+    DATA:
+      goods_id: "2"
+      spec:
+        - type: 套餐
+          value: 套餐二
+        - type: 颜色
+          value: 银色
+        - type: 容量
+          value: 64G
+      stock: 2
+- 通过JSONPATH提取数据-MSG:
+     关键字: ex_jsonData
+     EXVALUE: $..msg
+     INDEX: 0
+     VARNAME: msg_success
+- 断言-文本断言-等于:
+    关键字: assert_text_comparators
+    VALUE: "{{msg_success}}"
+    EXPECTED: 加入成功
+    OP_STR: ==

+ 33 - 0
examples/examples-ds/haidun_pj/23_加入购物车成功_json.yaml

@@ -0,0 +1,33 @@
+process: G1--P
+desc: 加入购物车成功-JSON格式
+featureName: 购物车模块
+storyName: 订单模块
+remark: 加入购物车模块备注
+steps:
+- 发送Post请求:
+    关键字: request_post_row_json
+    URL: "{{URL}}"
+    PARAMS:
+      s: api/cart/save
+      application: app
+      token: "{{msg_token}}"
+    DATA:
+      goods_id: "2"
+      spec:
+        - type: 套餐
+          value: 套餐二
+        - type: 颜色
+          value: 银色
+        - type: 容量
+          value: 64G
+      stock: 2
+- 通过JSONPATH提取数据-MSG:
+     关键字: ex_jsonData
+     EXVALUE: $..msg
+     INDEX: 0
+     VARNAME: msg_success
+- 断言-文本断言-等于:
+    关键字: assert_text_comparators
+    VALUE: "{{msg_success}}"
+    EXPECTED: 加入成功
+    OP_STR: ==

+ 33 - 0
examples/examples-ds/haidun_pj/24_查询购物车列表_get.yaml

@@ -0,0 +1,33 @@
+process: G1--P
+desc: 查询购物车列表数据
+featureName: 购物车模块
+storyName: 订单模块
+remark: 查看购物车模块备注
+steps:
+- 发送Post请求:
+    关键字: request_get
+    URL: "{{URL}}"
+    PARAMS:
+      s: api/cart/index
+      application: app
+      token: "{{msg_token}}"
+- 通过JSONPATH提取数据-MSG:
+     关键字: ex_jsonData
+     EXVALUE: $..msg
+     INDEX: 0
+     VARNAME: msg_success
+- 断言-文本断言-等于:
+    关键字: assert_text_comparators
+    VALUE: "{{msg_success}}"
+    EXPECTED: success
+    OP_STR: ==
+- 通过JSONPATH提取数据-购物车ID,用来删除:
+     关键字: ex_jsonData
+     EXVALUE: $..id
+     INDEX: 0
+     VARNAME: card_id_1
+- 通过JSONPATH提取数据--购物车ID,用来提交订单:
+     关键字: ex_jsonData
+     EXVALUE: $..id
+     INDEX: 1
+     VARNAME: card_id_2

+ 25 - 0
examples/examples-ds/haidun_pj/25_删除购物车列表.yaml

@@ -0,0 +1,25 @@
+process: G1--P
+desc: 删除购物车成功
+featureName: 购物车模块
+storyName: 订单模块
+remark: 查看购物车模块备注
+steps:
+- 发送Post请求:
+    关键字: request_post_form_urlencoded
+    URL: "{{URL}}"
+    PARAMS:
+      s: api/cart/delete
+      application: app
+      token: "{{msg_token}}"
+    DATA:
+      id: "{{card_id_1}}"
+- 通过JSONPATH提取数据-MSG:
+     关键字: ex_jsonData
+     EXVALUE: $..msg
+     INDEX: 0
+     VARNAME: msg_success
+- 断言-文本断言-等于:
+    关键字: assert_text_comparators
+    VALUE: "{{msg_success}}"
+    EXPECTED: 删除成功
+    OP_STR: ==

+ 30 - 0
examples/examples-ds/haidun_pj/26_添加地址接口.yaml

@@ -0,0 +1,30 @@
+process: G1--P
+desc: 添加地址接口
+featureName: 地址模块
+storyName: 地址模块
+remark: 添加地址模块备注
+steps:
+- 发送Post请求:
+    关键字: request_post_row_json
+    URL: "{{URL}}"
+    PARAMS:
+      s: api/useraddress/save
+      application: app
+      token: "{{msg_token}}"
+    DATA:
+      name: 李文静
+      tel: 15096964646
+      province: 18
+      city: 27
+      county: 2916
+      address: 2栋403室
+- 通过JSONPATH提取数据-MSG:
+     关键字: ex_jsonData
+     EXVALUE: $..msg
+     INDEX: 0
+     VARNAME: msg_success
+- 断言-文本断言-等于:
+    关键字: assert_text_comparators
+    VALUE: "{{msg_success}}"
+    EXPECTED: 新增成功
+    OP_STR: ==

+ 28 - 0
examples/examples-ds/haidun_pj/27_查询地址列表接口_get.yaml

@@ -0,0 +1,28 @@
+process: G1--P
+desc: 查询地址列表
+featureName: 地址模块
+storyName: 地址模块
+remark: 地址列表模块备注
+steps:
+- 发送Post请求:
+    关键字: request_get
+    URL: "{{URL}}"
+    PARAMS:
+      s: api/useraddress/index
+      application: app
+      token: "{{msg_token}}"
+- 通过JSONPATH提取数据-MSG:
+     关键字: ex_jsonData
+     EXVALUE: $..msg
+     INDEX: 0
+     VARNAME: msg_success
+- 断言-文本断言-等于:
+    关键字: assert_text_comparators
+    VALUE: "{{msg_success}}"
+    EXPECTED: success
+    OP_STR: ==
+- 通过JSONPATH提取数据-add_id:
+     关键字: ex_jsonData
+     EXVALUE: $..id
+     INDEX: 0
+     VARNAME: add_id

+ 25 - 0
examples/examples-ds/haidun_pj/28_删除地址列表接口.yaml

@@ -0,0 +1,25 @@
+process: G1--P
+desc: 删除地址列表
+featureName: 地址模块
+storyName: 地址模块
+remark: 地址删除模块备注
+steps:
+- 发送Post请求:
+    关键字: request_post_row_json
+    URL: "{{URL}}"
+    PARAMS:
+      s: api/useraddress/delete
+      application: app
+      token: "{{msg_token}}"
+    DATA:
+      id: "{{add_id}}"
+- 通过JSONPATH提取数据-MSG:
+     关键字: ex_jsonData
+     EXVALUE: $..msg
+     INDEX: 0
+     VARNAME: msg_success
+- 断言-文本断言-等于:
+    关键字: assert_text_comparators
+    VALUE: "{{msg_success}}"
+    EXPECTED: 删除成功
+    OP_STR: ==

+ 28 - 0
examples/examples-ds/haidun_pj/29_查询地址列表接口.yaml

@@ -0,0 +1,28 @@
+process: G1--P
+desc: 查询地址列表-提交订单用
+featureName: 地址模块
+storyName: 地址模块
+remark: 地址列表模块备注
+steps:
+- 发送Post请求:
+    关键字: request_get
+    URL: "{{URL}}"
+    PARAMS:
+      s: api/useraddress/index
+      application: app
+      token: "{{msg_token}}"
+- 通过JSONPATH提取数据-MSG:
+     关键字: ex_jsonData
+     EXVALUE: $..msg
+     INDEX: 0
+     VARNAME: msg_success
+- 断言-文本断言-等于:
+    关键字: assert_text_comparators
+    VALUE: "{{msg_success}}"
+    EXPECTED: success
+    OP_STR: ==
+- 通过JSONPATH提取数据-add_id:
+     关键字: ex_jsonData
+     EXVALUE: $..id
+     INDEX: 0
+     VARNAME: add_id

+ 29 - 0
examples/examples-ds/haidun_pj/30_提交订单-购物车_json.yaml

@@ -0,0 +1,29 @@
+process: G1--P
+desc: 提交订单-购物车
+featureName: 提交订单模块
+storyName: 订单模块
+remark: 提交订单模块备注
+steps:
+- 发送Post请求:
+    关键字: request_post_row_json
+    URL: "{{URL}}"
+    PARAMS:
+      s: /api/buy/add
+      application: app
+      token: "{{msg_token}}"
+    DATA:
+      buy_type: "cart"
+      address_id: "{{add_id}}"
+      ids: "{{card_id_2}}"
+      payment_id: 4
+      user_note: 通过购物车进行下单
+- 通过JSONPATH提取数据-MSG:
+     关键字: ex_jsonData
+     EXVALUE: $..msg
+     INDEX: 0
+     VARNAME: msg_success
+- 断言-文本断言-等于:
+    关键字: assert_text_comparators
+    VALUE: "{{msg_success}}"
+    EXPECTED: 提交成功
+    OP_STR: ==

+ 33 - 0
examples/examples-ds/haidun_pj/31_提交订单-商品详情_json.yaml

@@ -0,0 +1,33 @@
+process: G1--P
+desc: 提交订单-商品详情
+featureName: 提交订单模块
+storyName: 订单模块
+remark: 提交订单模块备注
+steps:
+- 发送Post请求:
+    关键字: request_post_row_json
+    URL: "{{URL}}"
+    PARAMS:
+      s: /api/buy/add
+      application: app
+      token: "{{msg_token}}"
+    DATA:
+      buy_type: "goods"
+      goods_id: 11
+      stock: 2
+      spec:
+        - type: 尺寸
+          value: M
+      address_id: "{{add_id}}"
+      payment_id: 4
+      user_note: 通过商品详情进行下单
+- 通过JSONPATH提取数据-MSG:
+     关键字: ex_jsonData
+     EXVALUE: $..msg
+     INDEX: 0
+     VARNAME: msg_success
+- 断言-文本断言-等于:
+    关键字: assert_text_comparators
+    VALUE: "{{msg_success}}"
+    EXPECTED: 提交成功
+    OP_STR: ==

+ 27 - 0
examples/examples-ds/haidun_pj/32_加密接口.yaml

@@ -0,0 +1,27 @@
+process: G1--P
+desc: 加密接口
+storyName: 加密项目
+featureName: 登录模块
+remark: 登录模块备注
+steps:
+  - 进行数据加密 - 用户名:
+      关键字: encrypt_aes
+      data: "{{username}}"
+      VARNAME: aes_username
+  - 进行数据加密 - 密码:
+      关键字: encrypt_aes
+      data: "{{password}}"
+      VARNAME: aes_password
+  - 发送Post请求:
+      关键字: request_post_form_urlencoded
+      URL: http://127.0.0.1:8080/login_safe
+      DATA:
+        password: "{{aes_username}}"
+        username: "{{aes_password}}"
+ddts:
+  - username: tony
+    password: '123456'
+    desc: "正确的用户名和密码"
+  - username: hami
+    password: '1234567'
+    desc: "错误的用户名和密码"

BIN=BIN
examples/examples-dsw/1_测试用例_读书屋.xlsx


BIN=BIN
examples/examples-dsw/2_测试用例_读书屋.xlsx


BIN=BIN
examples/examples-dsw/3_测试用例_读书屋.xlsx


BIN=BIN
examples/examples-dsw/4_测试用例_读书屋.xlsx


BIN=BIN
examples/examples-dsw/context.xlsx


BIN=BIN
examples/examples-dsw/海顿_测试用例.xlsx


+ 46 - 0
requirements.txt

@@ -0,0 +1,46 @@
+allure-combine==1.0.11
+allure-pytest==2.13.5
+allure-python-commons==2.13.5
+attrs==23.2.0
+beautifulsoup4==4.12.3
+blinker==1.8.2
+bs4==0.0.2
+certifi==2024.7.4
+charset-normalizer==3.3.2
+click==8.1.7
+colorama==0.4.6
+deepdiff==7.0.1
+et-xmlfile==1.1.0
+exceptiongroup==1.2.2
+Flask==3.0.3
+idna==3.7
+importlib_metadata==8.0.0
+iniconfig==2.0.0
+itsdangerous==2.2.0
+Jinja2==3.1.4
+jsonpath==0.82.2
+MarkupSafe==2.1.5
+numpy==2.0.0
+openpyxl==3.1.5
+ordered-set==4.1.0
+packaging==24.1
+pandas==2.2.2
+pluggy==1.5.0
+pycryptodome==3.20.0
+PyMySQL==1.1.1
+pytest==8.0.2
+pytest-rerunfailures==14.0
+python-dateutil==2.9.0.post0
+pytz==2024.1
+PyYAML==6.0.1
+requests==2.32.3
+six==1.16.0
+pytest-xdist==3.6.1
+filelock==3.16.1
+soupsieve==2.5
+tomli==2.0.1
+tzdata==2024.1
+urllib3==2.2.2
+Werkzeug==3.0.3
+zipp==3.19.2
+pytest-rerunfailures

+ 59 - 0
setup.py

@@ -0,0 +1,59 @@
+# -*- coding: utf-8 -*-
+import setuptools
+
+"""
+打包成一个 可执行模块
+"""
+with open("README.md", "r", encoding="utf-8") as fh:
+    long_description = fh.read()
+
+setuptools.setup(
+    # 关于项目的介绍 - 随便写都可以
+    name="APIRunner",
+    version="0.0.1",
+    author="zzh",
+    author_email="zzh",
+    description="API 自动化测试工具",
+    license="GPLv3",
+    long_description=long_description,
+    long_description_content_type="text/markdown",
+    url="",
+    project_urls={
+        "Bug Tracker": "",
+        "Contact Us": "",
+    },
+
+    classifiers=[
+        "Programming Language :: Python :: 3",
+        "License :: OSI Approved :: GNU General Public License (GPL)",
+        "Operating System :: OS Independent",
+    ],
+    # 需要安装的依赖 -- 工具依赖
+    install_requires=[
+        "allure-pytest==2.13.5",
+        "Jinja2",
+        "jsonpath",
+        "pluggy",
+        "pycparser",
+        "PyMySQL",
+        "PySocks",
+        "pytest",
+        "PyYAML",
+        "pyyaml-include==1.3.1",
+        "requests",
+        "exceptiongroup",
+        "jsonpath==0.82.2",
+        "allure-pytest==2.13.5"
+    ],
+    packages=setuptools.find_packages(),
+    package_data={'': ['*.*']},  # 默认只会加载py文件,设置加载所有的文件。
+    python_requires=">=3.6",
+    # 生成一个 可执行文件 例如 windows下面 .exe
+    entry_points={
+        'console_scripts': [
+            # 可执行文件的名称=执行的具体代码方法
+            'apirun=apirun.cli:run'
+        ]
+    },
+    zip_safe=False
+)