Browse Source

自动生成测试报告

aobn 2 months ago
parent
commit
03e51761a1
98 changed files with 947 additions and 98 deletions
  1. BIN
      .DS_Store
  2. 35 0
      .idea/copilotDiffState.xml
  3. 69 22
      .idea/workspace.xml
  4. 0 0
      __init__.py
  5. BIN
      __pycache__/__init__.cpython-311.pyc
  6. BIN
      __pycache__/conftest.cpython-311-pytest-8.4.2.pyc
  7. 6 0
      conftest.py
  8. BIN
      demo/.DS_Store
  9. BIN
      demo/__pycache__/test_a.cpython-311-pytest-8.4.2.pyc
  10. BIN
      demo/__pycache__/test_test.cpython-311-pytest-8.4.2.pyc
  11. BIN
      demo/dic/__pycache__/global_value.cpython-311.pyc
  12. 0 10
      demo/log/data.txt
  13. 3 9
      demo/log/globalInfo.txt.txt
  14. 0 10
      demo/log/headers.txt
  15. 0 0
      demo/log/json.txt
  16. 0 10
      demo/log/params.txt
  17. 5 15
      demo/log/respose.txt
  18. 0 10
      demo/log/url.txt
  19. 0 3
      demo/main.py
  20. BIN
      demo/main/__pycache__/test_a.cpython-311-pytest-8.4.2.pyc
  21. BIN
      demo/main/__pycache__/test_test.cpython-311-pytest-8.4.2.pyc
  22. 23 8
      demo/test_a.py
  23. 0 0
      demo/test_test.py
  24. BIN
      demo/utils/__pycache__/__init__.cpython-311.pyc
  25. BIN
      demo/utils/__pycache__/get_excel.cpython-311.pyc
  26. BIN
      demo/utils/__pycache__/send.cpython-311.pyc
  27. BIN
      demo/utils/__pycache__/write_log.cpython-311.pyc
  28. 1 1
      demo/utils/get_excel.py
  29. 7 0
      main.py
  30. 6 0
      pytest.ini
  31. 0 0
      requirements.txt
  32. 1 0
      测试报告/html/app.js
  33. 1 0
      测试报告/html/data/attachments/4652bcf73863b21f.txt
  34. 1 0
      测试报告/html/data/attachments/60dd6b5acbf1a15f.txt
  35. 1 0
      测试报告/html/data/attachments/976c983772a155ae.txt
  36. 1 0
      测试报告/html/data/attachments/b930ab66dedfb678.txt
  37. 1 0
      测试报告/html/data/attachments/cf9b61876a1932f1.txt
  38. 1 0
      测试报告/html/data/attachments/e2dcd8c4f6b2bfe2.txt
  39. 2 0
      测试报告/html/data/behaviors.csv
  40. 0 0
      测试报告/html/data/behaviors.json
  41. 0 0
      测试报告/html/data/categories.csv
  42. 1 0
      测试报告/html/data/categories.json
  43. 0 0
      测试报告/html/data/packages.json
  44. 7 0
      测试报告/html/data/suites.csv
  45. 0 0
      测试报告/html/data/suites.json
  46. 1 0
      测试报告/html/data/test-cases/3ac100dfa00828b8.json
  47. 0 0
      测试报告/html/data/test-cases/427c56cf8112259b.json
  48. 1 0
      测试报告/html/data/test-cases/6836f8a41e785dbe.json
  49. 0 0
      测试报告/html/data/test-cases/862e50ffb623bd70.json
  50. 0 0
      测试报告/html/data/test-cases/8e03048d4413b43b.json
  51. 0 0
      测试报告/html/data/test-cases/8f4399de319fe413.json
  52. 0 0
      测试报告/html/data/timeline.json
  53. 13 0
      测试报告/html/export/influxDbData.txt
  54. 10 0
      测试报告/html/export/mail.html
  55. 13 0
      测试报告/html/export/prometheusData.txt
  56. BIN
      测试报告/html/favicon.ico
  57. 1 0
      测试报告/html/history/categories-trend.json
  58. 1 0
      测试报告/html/history/duration-trend.json
  59. 1 0
      测试报告/html/history/history-trend.json
  60. 1 0
      测试报告/html/history/history.json
  61. 1 0
      测试报告/html/history/retry-trend.json
  62. 34 0
      测试报告/html/index.html
  63. 276 0
      测试报告/html/plugin/behaviors/index.js
  64. 160 0
      测试报告/html/plugin/packages/index.js
  65. 200 0
      测试报告/html/plugin/screen-diff/index.js
  66. 30 0
      测试报告/html/plugin/screen-diff/styles.css
  67. 3 0
      测试报告/html/styles.css
  68. 1 0
      测试报告/html/widgets/behaviors.json
  69. 1 0
      测试报告/html/widgets/categories-trend.json
  70. 1 0
      测试报告/html/widgets/categories.json
  71. 1 0
      测试报告/html/widgets/duration-trend.json
  72. 1 0
      测试报告/html/widgets/duration.json
  73. 1 0
      测试报告/html/widgets/environment.json
  74. 1 0
      测试报告/html/widgets/executors.json
  75. 1 0
      测试报告/html/widgets/history-trend.json
  76. 1 0
      测试报告/html/widgets/launch.json
  77. 1 0
      测试报告/html/widgets/retry-trend.json
  78. 1 0
      测试报告/html/widgets/severity.json
  79. 1 0
      测试报告/html/widgets/status-chart.json
  80. 1 0
      测试报告/html/widgets/suites.json
  81. 1 0
      测试报告/html/widgets/summary.json
  82. 1 0
      测试报告/json/1319e870-d015-4de8-8867-7196140be8b0-result.json
  83. 1 0
      测试报告/json/145b5286-16c6-4e9e-b61a-eb594b85ad5e-container.json
  84. 1 0
      测试报告/json/19bfc690-cdf0-472c-973b-cc97da821fb4-container.json
  85. 0 0
      测试报告/json/1e52bc85-092a-4469-9a9f-3ceb345323a7-result.json
  86. 1 0
      测试报告/json/37cbe19a-02fe-4cbf-8de7-258e220ebb0d-attachment.txt
  87. 1 0
      测试报告/json/508c9f22-e238-4e77-b1df-d960423fffb6-attachment.txt
  88. 1 0
      测试报告/json/53625ae8-f88a-4824-a792-c4c5c64e60d5-container.json
  89. 1 0
      测试报告/json/5d35f64b-fcb1-4967-a6fc-471be6b35145-attachment.txt
  90. 1 0
      测试报告/json/86bb6e2c-9637-477f-8b49-7b52d59c9927-result.json
  91. 0 0
      测试报告/json/a8d1b615-69aa-4762-8e87-1a04619266e1-result.json
  92. 1 0
      测试报告/json/a95a3161-dc98-4d67-9755-9f19eaaa8c94-result.json
  93. 1 0
      测试报告/json/b2de3312-f3ba-4c54-b6c4-d3942450ec7a-attachment.txt
  94. 1 0
      测试报告/json/b7191d7c-aff8-4054-8fd7-9a459aee51fc-container.json
  95. 1 0
      测试报告/json/c4dbaaa2-cbbf-43ae-838b-6fa512a88bc8-attachment.txt
  96. 1 0
      测试报告/json/e12b36f8-a994-4125-b10b-28275edcbefb-container.json
  97. 1 0
      测试报告/json/e6a8a9da-99f5-4b2a-8221-6651528dfa7f-result.json
  98. 1 0
      测试报告/json/e982a72e-5805-493c-ab70-523c094cf201-attachment.txt

BIN
.DS_Store


+ 35 - 0
.idea/copilotDiffState.xml

