aobn 2 月之前
當前提交
1ba12e7a8b

+ 10 - 0
.idea/Pytest.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.11 (Pytest)" jdkType="Python SDK" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>

+ 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>

+ 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/Pytest.iml" filepath="$PROJECT_DIR$/.idea/Pytest.iml" />
+    </modules>
+  </component>
+</project>

+ 6 - 0
.idea/vcs.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="$PROJECT_DIR$" vcs="Git" />
+  </component>
+</project>

+ 153 - 0
.idea/workspace.xml

@@ -0,0 +1,153 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="AutoImportSettings">
+    <option name="autoReloadType" value="SELECTIVE" />
+  </component>
+  <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>
+    <option name="SHOW_DIALOG" value="false" />
+    <option name="HIGHLIGHT_CONFLICTS" value="true" />
+    <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
+    <option name="LAST_RESOLUTION" value="IGNORE" />
+  </component>
+  <component name="FileTemplateManagerImpl">
+    <option name="RECENT_TEMPLATES">
+      <list>
+        <option value="Python Script" />
+      </list>
+    </option>
+  </component>
+  <component name="Git.Settings">
+    <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
+  </component>
+  <component name="ProjectColorInfo">{
+  &quot;associatedIndex&quot;: 3
+}</component>
+  <component name="ProjectId" id="349UAvcBQT85YOy0EpMnoSFhsiH" />
+  <component name="ProjectLevelVcsManager">
+    <ConfirmationsSetting value="2" id="Add" />
+  </component>
+  <component name="ProjectViewState">
+    <option name="hideEmptyMiddlePackages" value="true" />
+    <option name="showLibraryContents" value="true" />
+  </component>
+  <component name="PropertiesComponent"><![CDATA[{
+  "keyToString": {
+    "ModuleVcsDetector.initialDetectionPerformed": "true",
+    "Python tests.Python tests for demo.test_a.test_get_excel.executor": "Run",
+    "Python tests.Python tests in test_a.py.executor": "Run",
+    "Python.get_excel.executor": "Run",
+    "RunOnceActivity.ShowReadmeOnStart": "true",
+    "RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252": "true",
+    "RunOnceActivity.git.unshallow": "true",
+    "git-widget-placeholder": "main",
+    "last_opened_file_path": "/Users/xxh/test/Pytest",
+    "settings.editor.selected.configurable": "terminal"
+  }
+}]]></component>
+  <component name="RecentsManager">
+    <key name="CopyFile.RECENT_KEYS">
+      <recent name="$PROJECT_DIR$" />
+    </key>
+    <key name="MoveFile.RECENT_KEYS">
+      <recent name="$PROJECT_DIR$/demo" />
+      <recent name="$PROJECT_DIR$/demo/main" />
+      <recent name="$PROJECT_DIR$/excel" />
+    </key>
+  </component>
+  <component name="RunManager" selected="Python tests.Python tests in test_a.py">
+    <configuration name="get_excel" 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$/until" />
+      <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$/until/get_excel.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.main.test_a" type="tests" factoryName="Autodetect" temporary="true" nameIsGenerated="true">
+      <module name="Pytest" />
+      <option name="ENV_FILES" value="" />
+      <option name="INTERPRETER_OPTIONS" value="" />
+      <option name="PARENT_ENVS" value="true" />
+      <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="_new_additionalArguments" value="&quot;&quot;" />
+      <option name="_new_target" value="&quot;demo.main.test_a&quot;" />
+      <option name="_new_targetType" value="&quot;PYTHON&quot;" />
+      <method v="2" />
+    </configuration>
+    <configuration name="Python tests in test_a.py" type="tests" factoryName="Autodetect" temporary="true" nameIsGenerated="true">
+      <module name="Pytest" />
+      <option name="ENV_FILES" value="" />
+      <option name="INTERPRETER_OPTIONS" value="" />
+      <option name="PARENT_ENVS" value="true" />
+      <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="_new_additionalArguments" value="&quot;&quot;" />
+      <option name="_new_target" value="&quot;$PROJECT_DIR$/demo/main/test_a.py&quot;" />
+      <option name="_new_targetType" value="&quot;PATH&quot;" />
+      <method v="2" />
+    </configuration>
+    <recent_temporary>
+      <list>
+        <item itemvalue="Python tests.Python tests in test_a.py" />
+        <item itemvalue="Python tests.Python tests for demo.main.test_a" />
+        <item itemvalue="Python.get_excel" />
+      </list>
+    </recent_temporary>
+  </component>
+  <component name="SharedIndexes">
+    <attachedChunks>
+      <set>
+        <option value="bundled-python-sdk-b3d66beaba9a-c6efb3732140-com.jetbrains.pycharm.pro.sharedIndexes.bundled-PY-252.26199.168" />
+      </set>
+    </attachedChunks>
+  </component>
+  <component name="TaskManager">
+    <task active="true" id="Default" summary="Default task">
+      <changelist id="07cc7c5b-0297-4ba8-b7e8-ad9e2f5c9a81" name="Changes" comment="" />
+      <created>1760625141848</created>
+      <option name="number" value="Default" />
+      <option name="presentableId" value="Default" />
+      <updated>1760625141848</updated>
+    </task>
+    <servers />
+  </component>
+</project>