@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="CopilotDiffPersistence">
+    <option name="pendingDiffs">
+      <map>
+        <entry key="$PROJECT_DIR$/conftest.py">
+          <value>
+            <PendingDiffInfo>
+              <option name="filePath" value="$PROJECT_DIR$/conftest.py" />
+              <option name="updatedContent" value="import os&#10;&#10;def pytest_sessionfinish(session, exitstatus):&#10;    # pytest 结束后自动生成 allure 报告&#10;    os.system(&quot;allure generate 测试报告 -o 测试报告/html --clean&quot;)&#10;" />
+            </PendingDiffInfo>
+          </value>
+        </entry>
+        <entry key="$PROJECT_DIR$/demo/main/test_a.py">
+          <value>
+            <PendingDiffInfo>
+              <option name="filePath" value="$PROJECT_DIR$/demo/main/test_a.py" />
+              <option name="originalContent" value="import pytest,json&#10;import jsonpath&#10;from demo.utils import get_excel as gexcel&#10;from demo.utils.send import ApiClient&#10;from demo.utils.write_log import write_log&#10;from demo.dic.global_value import GlobalInfo&#10;client = ApiClient()&#10;&#10;@pytest.mark.parametrize(&quot;case_info&quot;, gexcel.get_excel(&quot;demo&quot;, 0))&#10;def test_case(case_info):&#10;    #初始化全局变量&#10;    dic = GlobalInfo().show_info()&#10;&#10;    # 拼接请求参数&#10;    url = case_info[&quot;url&quot;]&#10;    method = case_info[&quot;method&quot;]&#10;    headers = eval(case_info[&quot;headers&quot;]) if case_info[&quot;headers&quot;] else {}&#10;    params = eval(case_info[&quot;params&quot;]) if case_info[&quot;params&quot;] else {}&#10;    data = eval(case_info[&quot;data&quot;]) if case_info[&quot;data&quot;] else {}&#10;    _json = eval(case_info[&quot;json&quot;]) if case_info[&quot;json&quot;] else {}&#10;&#10;    # 写日志&#10;    write_log(&quot;url&quot;,url)&#10;    write_log(&quot;headers&quot;,headers)&#10;    write_log(&quot;params&quot;,params)&#10;    write_log(&quot;data&quot;,data)&#10;&#10;    # 前置操作&#10;&#10;&#10;    res = client.send_request(method, url, headers=headers, params=params, data=data, json=_json)&#10;    write_log(&quot;respose&quot;, res.json())&#10;&#10;&#10;    # assert res.status_code == 200&#10;&#10;&#10;    # 后置操作&#10;    ## 提取变量&#10;    if case_info[&quot;提取变量&quot;] != &quot;&quot;:&#10;        vars_to_extract = [v.strip() for v in case_info[&quot;提取变量&quot;].split(&quot;,&quot;) if v.strip()]&#10;        for var in vars_to_extract:&#10;            value = jsonpath.jsonpath(res.json(), f&quot;$..{var}&quot;)&#10;            if value:&#10;                GlobalInfo().set_info(var, value[0])&#10;        write_log(&quot;globalInfo.txt&quot;, json.dumps(GlobalInfo().show_info()))&#10;&#10;    print(_json)" />
+              <option name="updatedContent" value="import pytest, json&#10;import jsonpath&#10;from demo.utils import get_excel as gexcel&#10;from demo.utils.send import ApiClient&#10;from demo.utils.write_log import write_log&#10;from demo.dic.global_value import GlobalInfo&#10;client = ApiClient()&#10;&#10;@pytest.mark.parametrize(&quot;case_info&quot;, gexcel.get_excel(&quot;demo&quot;, 0))&#10;def test_case(case_info):&#10;    #初始化全局变量&#10;    dic = GlobalInfo().show_info()&#10;&#10;    # 拼接请求参数&#10;    url = case_info[&quot;url&quot;]&#10;    method = case_info[&quot;method&quot;]&#10;    headers = eval(case_info[&quot;headers&quot;]) if case_info[&quot;headers&quot;] else {}&#10;    params = eval(case_info[&quot;params&quot;]) if case_info[&quot;params&quot;] else {}&#10;    data = eval(case_info[&quot;data&quot;]) if case_info[&quot;data&quot;] else {}&#10;    _json = eval(case_info[&quot;json&quot;]) if case_info[&quot;json&quot;] else {}&#10;&#10;    # 写日志&#10;    write_log(&quot;url&quot;,url)&#10;    write_log(&quot;headers&quot;,headers)&#10;    write_log(&quot;params&quot;,params)&#10;    write_log(&quot;data&quot;,data)&#10;&#10;    # 前置操作&#10;&#10;&#10;    res = client.send_request(method, url, headers=headers, params=params, data=data, json=_json)&#10;    write_log(&quot;respose&quot;, res.json())&#10;&#10;&#10;    # assert res.status_code == 200&#10;&#10;&#10;    # 后置操作&#10;    ## 提取变量&#10;    if case_info[&quot;提取变量&quot;] != &quot;&quot;:&#10;        vars_to_extract = [v.strip() for v in case_info[&quot;提取变量&quot;].split(&quot;,&quot;) if v.strip()]&#10;        for var in vars_to_extract:&#10;            value = jsonpath.jsonpath(res.json(), f&quot;$..{var}&quot;)&#10;            if value:&#10;                GlobalInfo().set_info(var, value[0])&#10;        write_log(&quot;globalInfo.txt&quot;, json.dumps(GlobalInfo().show_info()))&#10;&#10;    print(_json)" />
+            </PendingDiffInfo>
+          </value>
+        </entry>
+        <entry key="$PROJECT_DIR$/demo/utils/get_excel.py">
+          <value>
+            <PendingDiffInfo>
+              <option name="filePath" value="$PROJECT_DIR$/demo/utils/get_excel.py" />
+              <option name="originalContent" value="import pandas as pd&#10;from pathlib import Path&#10;from . import write_log as log&#10;def get_excel(file_name, sheet_name=0):&#10;    &quot;&quot;&quot;&#10;    读取excel文件目录下.xlsx文件内容到DataFrame,并用空字符串填充缺失值&#10;    :param file_name:&#10;    :param sheet_name: 工作表名称或索引,默认读取第一个工作表&#10;    :return: 填充缺失值后的DataFrame&#10;    &quot;&quot;&quot;&#10;&#10;&#10;    project_root = Path(__file__).parent.parent&#10;    # 拼接 demo/demo.xlsx 路径&#10;    file_path = project_root / &quot;excel&quot; / (file_name+&quot;.xlsx&quot;)&#10;&#10;    df = pd.read_excel(file_path, sheet_name=sheet_name)&#10;    df = df.fillna(&quot;&quot;)  # 用空字符串填充缺失值&#10;    df = df.to_dict(orient=&quot;records&quot;)&#10;    # print(df)&#10;&#10;    log.clear_log(file_name)&#10;    log.write_log(file_name, df)&#10;    return df&#10;&#10;# print(file_path)" />
+              <option name="updatedContent" value="import pandas as pd&#10;from pathlib import Path&#10;from . import write_log as log&#10;def get_excel(file_name, sheet_name=0):&#10;    &quot;&quot;&quot;&#10;    读取excel文件目录下.xlsx文件内容到DataFrame,并用空字符串填充缺失值&#10;    :param file_name:&#10;    :param sheet_name: 工作表名称或索引,默认读取第一个工作表&#10;    :return: 填充缺失值后的DataFrame&#10;    &quot;&quot;&quot;&#10;&#10;&#10;    project_root = Path(__file__).parent.parent&#10;    # 拼接 demo/demo.xlsx 路径&#10;    file_path = project_root / &quot;excel&quot; / (file_name+&quot;.xlsx&quot;)&#10;&#10;    df = pd.read_excel(file_path, sheet_name=sheet_name)&#10;    df = df.fillna(&quot;&quot;)  # 用空字符串填充缺失值&#10;    df = df.to_dict(orient=&quot;records&quot;)&#10;    # print(df)&#10;&#10;    log.clear_log(file_name)&#10;    log.write_log(file_name, df)&#10;    return df&#10;&#10;# print(file_path)" />
+            </PendingDiffInfo>
+          </value>
+        </entry>
+      </map>
+    </option>
+  </component>
+</project>

+ 69 - 22
.idea/workspace.xml

@@ -4,23 +4,23 @@
     <option name="autoReloadType" value="SELECTIVE" />
     <option name="autoReloadType" value="SELECTIVE" />
   </component>
   </component>
   <component name="ChangeListManager">
   <component name="ChangeListManager">
-    <list default="true" id="07cc7c5b-0297-4ba8-b7e8-ad9e2f5c9a81" name="Changes" comment="">
-      <change afterPath="$PROJECT_DIR$/.idea/Pytest.iml" afterDir="false" />
-      <change afterPath="$PROJECT_DIR$/.idea/inspectionProfiles/profiles_settings.xml" afterDir="false" />
-      <change afterPath="$PROJECT_DIR$/.idea/modules.xml" afterDir="false" />
-      <change afterPath="$PROJECT_DIR$/.idea/vcs.xml" afterDir="false" />
-      <change afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
-      <change afterPath="$PROJECT_DIR$/demo/dic/global_value.py" afterDir="false" />
-      <change afterPath="$PROJECT_DIR$/demo/excel/jsom.xlxs" afterDir="false" />
-      <change afterPath="$PROJECT_DIR$/demo/main.py" afterDir="false" />
-      <change afterPath="$PROJECT_DIR$/demo/main/__init__.py" afterDir="false" />
-      <change afterPath="$PROJECT_DIR$/demo/main/test_a.py" afterDir="false" />
-      <change afterPath="$PROJECT_DIR$/demo/main/test_test.py" afterDir="false" />
-      <change afterPath="$PROJECT_DIR$/demo/pytest.ini" afterDir="false" />
-      <change afterPath="$PROJECT_DIR$/demo/requirements.txt" afterDir="false" />
-      <change afterPath="$PROJECT_DIR$/demo/utils/get_excel.py" afterDir="false" />
-      <change afterPath="$PROJECT_DIR$/demo/utils/send.py" afterDir="false" />
-      <change afterPath="$PROJECT_DIR$/demo/utils/write_log.py" afterDir="false" />
+    <list default="true" id="07cc7c5b-0297-4ba8-b7e8-ad9e2f5c9a81" name="Changes" comment="init">
+      <change afterPath="$PROJECT_DIR$/.idea/copilotDiffState.xml" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/pytest.ini" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/demo/log/data.txt" beforeDir="false" afterPath="$PROJECT_DIR$/demo/log/data.txt" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/demo/log/globalInfo.txt.txt" beforeDir="false" afterPath="$PROJECT_DIR$/demo/log/globalInfo.txt.txt" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/demo/log/headers.txt" beforeDir="false" afterPath="$PROJECT_DIR$/demo/log/headers.txt" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/demo/log/params.txt" beforeDir="false" afterPath="$PROJECT_DIR$/demo/log/params.txt" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/demo/log/respose.txt" beforeDir="false" afterPath="$PROJECT_DIR$/demo/log/respose.txt" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/demo/log/url.txt" beforeDir="false" afterPath="$PROJECT_DIR$/demo/log/url.txt" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/demo/main.py" beforeDir="false" afterPath="$PROJECT_DIR$/main.py" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/demo/main/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/__init__.py" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/demo/main/test_a.py" beforeDir="false" afterPath="$PROJECT_DIR$/demo/test_a.py" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/demo/main/test_test.py" beforeDir="false" afterPath="$PROJECT_DIR$/demo/test_test.py" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/demo/pytest.ini" beforeDir="false" afterPath="$PROJECT_DIR$/conftest.py" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/demo/requirements.txt" beforeDir="false" afterPath="$PROJECT_DIR$/requirements.txt" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/demo/utils/get_excel.py" beforeDir="false" afterPath="$PROJECT_DIR$/demo/utils/get_excel.py" afterDir="false" />
     </list>
     </list>
     <option name="SHOW_DIALOG" value="false" />
     <option name="SHOW_DIALOG" value="false" />
     <option name="HIGHLIGHT_CONFLICTS" value="true" />
     <option name="HIGHLIGHT_CONFLICTS" value="true" />
@@ -54,9 +54,11 @@
     "Python tests.Python tests for demo.test_a.test_get_excel.executor": "Run",
     "Python tests.Python tests for demo.test_a.test_get_excel.executor": "Run",
     "Python tests.Python tests in test_a.py.executor": "Run",
     "Python tests.Python tests in test_a.py.executor": "Run",
     "Python.get_excel.executor": "Run",
     "Python.get_excel.executor": "Run",
+    "Python.main.executor": "Run",
     "RunOnceActivity.ShowReadmeOnStart": "true",
     "RunOnceActivity.ShowReadmeOnStart": "true",
     "RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252": "true",
     "RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252": "true",
     "RunOnceActivity.git.unshallow": "true",
     "RunOnceActivity.git.unshallow": "true",
+    "SHARE_PROJECT_CONFIGURATION_FILES": "true",
     "git-widget-placeholder": "main",
     "git-widget-placeholder": "main",
     "last_opened_file_path": "/Users/xxh/test/Pytest",
     "last_opened_file_path": "/Users/xxh/test/Pytest",
     "settings.editor.selected.configurable": "terminal"
     "settings.editor.selected.configurable": "terminal"
@@ -67,12 +69,13 @@
       <recent name="$PROJECT_DIR$" />
       <recent name="$PROJECT_DIR$" />
     </key>
     </key>
     <key name="MoveFile.RECENT_KEYS">
     <key name="MoveFile.RECENT_KEYS">
+      <recent name="$PROJECT_DIR$" />
       <recent name="$PROJECT_DIR$/demo" />
       <recent name="$PROJECT_DIR$/demo" />
       <recent name="$PROJECT_DIR$/demo/main" />
       <recent name="$PROJECT_DIR$/demo/main" />
       <recent name="$PROJECT_DIR$/excel" />
       <recent name="$PROJECT_DIR$/excel" />
     </key>
     </key>
   </component>
   </component>
-  <component name="RunManager" selected="Python tests.Python tests in test_a.py">
+  <component name="RunManager" selected="Python.main">
     <configuration name="get_excel" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
     <configuration name="get_excel" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
       <module name="Pytest" />
       <module name="Pytest" />
       <option name="ENV_FILES" value="" />
       <option name="ENV_FILES" value="" />
@@ -95,7 +98,29 @@
       <option name="INPUT_FILE" value="" />
       <option name="INPUT_FILE" value="" />
       <method v="2" />
       <method v="2" />
     </configuration>
     </configuration>
-    <configuration name="Python tests for demo.main.test_a" type="tests" factoryName="Autodetect" temporary="true" nameIsGenerated="true">
+    <configuration name="main" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
+      <module name="Pytest" />
+      <option name="ENV_FILES" value="" />
+      <option name="INTERPRETER_OPTIONS" value="" />
+      <option name="PARENT_ENVS" value="true" />
+      <envs>
+        <env name="PYTHONUNBUFFERED" value="1" />
+      </envs>
+      <option name="SDK_HOME" value="" />
+      <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
+      <option name="IS_MODULE_SDK" value="true" />
+      <option name="ADD_CONTENT_ROOTS" value="true" />
+      <option name="ADD_SOURCE_ROOTS" value="true" />
+      <option name="SCRIPT_NAME" value="$PROJECT_DIR$/main.py" />
+      <option name="PARAMETERS" value="" />
+      <option name="SHOW_COMMAND_LINE" value="false" />
+      <option name="EMULATE_TERMINAL" value="false" />
+      <option name="MODULE_MODE" value="false" />
+      <option name="REDIRECT_INPUT" value="false" />
+      <option name="INPUT_FILE" value="" />
+      <method v="2" />
+    </configuration>
+    <configuration name="Python tests for demo.test_a" type="tests" factoryName="Autodetect" temporary="true" nameIsGenerated="true">
       <module name="Pytest" />
       <module name="Pytest" />
       <option name="ENV_FILES" value="" />
       <option name="ENV_FILES" value="" />
       <option name="INTERPRETER_OPTIONS" value="" />
       <option name="INTERPRETER_OPTIONS" value="" />
@@ -106,7 +131,7 @@
       <option name="ADD_CONTENT_ROOTS" value="true" />
       <option name="ADD_CONTENT_ROOTS" value="true" />
       <option name="ADD_SOURCE_ROOTS" value="true" />
       <option name="ADD_SOURCE_ROOTS" value="true" />
       <option name="_new_additionalArguments" value="&quot;&quot;" />
       <option name="_new_additionalArguments" value="&quot;&quot;" />
-      <option name="_new_target" value="&quot;demo.main.test_a&quot;" />
+      <option name="_new_target" value="&quot;demo.test_a&quot;" />
       <option name="_new_targetType" value="&quot;PYTHON&quot;" />
       <option name="_new_targetType" value="&quot;PYTHON&quot;" />
       <method v="2" />
       <method v="2" />
     </configuration>
     </configuration>
@@ -121,14 +146,15 @@
       <option name="ADD_CONTENT_ROOTS" value="true" />
       <option name="ADD_CONTENT_ROOTS" value="true" />
       <option name="ADD_SOURCE_ROOTS" value="true" />
       <option name="ADD_SOURCE_ROOTS" value="true" />
       <option name="_new_additionalArguments" value="&quot;&quot;" />
       <option name="_new_additionalArguments" value="&quot;&quot;" />
-      <option name="_new_target" value="&quot;$PROJECT_DIR$/demo/main/test_a.py&quot;" />
+      <option name="_new_target" value="&quot;$PROJECT_DIR$/demo/test_a.py&quot;" />
       <option name="_new_targetType" value="&quot;PATH&quot;" />
       <option name="_new_targetType" value="&quot;PATH&quot;" />
       <method v="2" />
       <method v="2" />
     </configuration>
     </configuration>
     <recent_temporary>
     <recent_temporary>
       <list>
       <list>
+        <item itemvalue="Python.main" />
         <item itemvalue="Python tests.Python tests in test_a.py" />
         <item itemvalue="Python tests.Python tests in test_a.py" />
-        <item itemvalue="Python tests.Python tests for demo.main.test_a" />
+        <item itemvalue="Python tests.Python tests for demo.test_a" />
         <item itemvalue="Python.get_excel" />
         <item itemvalue="Python.get_excel" />
       </list>
       </list>
     </recent_temporary>
     </recent_temporary>
@@ -148,6 +174,27 @@
       <option name="presentableId" value="Default" />
       <option name="presentableId" value="Default" />
       <updated>1760625141848</updated>
       <updated>1760625141848</updated>
     </task>
     </task>
+    <task id="LOCAL-00001" summary="init">
+      <option name="closed" value="true" />
+      <created>1760634763405</created>
+      <option name="number" value="00001" />
+      <option name="presentableId" value="LOCAL-00001" />
+      <option name="project" value="LOCAL" />
+      <updated>1760634763406</updated>
+    </task>
+    <task id="LOCAL-00002" summary="init">
+      <option name="closed" value="true" />
+      <created>1760634781406</created>
+      <option name="number" value="00002" />
+      <option name="presentableId" value="LOCAL-00002" />
+      <option name="project" value="LOCAL" />
+      <updated>1760634781406</updated>
+    </task>
+    <option name="localTasksCounter" value="3" />
     <servers />
     <servers />
   </component>
   </component>
+  <component name="VcsManagerConfiguration">
+    <MESSAGE value="init" />
+    <option name="LAST_COMMIT_MESSAGE" value="init" />
+  </component>
 </project>
 </project>

+ 0 - 0
demo/main/__init__.py → __init__.py


BIN
__pycache__/__init__.cpython-311.pyc


BIN
__pycache__/conftest.cpython-311-pytest-8.4.2.pyc


+ 6 - 0
conftest.py

@@ -0,0 +1,6 @@
+import os
+
+def pytest_sessionfinish(session, exitstatus):
+    # pytest 结束后自动生成 allure 报告
+    os.system("allure generate 测试报告 -o 测试报告/html --clean")
+

BIN
demo/.DS_Store


BIN
demo/__pycache__/test_a.cpython-311-pytest-8.4.2.pyc


BIN
demo/__pycache__/test_test.cpython-311-pytest-8.4.2.pyc


BIN
demo/dic/__pycache__/global_value.cpython-311.pyc


+ 0 - 10
demo/log/data.txt

@@ -3,13 +3,3 @@ INFO:root:{}
 INFO:root:{}
 INFO:root:{}
 INFO:root:{}
 INFO:root:{}
 INFO:root:{}
 INFO:root:{}
-INFO:root:{}
-INFO:root:{}
-INFO:root:{}
-INFO:root:{}
-INFO:root:{}
-INFO:root:{}
-INFO:root:{}
-INFO:root:{}
-INFO:root:{}
-INFO:root:{}

+ 3 - 9
demo/log/globalInfo.txt.txt

@@ -1,9 +1,3 @@
-INFO:root:{"token": "eyJhbGciOiJIUzI1NiJ9.eyJyb2xlIjoiVVNFUiIsImVtYWlsIjoiYWxsbm90aWNlQHFxLmNvbSIsInN1YiI6IjIiLCJpYXQiOjE3NjA2MzQxMjksImV4cCI6MTc2MDcyMDUyOX0.ma5EcWp0lak_0d6NvfW_fS7KH6bSB9QP0gQrbIvyzug", "code": 200}
-INFO:root:{"token": "eyJhbGciOiJIUzI1NiJ9.eyJyb2xlIjoiVVNFUiIsImVtYWlsIjoiYWxsbm90aWNlQHFxLmNvbSIsInN1YiI6IjIiLCJpYXQiOjE3NjA2MzQxMjksImV4cCI6MTc2MDcyMDUyOX0.ma5EcWp0lak_0d6NvfW_fS7KH6bSB9QP0gQrbIvyzug", "code": 200}
-INFO:root:{"token": "eyJhbGciOiJIUzI1NiJ9.eyJyb2xlIjoiVVNFUiIsImVtYWlsIjoiYWxsbm90aWNlQHFxLmNvbSIsInN1YiI6IjIiLCJpYXQiOjE3NjA2MzQxMjksImV4cCI6MTc2MDcyMDUyOX0.ma5EcWp0lak_0d6NvfW_fS7KH6bSB9QP0gQrbIvyzug", "code": 200}
-INFO:root:{"token": "eyJhbGciOiJIUzI1NiJ9.eyJyb2xlIjoiVVNFUiIsImVtYWlsIjoiYWxsbm90aWNlQHFxLmNvbSIsInN1YiI6IjIiLCJpYXQiOjE3NjA2MzQxNTMsImV4cCI6MTc2MDcyMDU1M30.bw9YZacueSfypzldsy_KvTlLp0kWGJxK1SW2qmDGpME", "code": 200}
-INFO:root:{"token": "eyJhbGciOiJIUzI1NiJ9.eyJyb2xlIjoiVVNFUiIsImVtYWlsIjoiYWxsbm90aWNlQHFxLmNvbSIsInN1YiI6IjIiLCJpYXQiOjE3NjA2MzQxNTMsImV4cCI6MTc2MDcyMDU1M30.bw9YZacueSfypzldsy_KvTlLp0kWGJxK1SW2qmDGpME", "code": 200}
-INFO:root:{"token": "eyJhbGciOiJIUzI1NiJ9.eyJyb2xlIjoiVVNFUiIsImVtYWlsIjoiYWxsbm90aWNlQHFxLmNvbSIsInN1YiI6IjIiLCJpYXQiOjE3NjA2MzQxNTMsImV4cCI6MTc2MDcyMDU1M30.bw9YZacueSfypzldsy_KvTlLp0kWGJxK1SW2qmDGpME", "code": 200}
-INFO:root:{"token": "eyJhbGciOiJIUzI1NiJ9.eyJyb2xlIjoiVVNFUiIsImVtYWlsIjoiYWxsbm90aWNlQHFxLmNvbSIsInN1YiI6IjIiLCJpYXQiOjE3NjA2MzQ2OTEsImV4cCI6MTc2MDcyMTA5MX0.38r-MAnKXS_lSBE44q7pVA4UlL9j7XHY3su_jkXRJX8", "code": 200}
-INFO:root:{"token": "eyJhbGciOiJIUzI1NiJ9.eyJyb2xlIjoiVVNFUiIsImVtYWlsIjoiYWxsbm90aWNlQHFxLmNvbSIsInN1YiI6IjIiLCJpYXQiOjE3NjA2MzQ2OTEsImV4cCI6MTc2MDcyMTA5MX0.38r-MAnKXS_lSBE44q7pVA4UlL9j7XHY3su_jkXRJX8", "code": 200}
-INFO:root:{"token": "eyJhbGciOiJIUzI1NiJ9.eyJyb2xlIjoiVVNFUiIsImVtYWlsIjoiYWxsbm90aWNlQHFxLmNvbSIsInN1YiI6IjIiLCJpYXQiOjE3NjA2MzQ2OTEsImV4cCI6MTc2MDcyMTA5MX0.38r-MAnKXS_lSBE44q7pVA4UlL9j7XHY3su_jkXRJX8", "code": 200}
+INFO:root:{"token": "eyJhbGciOiJIUzI1NiJ9.eyJyb2xlIjoiVVNFUiIsImVtYWlsIjoiYWxsbm90aWNlQHFxLmNvbSIsInN1YiI6IjIiLCJpYXQiOjE3NjA2MzgzMjYsImV4cCI6MTc2MDcyNDcyNn0.TjcbMY_KNDHS3bsHzWrSrEc3_Je7U38zwyyav9fYZaA", "code": 200}
+INFO:root:{"token": "eyJhbGciOiJIUzI1NiJ9.eyJyb2xlIjoiVVNFUiIsImVtYWlsIjoiYWxsbm90aWNlQHFxLmNvbSIsInN1YiI6IjIiLCJpYXQiOjE3NjA2MzgzMjYsImV4cCI6MTc2MDcyNDcyNn0.TjcbMY_KNDHS3bsHzWrSrEc3_Je7U38zwyyav9fYZaA", "code": 200}
+INFO:root:{"token": "eyJhbGciOiJIUzI1NiJ9.eyJyb2xlIjoiVVNFUiIsImVtYWlsIjoiYWxsbm90aWNlQHFxLmNvbSIsInN1YiI6IjIiLCJpYXQiOjE3NjA2MzgzMjYsImV4cCI6MTc2MDcyNDcyNn0.TjcbMY_KNDHS3bsHzWrSrEc3_Je7U38zwyyav9fYZaA", "code": 200}

+ 0 - 10
demo/log/headers.txt