+ 12 - 0
demo/dic/global_value.py

@@ -0,0 +1,12 @@
+
+class GlobalInfo(object):
+    _global_info = {}
+
+    def set_info(self, key, value):
+        self._global_info[key] = value
+
+    def get_info(self, key):
+        return self._global_info.get(key)
+
+    def show_info(self):
+        return self._global_info

+ 0 - 0
demo/excel/jsom.xlxs


+ 3 - 0
demo/main.py

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

+ 0 - 0
demo/main/__init__.py


+ 48 - 0
demo/main/test_a.py

@@ -0,0 +1,48 @@
+import pytest,json
+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
+client = ApiClient()
+
+@pytest.mark.parametrize("case_info", gexcel.get_excel("demo", 0))
+def test_case(case_info):
+    #初始化全局变量
+    dic = GlobalInfo().show_info()
+
+    # 拼接请求参数
+    url = case_info["url"]
+    method = case_info["method"]
+    headers = eval(case_info["headers"]) if case_info["headers"] else {}
+    params = eval(case_info["params"]) if case_info["params"] else {}
+    data = eval(case_info["data"]) if case_info["data"] else {}
+    _json = eval(case_info["json"]) if case_info["json"] else {}
+
+    # 写日志
+    write_log("url",url)
+    write_log("headers",headers)
+    write_log("params",params)
+    write_log("data",data)
+
+    # 前置操作
+
+
+    res = client.send_request(method, url, headers=headers, params=params, data=data, json=_json)
+    write_log("respose", res.json())
+
+
+    # assert res.status_code == 200
+
+
+    # 后置操作
+    ## 提取变量
+    if case_info["提取变量"] != "":
+        vars_to_extract = [v.strip() for v in case_info["提取变量"].split(",") if v.strip()]
+        for var in vars_to_extract:
+            value = jsonpath.jsonpath(res.json(), f"$..{var}")
+            if value:
+                GlobalInfo().set_info(var, value[0])
+        write_log("globalInfo.txt", json.dumps(GlobalInfo().show_info()))
+
+    print(_json)

+ 2 - 0
demo/main/test_test.py

@@ -0,0 +1,2 @@
+import pytest
+

+ 0 - 0
demo/pytest.ini


+ 7 - 0
demo/requirements.txt

@@ -0,0 +1,7 @@
+pytest
+allure-pytest==2.15.0
+pandas
+jsonpath
+openpyxl
+requests
+pandas-stubs==2.3.2.250926

+ 26 - 0
demo/utils/get_excel.py

@@ -0,0 +1,26 @@
+import pandas as pd
+from pathlib import Path
+import demo.utils.write_log as log
+def get_excel(file_name, sheet_name=0):
+    """
+    读取excel文件目录下.xlsx文件内容到DataFrame,并用空字符串填充缺失值
+    :param file_name:
+    :param sheet_name: 工作表名称或索引,默认读取第一个工作表
+    :return: 填充缺失值后的DataFrame
+    """
+
+
+    project_root = Path(__file__).parent.parent
+    # 拼接 demo/demo.xlsx 路径
+    file_path = project_root / "excel" / (file_name+".xlsx")
+
+    df = pd.read_excel(file_path, sheet_name=sheet_name)
+    df = df.fillna("")  # 用空字符串填充缺失值
+    df = df.to_dict(orient="records")
+    # print(df)
+
+    log.clear_log(file_name)
+    log.write_log(file_name, df)
+    return df
+
+# print(file_path)

+ 18 - 0
demo/utils/send.py

@@ -0,0 +1,18 @@
+
+import requests
+
+class ApiClient:
+    def __init__(self, base_url=None):
+        self.base_url = base_url
+
+    def send_request(self,method, url, headers=None, params=None, data=None, json=None):
+        res = requests.request(
+            method=method,
+            url=self.base_url + url if self.base_url else url,
+            headers=headers,
+            params=params,
+            data=data,
+            json=json
+        )
+        # print(res.text)
+        return res

+ 25 - 0
demo/utils/write_log.py

@@ -0,0 +1,25 @@
+
+import logging
+import os
+from pathlib import Path
+def write_log(file_name, info):
+
+    project_root = Path(__file__).parent.parent
+    # 拼接 demo/demo.xlsx 路径
+    file_path = project_root / "log" / (file_name+".txt")
+
+    logging.basicConfig(filename=file_path, level=logging.INFO, force=True)
+    # 将 file 的内容写入日志
+    logging.info(info)
+    # 关闭日志系统,确保日志写入文件
+    logging.shutdown()
+
+
+def clear_log(file_name):
+
+    project_root = Path(__file__).parent.parent
+    # 拼接 demo/demo.xlsx 路径
+    file_path = project_root / "log" / (file_name+".txt")
+
+    with open(file_path, "w") as f:
+        pass  # 直接写入空内容