@@ -3,13 +3,3 @@ INFO:root:{'Content-Type': 'application/json', 'Authorization': 'Bearer ${token}
 INFO:root:{'Content-Type': 'application/json', 'Authorization': 'Bearer ${token}'}
 INFO:root:{'Content-Type': 'application/json', 'Authorization': 'Bearer ${token}'}
 INFO:root:{'Content-Type': 'application/json', 'Authorization': 'Bearer ${token}'}
 INFO:root:{'Content-Type': 'application/json', 'Authorization': 'Bearer ${token}'}
 INFO:root:{'Content-Type': 'application/json', 'Authorization': 'Bearer ${token}'}
 INFO:root:{'Content-Type': 'application/json', 'Authorization': 'Bearer ${token}'}
-INFO:root:{'Content-Type': 'application/json'}
-INFO:root:{'Content-Type': 'application/json', 'Authorization': 'Bearer ${token}'}
-INFO:root:{'Content-Type': 'application/json', 'Authorization': 'Bearer ${token}'}
-INFO:root:{'Content-Type': 'application/json', 'Authorization': 'Bearer ${token}'}
-INFO:root:{'Content-Type': 'application/json', 'Authorization': 'Bearer ${token}'}
-INFO:root:{'Content-Type': 'application/json'}
-INFO:root:{'Content-Type': 'application/json', 'Authorization': 'Bearer ${token}'}
-INFO:root:{'Content-Type': 'application/json', 'Authorization': 'Bearer ${token}'}
-INFO:root:{'Content-Type': 'application/json', 'Authorization': 'Bearer ${token}'}
-INFO:root:{'Content-Type': 'application/json', 'Authorization': 'Bearer ${token}'}

+ 0 - 0
demo/pytest.ini → demo/log/json.txt


+ 0 - 10
demo/log/params.txt

@@ -3,13 +3,3 @@ INFO:root:{}
 INFO:root:{}
 INFO:root:{}
 INFO:root:{}
 INFO:root:{}
 INFO:root:{}
 INFO:root:{}
-INFO:root:{}
-INFO:root:{}
-INFO:root:{}
-INFO:root:{}
-INFO:root:{}
-INFO:root:{}
-INFO:root:{}
-INFO:root:{}
-INFO:root:{}
-INFO:root:{}

+ 5 - 15
demo/log/respose.txt

@@ -1,15 +1,5 @@
-INFO:root:{'code': 200, 'message': '登录成功', 'data': {'id': 2, 'username': 'allnotice', 'email': 'allnotice@qq.com', 'token': 'eyJhbGciOiJIUzI1NiJ9.eyJyb2xlIjoiVVNFUiIsImVtYWlsIjoiYWxsbm90aWNlQHFxLmNvbSIsInN1YiI6IjIiLCJpYXQiOjE3NjA2MzQxMjksImV4cCI6MTc2MDcyMDUyOX0.ma5EcWp0lak_0d6NvfW_fS7KH6bSB9QP0gQrbIvyzug'}, 'timestamp': '2025-10-17T01:02:09.697293845'}
-INFO:root:{'code': 401, 'message': '未授权:Full authentication is required to access this resource', 'data': None, 'timestamp': '2025-10-17T01:02:09.728199928'}
-INFO:root:{'code': 401, 'message': '未授权:Full authentication is required to access this resource', 'data': None, 'timestamp': '2025-10-17T01:02:09.759111182'}
-INFO:root:{'code': 401, 'message': '未授权:Full authentication is required to access this resource', 'data': None, 'timestamp': '2025-10-17T01:02:09.792139584'}
-INFO:root:{'code': 401, 'message': '未授权:Full authentication is required to access this resource', 'data': None, 'timestamp': '2025-10-17T01:02:09.821487583'}
-INFO:root:{'code': 200, 'message': '登录成功', 'data': {'id': 2, 'username': 'allnotice', 'email': 'allnotice@qq.com', 'token': 'eyJhbGciOiJIUzI1NiJ9.eyJyb2xlIjoiVVNFUiIsImVtYWlsIjoiYWxsbm90aWNlQHFxLmNvbSIsInN1YiI6IjIiLCJpYXQiOjE3NjA2MzQxNTMsImV4cCI6MTc2MDcyMDU1M30.bw9YZacueSfypzldsy_KvTlLp0kWGJxK1SW2qmDGpME'}, 'timestamp': '2025-10-17T01:02:33.851599883'}
-INFO:root:{'code': 401, 'message': '未授权:Full authentication is required to access this resource', 'data': None, 'timestamp': '2025-10-17T01:02:33.880589996'}
-INFO:root:{'code': 401, 'message': '未授权:Full authentication is required to access this resource', 'data': None, 'timestamp': '2025-10-17T01:02:33.912406827'}
-INFO:root:{'code': 401, 'message': '未授权:Full authentication is required to access this resource', 'data': None, 'timestamp': '2025-10-17T01:02:33.941766276'}
-INFO:root:{'code': 401, 'message': '未授权:Full authentication is required to access this resource', 'data': None, 'timestamp': '2025-10-17T01:02:33.973952953'}
-INFO:root:{'code': 200, 'message': '登录成功', 'data': {'id': 2, 'username': 'allnotice', 'email': 'allnotice@qq.com', 'token': 'eyJhbGciOiJIUzI1NiJ9.eyJyb2xlIjoiVVNFUiIsImVtYWlsIjoiYWxsbm90aWNlQHFxLmNvbSIsInN1YiI6IjIiLCJpYXQiOjE3NjA2MzQ2OTEsImV4cCI6MTc2MDcyMTA5MX0.38r-MAnKXS_lSBE44q7pVA4UlL9j7XHY3su_jkXRJX8'}, 'timestamp': '2025-10-17T01:11:31.924946824'}
-INFO:root:{'code': 401, 'message': '未授权:Full authentication is required to access this resource', 'data': None, 'timestamp': '2025-10-17T01:11:31.958876374'}
-INFO:root:{'code': 401, 'message': '未授权:Full authentication is required to access this resource', 'data': None, 'timestamp': '2025-10-17T01:11:31.987282394'}
-INFO:root:{'code': 401, 'message': '未授权:Full authentication is required to access this resource', 'data': None, 'timestamp': '2025-10-17T01:11:32.016665617'}
-INFO:root:{'code': 401, 'message': '未授权:Full authentication is required to access this resource', 'data': None, 'timestamp': '2025-10-17T01:11:32.045064344'}
+INFO:root:{'code': 200, 'message': '登录成功', 'data': {'id': 2, 'username': 'allnotice', 'email': 'allnotice@qq.com', 'token': 'eyJhbGciOiJIUzI1NiJ9.eyJyb2xlIjoiVVNFUiIsImVtYWlsIjoiYWxsbm90aWNlQHFxLmNvbSIsInN1YiI6IjIiLCJpYXQiOjE3NjA2MzgzMjYsImV4cCI6MTc2MDcyNDcyNn0.TjcbMY_KNDHS3bsHzWrSrEc3_Je7U38zwyyav9fYZaA'}, 'timestamp': '2025-10-17T02:12:06.545339978'}
+INFO:root:{'code': 401, 'message': '未授权:Full authentication is required to access this resource', 'data': None, 'timestamp': '2025-10-17T02:12:06.576167229'}
+INFO:root:{'code': 401, 'message': '未授权:Full authentication is required to access this resource', 'data': None, 'timestamp': '2025-10-17T02:12:06.604583015'}
+INFO:root:{'code': 401, 'message': '未授权:Full authentication is required to access this resource', 'data': None, 'timestamp': '2025-10-17T02:12:06.636687083'}
+INFO:root:{'code': 401, 'message': '未授权:Full authentication is required to access this resource', 'data': None, 'timestamp': '2025-10-17T02:12:06.664425563'}

+ 0 - 10
demo/log/url.txt

@@ -3,13 +3,3 @@ INFO:root:http://106.52.242.71:8001/api/user/subdomains/register
 INFO:root:http://106.52.242.71:8001/api/user/dns-records
 INFO:root:http://106.52.242.71:8001/api/user/dns-records
 INFO:root:http://106.52.242.71:8001/api/user/dns-records/modify
 INFO:root:http://106.52.242.71:8001/api/user/dns-records/modify
 INFO:root:http://106.52.242.71:8001/api/user/dns-records/delete
 INFO:root:http://106.52.242.71:8001/api/user/dns-records/delete
-INFO:root:http://106.52.242.71:8001/api/auth/login
-INFO:root:http://106.52.242.71:8001/api/user/subdomains/register
-INFO:root:http://106.52.242.71:8001/api/user/dns-records
-INFO:root:http://106.52.242.71:8001/api/user/dns-records/modify
-INFO:root:http://106.52.242.71:8001/api/user/dns-records/delete
-INFO:root:http://106.52.242.71:8001/api/auth/login
-INFO:root:http://106.52.242.71:8001/api/user/subdomains/register
-INFO:root:http://106.52.242.71:8001/api/user/dns-records
-INFO:root:http://106.52.242.71:8001/api/user/dns-records/modify
-INFO:root:http://106.52.242.71:8001/api/user/dns-records/delete

+ 0 - 3
demo/main.py

@@ -1,3 +0,0 @@
-import pytest
-
-pytest.main()

BIN
demo/main/__pycache__/test_a.cpython-311-pytest-8.4.2.pyc


BIN
demo/main/__pycache__/test_test.cpython-311-pytest-8.4.2.pyc


+ 23 - 8
demo/main/test_a.py → demo/test_a.py

@@ -1,11 +1,23 @@
-import pytest,json
+import pytest, json
 import jsonpath
 import jsonpath
-from demo.utils import get_excel as gexcel
-from demo.utils.send import ApiClient
-from demo.utils.write_log import write_log
-from demo.dic.global_value import  GlobalInfo
+from utils import get_excel as gexcel
+from utils.send import ApiClient
+from utils.write_log import write_log,clear_log
+from dic.global_value import GlobalInfo
 client = ApiClient()
 client = ApiClient()
 
 
+clear_log("url")
+clear_log("headers")
+clear_log("params")
+clear_log("data")
+clear_log("json")
+clear_log("respose")
+clear_log("globalInfo.txt")
+@pytest.mark.login
+def test_excel_path():
+    print("login")
+    assert 1 == 1
+
 @pytest.mark.parametrize("case_info", gexcel.get_excel("demo", 0))
 @pytest.mark.parametrize("case_info", gexcel.get_excel("demo", 0))
 def test_case(case_info):
 def test_case(case_info):
     #初始化全局变量
     #初始化全局变量
@@ -19,14 +31,17 @@ def test_case(case_info):
     data = eval(case_info["data"]) if case_info["data"] else {}
     data = eval(case_info["data"]) if case_info["data"] else {}
     _json = eval(case_info["json"]) if case_info["json"] else {}
     _json = eval(case_info["json"]) if case_info["json"] else {}
 
 
+
+
+    # 前置操作
+
+
     # 写日志
     # 写日志
     write_log("url",url)
     write_log("url",url)
     write_log("headers",headers)
     write_log("headers",headers)
     write_log("params",params)
     write_log("params",params)
     write_log("data",data)
     write_log("data",data)
-
-    # 前置操作
-
+    ## 变量替换
 
 
     res = client.send_request(method, url, headers=headers, params=params, data=data, json=_json)
     res = client.send_request(method, url, headers=headers, params=params, data=data, json=_json)
     write_log("respose", res.json())
     write_log("respose", res.json())

+ 0 - 0
demo/main/test_test.py → demo/test_test.py


BIN
demo/utils/__pycache__/__init__.cpython-311.pyc


BIN
demo/utils/__pycache__/get_excel.cpython-311.pyc


BIN
demo/utils/__pycache__/send.cpython-311.pyc


BIN
demo/utils/__pycache__/write_log.cpython-311.pyc


+ 1 - 1
demo/utils/get_excel.py

@@ -1,6 +1,6 @@
 import pandas as pd
 import pandas as pd
 from pathlib import Path
 from pathlib import Path
-import demo.utils.write_log as log
+from . import write_log as log
 def get_excel(file_name, sheet_name=0):
 def get_excel(file_name, sheet_name=0):
     """
     """
     读取excel文件目录下.xlsx文件内容到DataFrame,并用空字符串填充缺失值
     读取excel文件目录下.xlsx文件内容到DataFrame,并用空字符串填充缺失值

+ 7 - 0
main.py

@@ -0,0 +1,7 @@
+import pytest
+import os
+
+pytest.main(['-vs'])
+
+os.system("allure generate  -o 测试报告 -c 测试报告")
+

+ 6 - 0
pytest.ini

@@ -0,0 +1,6 @@
+[pytest]
+
+addopts = --alluredir=测试报告/json --clean-alluredir
+
+markers =
+    login: mark a test as a login test

+ 0 - 0
demo/requirements.txt → requirements.txt


File diff suppressed because it is too large
+ 1 - 0
测试报告/html/app.js


+ 1 - 0
测试报告/html/data/attachments/4652bcf73863b21f.txt

@@ -0,0 +1 @@
+{'subdomain': 'bbbbbbbbbbb', 'domain': 'www.vvvv.host'}

+ 1 - 0
测试报告/html/data/attachments/60dd6b5acbf1a15f.txt

@@ -0,0 +1 @@
+{'subdomainId': '${int.id}', 'name': 'ddd', 'type': 'AAAA', 'value': '2408:826a:361a:2980::63', 'line': '默认', 'ttl': 600, 'remark': '网站主页'}

+ 1 - 0
测试报告/html/data/attachments/976c983772a155ae.txt

@@ -0,0 +1 @@
+{'email': 'allnotice@qq.com', 'password': '22222hua'}

+ 1 - 0
测试报告/html/data/attachments/b930ab66dedfb678.txt

@@ -0,0 +1 @@
+{'recordId': '${int.id}'}

+ 1 - 0
测试报告/html/data/attachments/cf9b61876a1932f1.txt

@@ -0,0 +1 @@
+{'id': '${int.id}', 'type': 'CNAME', 'value': 'sd.com', 'ttl': 600, 'status': 'ENABLE', 'remark': '更新后的网站主页'}

+ 1 - 0
测试报告/html/data/attachments/e2dcd8c4f6b2bfe2.txt

@@ -0,0 +1 @@
+login

+ 2 - 0
测试报告/html/data/behaviors.csv

@@ -0,0 +1,2 @@
+"BROKEN","EPIC","FAILED","FEATURE","PASSED","SKIPPED","STORY","UNKNOWN"
+"0","","0","","6","0","","0"

File diff suppressed because it is too large
+ 0 - 0
测试报告/html/data/behaviors.json


+ 0 - 0
测试报告/html/data/categories.csv


+ 1 - 0
测试报告/html/data/categories.json

@@ -0,0 +1 @@
+{"uid":"4b4757e66a1912dae1a509f688f20b0f","name":"categories","children":[]}

File diff suppressed because it is too large
+ 0 - 0
测试报告/html/data/packages.json


+ 7 - 0
测试报告/html/data/suites.csv

@@ -0,0 +1,7 @@
+"DESCRIPTION","DURATION IN MS","NAME","PARENT SUITE","START TIME","STATUS","STOP TIME","SUB SUITE","SUITE","TEST CLASS","TEST METHOD"
+"","29","test_case[case_info4]","demo","2025-10-17","passed","2025-10-17","","test_a","",""
+"","1","test_excel_path","demo","2025-10-17","passed","2025-10-17","","test_a","",""
+"","30","test_case[case_info3]","demo","2025-10-17","passed","2025-10-17","","test_a","",""
+"","30","test_case[case_info1]","demo","2025-10-17","passed","2025-10-17","","test_a","",""
+"","32","test_case[case_info2]","demo","2025-10-17","passed","2025-10-17","","test_a","",""
+"","118","test_case[case_info0]","demo","2025-10-17","passed","2025-10-17","","test_a","",""

File diff suppressed because it is too large
+ 0 - 0
测试报告/html/data/suites.json


+ 1 - 0
测试报告/html/data/test-cases/3ac100dfa00828b8.json

@@ -0,0 +1 @@
+{"uid":"3ac100dfa00828b8","name":"test_case[case_info0]","fullName":"demo.test_a#test_case","historyId":"72dda26adc4f130d365722908db8f25e","time":{"start":1760638176089,"stop":1760638176207,"duration":118},"status":"passed","flaky":false,"newFailed":false,"newBroken":false,"newPassed":false,"retriesCount":0,"retriesStatusChange":false,"beforeStages":[],"testStage":{"status":"passed","steps":[],"attachments":[{"uid":"976c983772a155ae","name":"stdout","source":"976c983772a155ae.txt","type":"text/plain","size":54}],"parameters":[],"stepsCount":0,"hasContent":true,"shouldDisplayMessage":false,"attachmentsCount":1,"attachmentStep":false},"afterStages":[],"labels":[{"name":"parentSuite","value":"demo"},{"name":"suite","value":"test_a"},{"name":"host","value":"xxhdeMacBook-Air.local"},{"name":"thread","value":"5663-MainThread"},{"name":"framework","value":"pytest"},{"name":"language","value":"cpython3"},{"name":"package","value":"demo.test_a"},{"name":"resultFormat","value":"allure2"}],"parameters":[{"name":"case_info","value":"{'用例编号': 'p1', 'title': '登陆', 'method': 'post', 'url': 'http://106.52.242.71:8001/api/auth/login', 'headers': '{\"Content-Type\":\"application/json\"}', 'params': '', 'json': '{\\n  \"email\": \"allnotice@qq.com\",\\n  \"password\": \"22222hua\"\\n}\\n', 'data': '', '预期响应码': 200, '实际响应码': '', '需要变量': '', '提取变量': 'token,code', '响应实例': ''}"}],"links":[],"hidden":false,"retry":false,"extra":{"severity":"normal","retries":[],"categories":[],"tags":[]},"source":"3ac100dfa00828b8.json","parameterValues":["{'用例编号': 'p1', 'title': '登陆', 'method': 'post', 'url': 'http://106.52.242.71:8001/api/auth/login', 'headers': '{\"Content-Type\":\"application/json\"}', 'params': '', 'json': '{\\n  \"email\": \"allnotice@qq.com\",\\n  \"password\": \"22222hua\"\\n}\\n', 'data': '', '预期响应码': 200, '实际响应码': '', '需要变量': '', '提取变量': 'token,code', '响应实例': ''}"]}

File diff suppressed because it is too large
+ 0 - 0
测试报告/html/data/test-cases/427c56cf8112259b.json


+ 1 - 0
测试报告/html/data/test-cases/6836f8a41e785dbe.json

@@ -0,0 +1 @@
+{"uid":"6836f8a41e785dbe","name":"test_excel_path","fullName":"demo.test_a#test_excel_path","historyId":"c26c784648e6778bbd26f03ee5eea420","time":{"start":1760638176087,"stop":1760638176088,"duration":1},"status":"passed","flaky":false,"newFailed":false,"newBroken":false,"newPassed":false,"retriesCount":0,"retriesStatusChange":false,"beforeStages":[],"testStage":{"status":"passed","steps":[],"attachments":[{"uid":"e2dcd8c4f6b2bfe2","name":"stdout","source":"e2dcd8c4f6b2bfe2.txt","type":"text/plain","size":6}],"parameters":[],"stepsCount":0,"hasContent":true,"shouldDisplayMessage":false,"attachmentsCount":1,"attachmentStep":false},"afterStages":[],"labels":[{"name":"tag","value":"login"},{"name":"parentSuite","value":"demo"},{"name":"suite","value":"test_a"},{"name":"host","value":"xxhdeMacBook-Air.local"},{"name":"thread","value":"5663-MainThread"},{"name":"framework","value":"pytest"},{"name":"language","value":"cpython3"},{"name":"package","value":"demo.test_a"},{"name":"resultFormat","value":"allure2"}],"parameters":[],"links":[],"hidden":false,"retry":false,"extra":{"severity":"normal","retries":[],"categories":[],"tags":["login"]},"source":"6836f8a41e785dbe.json","parameterValues":[]}

File diff suppressed because it is too large
+ 0 - 0
测试报告/html/data/test-cases/862e50ffb623bd70.json


File diff suppressed because it is too large
+ 0 - 0
测试报告/html/data/test-cases/8e03048d4413b43b.json


File diff suppressed because it is too large
+ 0 - 0
测试报告/html/data/test-cases/8f4399de319fe413.json


File diff suppressed because it is too large
+ 0 - 0
测试报告/html/data/timeline.json


+ 13 - 0
测试报告/html/export/influxDbData.txt

@@ -0,0 +1,13 @@
+launch_status failed=0 1760638327000000000
+launch_status broken=0 1760638327000000000
+launch_status passed=6 1760638327000000000
+launch_status skipped=0 1760638327000000000
+launch_status unknown=0 1760638327000000000
+launch_time duration=245 1760638327000000000
+launch_time min_duration=1 1760638327000000000
+launch_time max_duration=118 1760638327000000000
+launch_time sum_duration=240 1760638327000000000
+launch_time start=1760638176087 1760638327000000000
+launch_time stop=1760638176332 1760638327000000000
+launch_retries retries=0 1760638327000000000
+launch_retries run=6 1760638327000000000

+ 10 - 0
测试报告/html/export/mail.html

@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <title>Allure Report summary mail</title>
+</head>
+<body>
+    Mail body
+</body>
+</html>

+ 13 - 0
测试报告/html/export/prometheusData.txt

@@ -0,0 +1,13 @@
+launch_status_failed 0
+launch_status_broken 0
+launch_status_passed 6
+launch_status_skipped 0
+launch_status_unknown 0
+launch_time_duration 245
+launch_time_min_duration 1
+launch_time_max_duration 118
+launch_time_sum_duration 240
+launch_time_start 1760638176087
+launch_time_stop 1760638176332
+launch_retries_retries 0
+launch_retries_run 6

BIN
测试报告/html/favicon.ico


+ 1 - 0
测试报告/html/history/categories-trend.json

@@ -0,0 +1 @@
+[{"data":{}}]

+ 1 - 0
测试报告/html/history/duration-trend.json

@@ -0,0 +1 @@
+[{"data":{"duration":245}}]

+ 1 - 0
测试报告/html/history/history-trend.json

@@ -0,0 +1 @@
+[{"data":{"failed":0,"broken":0,"skipped":0,"passed":6,"unknown":0,"total":6}}]

+ 1 - 0
测试报告/html/history/history.json

@@ -0,0 +1 @@
+{"1fc1e369b89c187bd88dbf748b49002b":{"statistic":{"failed":0,"broken":0,"skipped":0,"passed":1,"unknown":0,"total":1},"items":[{"uid":"8f4399de319fe413","status":"passed","time":{"start":1760638176272,"stop":1760638176302,"duration":30}}]},"a1c975e457b641274223d34e793281c7":{"statistic":{"failed":0,"broken":0,"skipped":0,"passed":1,"unknown":0,"total":1},"items":[{"uid":"427c56cf8112259b","status":"passed","time":{"start":1760638176239,"stop":1760638176271,"duration":32}}]},"9a09e483c58e11bb1439fb510b09951c":{"statistic":{"failed":0,"broken":0,"skipped":0,"passed":1,"unknown":0,"total":1},"items":[{"uid":"862e50ffb623bd70","status":"passed","time":{"start":1760638176208,"stop":1760638176238,"duration":30}}]},"a15ee8806eae738200552428d49a6701":{"statistic":{"failed":0,"broken":0,"skipped":0,"passed":1,"unknown":0,"total":1},"items":[{"uid":"8e03048d4413b43b","status":"passed","time":{"start":1760638176303,"stop":1760638176332,"duration":29}}]},"72dda26adc4f130d365722908db8f25e":{"statistic":{"failed":0,"broken":0,"skipped":0,"passed":1,"unknown":0,"total":1},"items":[{"uid":"3ac100dfa00828b8","status":"passed","time":{"start":1760638176089,"stop":1760638176207,"duration":118}}]},"c26c784648e6778bbd26f03ee5eea420":{"statistic":{"failed":0,"broken":0,"skipped":0,"passed":1,"unknown":0,"total":1},"items":[{"uid":"6836f8a41e785dbe","status":"passed","time":{"start":1760638176087,"stop":1760638176088,"duration":1}}]}}

+ 1 - 0
测试报告/html/history/retry-trend.json

@@ -0,0 +1 @@
+[{"data":{"run":6,"retry":0}}]

+ 34 - 0
测试报告/html/index.html

@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html dir="ltr" lang="en">
+<head>
+    <meta charset="utf-8">
+    <title>Allure Report</title>
+    <link rel="icon" href="favicon.ico">
+    <link rel="stylesheet" type="text/css" href="styles.css">
+    <link rel="stylesheet" type="text/css" href="plugin/screen-diff/styles.css">
+</head>
+<body>
+    <div id="alert"></div>
+    <div id="content">
+        <span class="spinner">
+            <span class="spinner__circle"></span>
+        </span>
+    </div>
+    <div id="popup"></div>
+    <script src="app.js"></script>
+    <script src="plugin/behaviors/index.js"></script>
+    <script src="plugin/packages/index.js"></script>
+    <script src="plugin/screen-diff/index.js"></script>
+    <script async src="https://www.googletagmanager.com/gtag/js?id=G-FVWC4GKEYS"></script>
+    <script>
+        window.dataLayer = window.dataLayer || [];
+        function gtag(){dataLayer.push(arguments);}
+        gtag('js', new Date());
+        gtag('config', 'G-FVWC4GKEYS', {
+          'allureVersion': '2.35.1',
+          'reportUuid': 'c1af883a-4069-425f-a189-a01decc26380',
+          'single_file': false
+        });
+    </script>
+</body>
+</html>

+ 276 - 0
测试报告/html/plugin/behaviors/index.js

@@ -0,0 +1,276 @@
+'use strict';
+
+allure.api.addTranslation('en', {
+    tab: {
+        behaviors: {
+            name: 'Behaviors'
+        }
+    },
+    widget: {
+        behaviors: {
+            name: 'Features by stories',
+            showAll: 'show all'
+        }
+    }
+});
+
+allure.api.addTranslation('ru', {
+    tab: {
+        behaviors: {
+            name: 'Функциональность'
+        }
+    },
+    widget: {
+        behaviors: {
+            name: 'Функциональность',
+            showAll: 'показать все'
+        }
+    }
+});
+
+allure.api.addTranslation('zh', {
+    tab: {
+        behaviors: {
+            name: '功能'
+        }
+    },
+    widget: {
+        behaviors: {
+            name: '特性场景',
+            showAll: '显示所有'
+        }
+    }
+});
+
+allure.api.addTranslation('de', {
+    tab: {
+        behaviors: {
+            name: 'Verhalten'
+        }
+    },
+    widget: {
+        behaviors: {
+            name: 'Features nach Stories',
+            showAll: 'Zeige alle'
+        }
+    }
+});
+
+allure.api.addTranslation('nl', {
+    tab: {
+        behaviors: {
+            name: 'Functionaliteit'
+        }
+    },
+    widget: {
+        behaviors: {
+            name: 'Features en story’s',
+            showAll: 'Toon alle'
+        }
+    }
+});
+
+allure.api.addTranslation('he', {
+    tab: {
+        behaviors: {
+            name: 'התנהגויות'
+        }
+    },
+    widget: {
+        behaviors: {
+            name: 'תכונות לפי סיפורי משתמש',
+            showAll: 'הצג הכול'
+        }
+    }
+});
+
+allure.api.addTranslation('br', {
+    tab: {
+        behaviors: {
+            name: 'Comportamentos'
+        }
+    },
+    widget: {
+        behaviors: {
+            name: 'Funcionalidades por história',
+            showAll: 'Mostrar tudo'
+        }
+    }
+});
+
+allure.api.addTranslation('ja', {
+    tab: {
+        behaviors: {
+            name: '振る舞い'
+        }
+    },
+    widget: {
+        behaviors: {
+            name: 'ストーリー別の機能',
+            showAll: '全て表示'
+        }
+    }
+});
+
+allure.api.addTranslation('es', {
+    tab: {
+        behaviors: {
+            name: 'Funcionalidades'
+        }
+    },
+    widget: {
+        behaviors: {
+            name: 'Funcionalidades por Historias de Usuario',
+            showAll: 'mostrar todo'
+        }
+    }
+});
+
+allure.api.addTranslation('kr', {
+    tab: {
+        behaviors: {
+            name: '동작'
+        }
+    },
+    widget: {
+        behaviors: {
+            name: '스토리별 기능',
+            showAll: '전체 보기'
+        }
+    }
+});
+
+allure.api.addTranslation('fr', {
+    tab: {
+        behaviors: {
+            name: 'Comportements'
+        }
+    },
+    widget: {
+        behaviors: {
+            name: 'Thèmes par histoires',
+            showAll: 'Montrer tout'
+        }
+    }
+});
+
+allure.api.addTranslation('pl', {
+    tab: {
+        behaviors: {
+            name: 'Zachowania'
+        }
+    },
+    widget: {
+        behaviors: {
+            name: 'Funkcje według historii',
+            showAll: 'pokaż wszystko'
+        }
+    }
+});
+
+allure.api.addTranslation('am', {
+    tab: {
+        behaviors: {
+            name: 'Վարքագծեր'
+        }
+    },
+    widget: {
+        behaviors: {
+            name: 'Ֆիչրները ըստ պատմությունների',
+            showAll: 'ցույց տալ բոլորը'
+        }
+    }
+});
+
+allure.api.addTranslation('az', {
+    tab: {
+        behaviors: {
+            name: 'Davranışlar'
+        }
+    },
+    widget: {
+        behaviors: {
+            name: 'Hekayələr üzrə xüsusiyyətlər',
+            showAll: 'hamısını göstər'
+        }
+    }
+});
+
+allure.api.addTranslation('sv', {
+    tab: {
+        behaviors: {
+            name: 'Beteenden'
+        }
+    },
+    widget: {
+        behaviors: {
+            name: 'Funktioner efter user stories',
+            showAll: 'visa allt'
+        }
+    }
+});
+
+allure.api.addTranslation('isv', {
+    tab: {
+        behaviors: {
+            name: 'Funkcionalnost',
+        }
+    },
+    widget: {
+        behaviors: {
+            name: 'Funkcionalnost',
+            showAll: 'pokaži vsěčto',
+        }
+    }
+});
+
+allure.api.addTranslation('ka', {
+    tab: {
+        behaviors: {
+            name: 'ფუნქციონალი',
+        }
+    },
+    widget: {
+        behaviors: {
+            name: 'ფუნქციონალი',
+            showAll: 'ყველას ჩვენება',
+        }
+    }
+});
+
+allure.api.addTranslation('it', {
+    tab: {
+        behaviors: {
+            name: 'Comportamenti'
+        }
+    },
+    widget: {
+        behaviors: {
+            name: 'Funzionalità per storie',
+            showAll: 'Mostra tutto'
+        }
+    }
+});
+
+allure.api.addTab('behaviors', {
+    title: 'tab.behaviors.name', icon: 'fa fa-list',
+    route: 'behaviors(/)(:testGroup)(/)(:testResult)(/)(:testResultTab)(/)',
+    onEnter: (function (testGroup, testResult, testResultTab) {
+        return new allure.components.TreeLayout({
+            testGroup: testGroup,
+            testResult: testResult,
+            testResultTab: testResultTab,
+            tabName: 'tab.behaviors.name',
+            baseUrl: 'behaviors',
+            url: 'data/behaviors.json',
+            csvUrl: 'data/behaviors.csv'
+        });
+    })
+});
+
+allure.api.addWidget('widgets', 'behaviors', allure.components.WidgetStatusView.extend({
+    rowTag: 'a',
+    title: 'widget.behaviors.name',
+    baseUrl: 'behaviors',
+    showLinks: true
+}));

+ 160 - 0
测试报告/html/plugin/packages/index.js

@@ -0,0 +1,160 @@
+'use strict';
+
+allure.api.addTranslation('en', {
+    tab: {
+        packages: {
+            name: 'Packages'
+        }
+    }
+});
+
+allure.api.addTranslation('ru', {
+    tab: {
+        packages: {
+            name: 'Пакеты'
+        }
+    }
+});
+
+allure.api.addTranslation('zh', {
+    tab: {
+        packages: {
+            name: '包'
+        }
+    }
+});
+
+allure.api.addTranslation('de', {
+    tab: {
+        packages: {
+            name: 'Pakete'
+        }
+    }
+});
+
+allure.api.addTranslation('nl', {
+    tab: {
+        packages: {
+            name: 'Packages'
+        }
+    }
+});
+
+allure.api.addTranslation('he', {
+    tab: {
+        packages: {
+            name: 'חבילות'
+        }
+    }
+});
+
+allure.api.addTranslation('br', {
+    tab: {
+        packages: {
+            name: 'Pacotes'
+        }
+    }
+});
+
+allure.api.addTranslation('ja', {
+    tab: {
+        packages: {
+            name: 'パッケージ'
+        }
+    }
+});
+
+allure.api.addTranslation('es', {
+    tab: {
+        packages: {
+            name: 'Paquetes'
+        }
+    }
+});
+
+allure.api.addTranslation('kr', {
+    tab: {
+        packages: {
+            name: '패키지'
+        }
+    }
+});
+
+allure.api.addTranslation('fr', {
+    tab: {
+        packages: {
+            name: 'Paquets'
+        }
+    }
+});
+
+allure.api.addTranslation('pl', {
+    tab: {
+        packages: {
+            name: 'Pakiety'
+        }
+    }
+});
+
+allure.api.addTranslation('am', {
+    tab: {
+        packages: {
+            name: 'Փաթեթներ'
+        }
+    }
+});
+
+allure.api.addTranslation('az', {
+    tab: {
+        packages: {
+            name: 'Paketlər'
+        }
+    }
+});
+
+allure.api.addTranslation('sv', {
+    tab: {
+        packages: {
+            name: 'Paket'
+        }
+    }
+});
+
+allure.api.addTranslation('isv', {
+    tab: {
+        packages: {
+            name: 'Pakety'
+        }
+    }
+});
+
+allure.api.addTranslation('ka', {
+    tab: {
+        packages: {
+            name: 'პაკეტები'
+        }
+    }
+});
+
+allure.api.addTranslation('it', {
+    tab: {
+        packages: {
+            name: 'Pacchetti'
+        }
+    }
+});
+
+allure.api.addTab('packages', {
+    title: 'tab.packages.name', icon: 'fa fa-align-left',
+    route: 'packages(/)(:testGroup)(/)(:testResult)(/)(:testResultTab)(/)',
+    onEnter: (function (testGroup, testResult, testResultTab) {
+        return new allure.components.TreeLayout({
+            testGroup: testGroup,
+            testResult: testResult,
+            testResultTab: testResultTab,
+            tabName: 'tab.packages.name',
+            baseUrl: 'packages',
+            url: 'data/packages.json'
+        });
+    })
+});

+ 200 - 0
测试报告/html/plugin/screen-diff/index.js

@@ -0,0 +1,200 @@
+(function () {
+    var settings = allure.getPluginSettings('screen-diff', { diffType: 'diff' });
+
+    function renderImage(src) {
+        return (
+            '<div class="screen-diff__container">' +
+            '<img class="screen-diff__image" src="' +
+            src +
+            '">' +
+            '</div>'
+        );
+    }
+
+    function findImage(data, name) {
+        if (data.testStage && data.testStage.attachments) {
+            var matchedImage = data.testStage.attachments.filter(function (attachment) {
+                return attachment.name === name;
+            })[0];
+            if (matchedImage) {
+                return 'data/attachments/' + matchedImage.source;
+            }
+        }
+        return null;
+    }
+
+    function renderDiffContent(type, diffImage, actualImage, expectedImage) {
+        if (type === 'diff') {
+            if (diffImage) {
+                return renderImage(diffImage);
+            }
+        }
+        if (type === 'overlay' && expectedImage) {
+            return (
+                '<div class="screen-diff__overlay screen-diff__container">' +
+                '<img class="screen-diff__image" src="' +
+                expectedImage +
+                '">' +
+                '<div class="screen-diff__image-over">' +
+                '<img class="screen-diff__image" src="' +
+                actualImage +
+                '">' +
+                '</div>' +
+                '</div>'
+            );
+        }
+        if (actualImage) {
+            return renderImage(actualImage);
+        }
+        return 'No diff data provided';
+    }
+
+    var TestResultView = Backbone.Marionette.View.extend({
+        regions: {
+            subView: '.screen-diff-view',
+        },
+        template: function () {
+            return '<div class="screen-diff-view"></div>';
+        },
+        onRender: function () {
+            var data = this.model.toJSON();
+            var testType = data.labels.filter(function (label) {
+                return label.name === 'testType';
+            })[0];
+            var diffImage = findImage(data, 'diff');
+            var actualImage = findImage(data, 'actual');
+            var expectedImage = findImage(data, 'expected');
+            if (!testType || testType.value !== 'screenshotDiff') {
+                return;
+            }
+            this.showChildView(
+                'subView',
+                new ScreenDiffView({
+                    diffImage: diffImage,
+                    actualImage: actualImage,
+                    expectedImage: expectedImage,
+                }),
+            );
+        },
+    });
+    var ErrorView = Backbone.Marionette.View.extend({
+        templateContext: function () {
+            return this.options;
+        },
+        template: function (data) {
+            return '<pre class="screen-diff-error">' + data.error + '</pre>';
+        },
+    });
+    var AttachmentView = Backbone.Marionette.View.extend({
+        regions: {
+            subView: '.screen-diff-view',
+        },
+        template: function () {
+            return '<div class="screen-diff-view"></div>';
+        },
+        onRender: function () {
+            jQuery
+                .getJSON(this.options.sourceUrl)
+                .then(this.renderScreenDiffView.bind(this), this.renderErrorView.bind(this));
+        },
+        renderErrorView: function (error) {
+            console.log(error);
+            this.showChildView(
+                'subView',
+                new ErrorView({
+                    error: error.statusText,
+                }),
+            );
+        },
+        renderScreenDiffView: function (data) {
+            this.showChildView(
+                'subView',
+                new ScreenDiffView({
+                    diffImage: data.diff,
+                    actualImage: data.actual,
+                    expectedImage: data.expected,
+                }),
+            );
+        },
+    });
+
+    var ScreenDiffView = Backbone.Marionette.View.extend({
+        className: 'pane__section',
+        events: function () {
+            return {
+                ['click [name="screen-diff-type-' + this.cid + '"]']: 'onDiffTypeChange',
+                'mousemove .screen-diff__overlay': 'onOverlayMove',
+            };
+        },
+        initialize: function (options) {
+            this.diffImage = options.diffImage;
+            this.actualImage = options.actualImage;
+            this.expectedImage = options.expectedImage;
+            this.radioName = 'screen-diff-type-' + this.cid;
+        },
+        templateContext: function () {
+            return {
+                diffType: settings.get('diffType'),
+                diffImage: this.diffImage,
+                actualImage: this.actualImage,
+                expectedImage: this.expectedImage,
+                radioName: this.radioName,
+            };
+        },
+        template: function (data) {
+            if (!data.diffImage && !data.actualImage && !data.expectedImage) {
+                return '';
+            }
+
+            return (
+                '<h3 class="pane__section-title">Screen Diff</h3>' +
+                '<div class="screen-diff__content">' +
+                '<div class="screen-diff__switchers">' +
+                '<label><input type="radio" name="' +
+                data.radioName +
+                '" value="diff"> Show diff</label>' +
+                '<label><input type="radio" name="' +
+                data.radioName +
+                '" value="overlay"> Show overlay</label>' +
+                '</div>' +
+                renderDiffContent(
+                    data.diffType,
+                    data.diffImage,
+                    data.actualImage,
+                    data.expectedImage,
+                ) +
+                '</div>'
+            );
+        },
+        adjustImageSize: function (event) {
+            var overImage = this.$(event.target);
+            overImage.width(overImage.width());
+        },
+        onRender: function () {
+            const diffType = settings.get('diffType');
+            this.$('[name="' + this.radioName + '"][value="' + diffType + '"]').prop(
+                'checked',
+                true,
+            );
+            if (diffType === 'overlay') {
+                this.$('.screen-diff__image-over img').on('load', this.adjustImageSize.bind(this));
+            }
+        },
+        onOverlayMove: function (event) {
+            var pageX = event.pageX;
+            var containerScroll = this.$('.screen-diff__container').scrollLeft();
+            var elementX = event.currentTarget.getBoundingClientRect().left;
+            var delta = pageX - elementX + containerScroll;
+            this.$('.screen-diff__image-over').width(delta);
+        },
+        onDiffTypeChange: function (event) {
+            settings.save('diffType', event.target.value);
+            this.render();
+        },
+    });
+    allure.api.addTestResultBlock(TestResultView, { position: 'before' });
+    allure.api.addAttachmentViewer('application/vnd.allure.image.diff', {
+        View: AttachmentView,
+        icon: 'fa fa-exchange',
+    });
+})();

+ 30 - 0
测试报告/html/plugin/screen-diff/styles.css

@@ -0,0 +1,30 @@
+.screen-diff__switchers {
+  margin-bottom: 1em;
+}
+
+.screen-diff__switchers label + label {
+  margin-left: 1em;
+}
+
+.screen-diff__overlay {
+  position: relative;
+  cursor: col-resize;
+}
+
+.screen-diff__container {
+  overflow-x: auto;
+}
+
+.screen-diff__image-over {
+  top: 0;
+  left: 0;
+  bottom: 0;
+  background: #fff;
+  position: absolute;
+  overflow: hidden;
+  box-shadow: 2px 0 1px -1px #aaa;
+}
+
+.screen-diff-error {
+  color: #fd5a3e;
+}

File diff suppressed because it is too large
+ 3 - 0
测试报告/html/styles.css


+ 1 - 0
测试报告/html/widgets/behaviors.json

@@ -0,0 +1 @@
+{"total":6,"items":[]}

+ 1 - 0
测试报告/html/widgets/categories-trend.json

@@ -0,0 +1 @@
+[{"data":{}}]

+ 1 - 0
测试报告/html/widgets/categories.json

@@ -0,0 +1 @@
+{"total":0,"items":[]}

+ 1 - 0
测试报告/html/widgets/duration-trend.json

@@ -0,0 +1 @@
+[{"data":{"duration":245}}]

+ 1 - 0
测试报告/html/widgets/duration.json

@@ -0,0 +1 @@
+[{"uid":"8e03048d4413b43b","name":"test_case[case_info4]","time":{"start":1760638176303,"stop":1760638176332,"duration":29},"status":"passed","severity":"normal"},{"uid":"6836f8a41e785dbe","name":"test_excel_path","time":{"start":1760638176087,"stop":1760638176088,"duration":1},"status":"passed","severity":"normal"},{"uid":"8f4399de319fe413","name":"test_case[case_info3]","time":{"start":1760638176272,"stop":1760638176302,"duration":30},"status":"passed","severity":"normal"},{"uid":"862e50ffb623bd70","name":"test_case[case_info1]","time":{"start":1760638176208,"stop":1760638176238,"duration":30},"status":"passed","severity":"normal"},{"uid":"427c56cf8112259b","name":"test_case[case_info2]","time":{"start":1760638176239,"stop":1760638176271,"duration":32},"status":"passed","severity":"normal"},{"uid":"3ac100dfa00828b8","name":"test_case[case_info0]","time":{"start":1760638176089,"stop":1760638176207,"duration":118},"status":"passed","severity":"normal"}]

+ 1 - 0
测试报告/html/widgets/environment.json

@@ -0,0 +1 @@
+[]

+ 1 - 0
测试报告/html/widgets/executors.json

@@ -0,0 +1 @@
+[]

+ 1 - 0
测试报告/html/widgets/history-trend.json

@@ -0,0 +1 @@
+[{"data":{"failed":0,"broken":0,"skipped":0,"passed":6,"unknown":0,"total":6}}]

+ 1 - 0
测试报告/html/widgets/launch.json

@@ -0,0 +1 @@
+[]

+ 1 - 0
测试报告/html/widgets/retry-trend.json

@@ -0,0 +1 @@
+[{"data":{"run":6,"retry":0}}]

+ 1 - 0
测试报告/html/widgets/severity.json

@@ -0,0 +1 @@
+[{"uid":"8f4399de319fe413","name":"test_case[case_info3]","time":{"start":1760638176272,"stop":1760638176302,"duration":30},"status":"passed","severity":"normal"},{"uid":"3ac100dfa00828b8","name":"test_case[case_info0]","time":{"start":1760638176089,"stop":1760638176207,"duration":118},"status":"passed","severity":"normal"},{"uid":"427c56cf8112259b","name":"test_case[case_info2]","time":{"start":1760638176239,"stop":1760638176271,"duration":32},"status":"passed","severity":"normal"},{"uid":"6836f8a41e785dbe","name":"test_excel_path","time":{"start":1760638176087,"stop":1760638176088,"duration":1},"status":"passed","severity":"normal"},{"uid":"862e50ffb623bd70","name":"test_case[case_info1]","time":{"start":1760638176208,"stop":1760638176238,"duration":30},"status":"passed","severity":"normal"},{"uid":"8e03048d4413b43b","name":"test_case[case_info4]","time":{"start":1760638176303,"stop":1760638176332,"duration":29},"status":"passed","severity":"normal"}]

+ 1 - 0
测试报告/html/widgets/status-chart.json

@@ -0,0 +1 @@
+[{"uid":"8e03048d4413b43b","name":"test_case[case_info4]","time":{"start":1760638176303,"stop":1760638176332,"duration":29},"status":"passed","severity":"normal"},{"uid":"6836f8a41e785dbe","name":"test_excel_path","time":{"start":1760638176087,"stop":1760638176088,"duration":1},"status":"passed","severity":"normal"},{"uid":"8f4399de319fe413","name":"test_case[case_info3]","time":{"start":1760638176272,"stop":1760638176302,"duration":30},"status":"passed","severity":"normal"},{"uid":"862e50ffb623bd70","name":"test_case[case_info1]","time":{"start":1760638176208,"stop":1760638176238,"duration":30},"status":"passed","severity":"normal"},{"uid":"427c56cf8112259b","name":"test_case[case_info2]","time":{"start":1760638176239,"stop":1760638176271,"duration":32},"status":"passed","severity":"normal"},{"uid":"3ac100dfa00828b8","name":"test_case[case_info0]","time":{"start":1760638176089,"stop":1760638176207,"duration":118},"status":"passed","severity":"normal"}]

+ 1 - 0
测试报告/html/widgets/suites.json

@@ -0,0 +1 @@
+{"total":1,"items":[{"uid":"b3ab64535ad66c4ce064c5467c723836","name":"demo","statistic":{"failed":0,"broken":0,"skipped":0,"passed":6,"unknown":0,"total":6}}]}

+ 1 - 0
测试报告/html/widgets/summary.json

@@ -0,0 +1 @@
+{"reportName":"Allure Report","testRuns":[],"statistic":{"failed":0,"broken":0,"skipped":0,"passed":6,"unknown":0,"total":6},"time":{"start":1760638176087,"stop":1760638176332,"duration":245,"minDuration":1,"maxDuration":118,"sumDuration":240}}

+ 1 - 0
测试报告/json/1319e870-d015-4de8-8867-7196140be8b0-result.json

@@ -0,0 +1 @@
+{"name": "test_case[case_info4]", "status": "passed", "attachments": [{"name": "stdout", "source": "508c9f22-e238-4e77-b1df-d960423fffb6-attachment.txt", "type": "text/plain"}], "parameters": [{"name": "case_info", "value": "{'用例编号': 'p5', 'title': '删除记录', 'method': 'post', 'url': 'http://106.52.242.71:8001/api/user/dns-records/delete', 'headers': '{\"Content-Type\":\"application/json\",\"Authorization\":\"Bearer ${token}\"}', 'params': '', 'json': '{\\n  \"recordId\":\"${int.id}\"\\n}', 'data': '', '预期响应码': 200, '实际响应码': '', '需要变量': '', '提取变量': '', '响应实例': '{\\n \"code\": 200,\\n \"message\": \"DNS解析记录删除成功\",\\n \"data\": true,\\n \"timestamp\": \"2025-10-13T03:12:40.686714541\"\\n}'}"}], "start": 1760638326594, "stop": 1760638326619, "uuid": "4b292c79-4995-4d7b-9d83-718d1dcc5019", "historyId": "a15ee8806eae738200552428d49a6701", "testCaseId": "d5daf8ae46d06c3b1be89dffaef4b7c7", "fullName": "demo.test_a#test_case", "labels": [{"name": "parentSuite", "value": "demo"}, {"name": "suite", "value": "test_a"}, {"name": "host", "value": "xxhdeMacBook-Air.local"}, {"name": "thread", "value": "5833-MainThread"}, {"name": "framework", "value": "pytest"}, {"name": "language", "value": "cpython3"}, {"name": "package", "value": "demo.test_a"}], "titlePath": ["demo", "test_a.py"]}

+ 1 - 0
测试报告/json/145b5286-16c6-4e9e-b61a-eb594b85ad5e-container.json

@@ -0,0 +1 @@
+{"uuid": "caeb7cd1-09e9-4d79-909f-099c3d7c8562", "befores": [{"name": "case_info", "status": "passed", "start": 1760638326533, "stop": 1760638326533}], "start": 1760638326533, "stop": 1760638326561}

+ 1 - 0
测试报告/json/19bfc690-cdf0-472c-973b-cc97da821fb4-container.json

@@ -0,0 +1 @@
+{"uuid": "2fd054c8-b75a-4e42-bd6d-f2a4d814733a", "befores": [{"name": "case_info", "status": "passed", "start": 1760638326594, "stop": 1760638326594}], "start": 1760638326594, "stop": 1760638326619}

File diff suppressed because it is too large
+ 0 - 0
测试报告/json/1e52bc85-092a-4469-9a9f-3ceb345323a7-result.json


+ 1 - 0
测试报告/json/37cbe19a-02fe-4cbf-8de7-258e220ebb0d-attachment.txt

@@ -0,0 +1 @@
+login

+ 1 - 0
测试报告/json/508c9f22-e238-4e77-b1df-d960423fffb6-attachment.txt

@@ -0,0 +1 @@
+{'recordId': '${int.id}'}

+ 1 - 0
测试报告/json/53625ae8-f88a-4824-a792-c4c5c64e60d5-container.json

@@ -0,0 +1 @@
+{"uuid": "91f75bf9-9f39-4b88-ac73-b14037601009", "befores": [{"name": "case_info", "status": "passed", "start": 1760638326383, "stop": 1760638326383}], "start": 1760638326383, "stop": 1760638326502}

+ 1 - 0
测试报告/json/5d35f64b-fcb1-4967-a6fc-471be6b35145-attachment.txt

@@ -0,0 +1 @@
+{'id': '${int.id}', 'type': 'CNAME', 'value': 'sd.com', 'ttl': 600, 'status': 'ENABLE', 'remark': '更新后的网站主页'}

+ 1 - 0
测试报告/json/86bb6e2c-9637-477f-8b49-7b52d59c9927-result.json

@@ -0,0 +1 @@
+{"name": "test_case[case_info0]", "status": "passed", "attachments": [{"name": "stdout", "source": "c4dbaaa2-cbbf-43ae-838b-6fa512a88bc8-attachment.txt", "type": "text/plain"}], "parameters": [{"name": "case_info", "value": "{'用例编号': 'p1', 'title': '登陆', 'method': 'post', 'url': 'http://106.52.242.71:8001/api/auth/login', 'headers': '{\"Content-Type\":\"application/json\"}', 'params': '', 'json': '{\\n  \"email\": \"allnotice@qq.com\",\\n  \"password\": \"22222hua\"\\n}\\n', 'data': '', '预期响应码': 200, '实际响应码': '', '需要变量': '', '提取变量': 'token,code', '响应实例': ''}"}], "start": 1760638326383, "stop": 1760638326502, "uuid": "11e5812c-70db-4b01-814c-3a081507f147", "historyId": "72dda26adc4f130d365722908db8f25e", "testCaseId": "d5daf8ae46d06c3b1be89dffaef4b7c7", "fullName": "demo.test_a#test_case", "labels": [{"name": "parentSuite", "value": "demo"}, {"name": "suite", "value": "test_a"}, {"name": "host", "value": "xxhdeMacBook-Air.local"}, {"name": "thread", "value": "5833-MainThread"}, {"name": "framework", "value": "pytest"}, {"name": "language", "value": "cpython3"}, {"name": "package", "value": "demo.test_a"}], "titlePath": ["demo", "test_a.py"]}

File diff suppressed because it is too large
+ 0 - 0
测试报告/json/a8d1b615-69aa-4762-8e87-1a04619266e1-result.json


+ 1 - 0
测试报告/json/a95a3161-dc98-4d67-9755-9f19eaaa8c94-result.json

@@ -0,0 +1 @@
+{"name": "test_case[case_info1]", "status": "passed", "attachments": [{"name": "stdout", "source": "e982a72e-5805-493c-ab70-523c094cf201-attachment.txt", "type": "text/plain"}], "parameters": [{"name": "case_info", "value": "{'用例编号': 'p2', 'title': '注册域名', 'method': 'post', 'url': 'http://106.52.242.71:8001/api/user/subdomains/register', 'headers': '{\"Content-Type\":\"application/json\",\"Authorization\":\"Bearer ${token}\"}', 'params': '', 'json': '{\\n  \"subdomain\": \"bbbbbbbbbbb\",\\n  \"domain\": \"www.vvvv.host\"\\n}', 'data': '', '预期响应码': 200, '实际响应码': '', '需要变量': '', '提取变量': 'id', '响应实例': '{\\n \"code\": 200,\\n \"message\": \"操作成功\",\\n \"data\": {\\n  \"id\": 11201,\\n  \"userId\": 2,\\n  \"subdomain\": \"t2t\",\\n  \"domain\": \"www.vvvv.host\",\\n  \"fullDomain\": \"t2t.www.vvvv.host\",\\n  \"status\": \"ACTIVE\",\\n  \"remark\": \"allnotice@qq.com\",\\n  \"createTime\": null,\\n  \"updateTime\": null\\n },\\n \"timestamp\": \"2025-10-13T02:54:10.513305888\"\\n}'}"}], "start": 1760638326503, "stop": 1760638326533, "uuid": "6de540b1-5395-41e5-a442-87c5a5d6bb73", "historyId": "9a09e483c58e11bb1439fb510b09951c", "testCaseId": "d5daf8ae46d06c3b1be89dffaef4b7c7", "fullName": "demo.test_a#test_case", "labels": [{"name": "parentSuite", "value": "demo"}, {"name": "suite", "value": "test_a"}, {"name": "host", "value": "xxhdeMacBook-Air.local"}, {"name": "thread", "value": "5833-MainThread"}, {"name": "framework", "value": "pytest"}, {"name": "language", "value": "cpython3"}, {"name": "package", "value": "demo.test_a"}], "titlePath": ["demo", "test_a.py"]}

+ 1 - 0
测试报告/json/b2de3312-f3ba-4c54-b6c4-d3942450ec7a-attachment.txt

@@ -0,0 +1 @@
+{'subdomainId': '${int.id}', 'name': 'ddd', 'type': 'AAAA', 'value': '2408:826a:361a:2980::63', 'line': '默认', 'ttl': 600, 'remark': '网站主页'}

+ 1 - 0
测试报告/json/b7191d7c-aff8-4054-8fd7-9a459aee51fc-container.json

@@ -0,0 +1 @@
+{"uuid": "aae01e69-a819-4eda-9e21-ebdf57a3a164", "befores": [{"name": "case_info", "status": "passed", "start": 1760638326562, "stop": 1760638326562}], "start": 1760638326562, "stop": 1760638326593}

+ 1 - 0
测试报告/json/c4dbaaa2-cbbf-43ae-838b-6fa512a88bc8-attachment.txt

@@ -0,0 +1 @@
+{'email': 'allnotice@qq.com', 'password': '22222hua'}

+ 1 - 0
测试报告/json/e12b36f8-a994-4125-b10b-28275edcbefb-container.json

@@ -0,0 +1 @@
+{"uuid": "4c8aad79-9cc2-45ba-b984-0c9a3181f2a2", "befores": [{"name": "case_info", "status": "passed", "start": 1760638326503, "stop": 1760638326503}], "start": 1760638326503, "stop": 1760638326533}

+ 1 - 0
测试报告/json/e6a8a9da-99f5-4b2a-8221-6651528dfa7f-result.json

@@ -0,0 +1 @@
+{"name": "test_excel_path", "status": "passed", "attachments": [{"name": "stdout", "source": "37cbe19a-02fe-4cbf-8de7-258e220ebb0d-attachment.txt", "type": "text/plain"}], "start": 1760638326382, "stop": 1760638326382, "uuid": "7491dbad-67fc-474f-98e6-e141f45d6466", "historyId": "c26c784648e6778bbd26f03ee5eea420", "testCaseId": "c26c784648e6778bbd26f03ee5eea420", "fullName": "demo.test_a#test_excel_path", "labels": [{"name": "tag", "value": "login"}, {"name": "parentSuite", "value": "demo"}, {"name": "suite", "value": "test_a"}, {"name": "host", "value": "xxhdeMacBook-Air.local"}, {"name": "thread", "value": "5833-MainThread"}, {"name": "framework", "value": "pytest"}, {"name": "language", "value": "cpython3"}, {"name": "package", "value": "demo.test_a"}], "titlePath": ["demo", "test_a.py"]}

+ 1 - 0
测试报告/json/e982a72e-5805-493c-ab70-523c094cf201-attachment.txt

@@ -0,0 +1 @@
+{'subdomain': 'bbbbbbbbbbb', 'domain': 'www.vvvv.host'}

Some files were not shown because too many files changed in this diff