Skip to content

Commit

Permalink
重构jsonpath实施为python-jsonpath (#39)
Browse files Browse the repository at this point in the history
* 重构jsonpath实施为python-jsonpath

* 统一jsonpath返回结果处理
  • Loading branch information
wu-clan authored Sep 10, 2023
1 parent 929db48 commit 2a30826
Show file tree
Hide file tree
Showing 7 changed files with 34 additions and 28 deletions.
2 changes: 1 addition & 1 deletion .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
github: wu-clan
custom: https://wu-clan.github.io/httpfpt_docs/reward/
14 changes: 7 additions & 7 deletions httpfpt/db/mysql_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import pymysql
from dbutils.pooled_db import PooledDB
from jsonpath import jsonpath
from jsonpath import findall

from httpfpt.common.env_handler import write_env_vars
from httpfpt.common.log import log
Expand Down Expand Up @@ -104,7 +104,7 @@ def execute(self, sql: str) -> int:
finally:
self.close()

def exec_case_sql(self, sql: str | list, env: Optional[str] = None) -> None:
def exec_case_sql(self, sql: str | list, env: Optional[str] = None) -> dict | int | None:
"""
执行用例 sql
Expand All @@ -118,15 +118,15 @@ def exec_case_sql(self, sql: str | list, env: Optional[str] = None) -> None:
else:
if isinstance(sql, str):
log.info(f'执行 sql: {sql}')
self.query(sql)
return self.query(sql)
for s in sql:
# 获取返回数据
if isinstance(s, str):
log.info(f'执行 sql: {s}')
if SqlType.select in s:
self.query(s)
return self.query(s)
else:
self.execute(s)
return self.execute(s)
# 设置变量
if isinstance(s, dict):
log.info(f'执行变量提取 sql: {s["sql"]}')
Expand All @@ -135,9 +135,9 @@ def exec_case_sql(self, sql: str | list, env: Optional[str] = None) -> None:
sql_text = s['sql']
json_path = s['jsonpath']
query_data = self.query(sql_text)
value = jsonpath(query_data, json_path)
value = findall(json_path, query_data)
if value:
value = value[0]
value = str(value[0])
else:
raise ValueError(f'jsonpath 取值失败, 表达式: {json_path}')
if set_type == VarType.CACHE:
Expand Down
23 changes: 14 additions & 9 deletions httpfpt/utils/assert_control.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
from decimal import Decimal
from typing import Union, Any

from jsonpath import jsonpath
from jsonpath import findall

from httpfpt.common.log import log
from httpfpt.db.mysql_db import MysqlDB
from httpfpt.enums.assert_type import AssertType
from httpfpt.enums.sql_type import SqlType


class Asserter:
Expand Down Expand Up @@ -69,7 +70,7 @@ def _json_asserter(self, response: dict, assert_text: dict) -> None:
2. ...
语法说明::
符合 jsonpath 取值语法即可, `jsonpath <https://goessner.net/articles/JsonPath/index.html#e2>`_
符合 jsonpath 取值语法即可, `jsonpath <https://jg-rp.github.io/python-jsonpath/syntax/>`_
取值范围::
与 code 断言器一致
Expand All @@ -93,7 +94,7 @@ def _json_asserter(self, response: dict, assert_text: dict) -> None:
except KeyError as e:
raise ValueError(f'断言格式错误, 缺少必须参数, 请检查: {e}')
else:
response_value = jsonpath(response, assert_jsonpath)
response_value = findall(assert_jsonpath, response)
if response_value:
log.info(f'执行断言:{assert_text}')
self._exec_json_assert(assert_check, assert_value, assert_type, response_value[0])
Expand All @@ -120,13 +121,17 @@ def _sql_asserter(self, assert_text: dict) -> None:
except KeyError as e:
raise ValueError(f'断言格式错误, 缺少必须参数, 请检查: {e}')
else:
if assert_sql.split(' ')[0].upper() != SqlType.select:
raise ValueError(f'sql 断言 {assert_check}:{assert_type} 执行失败,请检查 sql 是否为 DQL 类型')
sql_data = MysqlDB().exec_case_sql(assert_sql)
sql_value = jsonpath(sql_data, assert_jsonpath)
if sql_value:
log.info(f'执行断言:{assert_text}')
self._exec_json_assert(assert_check, assert_value, assert_type, sql_value[0])
else:
raise ValueError(f'jsonpath取值失败, 表达式: {assert_jsonpath}')
if not isinstance(sql_data, dict):
raise ValueError('jsonpath取值失败, sql 语句执行结果不是有效的 dict 类型')
sql_value = findall(assert_jsonpath, sql_data)
if sql_value:
log.info(f'执行断言:{assert_text}')
self._exec_json_assert(assert_check, assert_value, assert_type, sql_value[0])
else:
raise ValueError(f'jsonpath取值失败, 表达式: {assert_jsonpath}')

@staticmethod
def _exec_code_assert(response: dict, assert_text: str) -> None:
Expand Down
11 changes: 6 additions & 5 deletions httpfpt/utils/auth_plugins.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import requests
from jsonpath import jsonpath
from jsonpath import findall

from httpfpt.common.yaml_handler import read_yaml
from httpfpt.core.path_conf import AUTH_CONF_PATH
Expand All @@ -19,7 +18,7 @@ class AuthPlugins:
def __init__(self) -> None:
self.auth_type = AUTH_TYPE
if not getattr(AuthType, self.auth_type, None):
raise ValueError(f'认证类型错误, 仅允许 {get_enum_values(AuthType)} 其中之一, 请检查认证配置文件')
raise ValueError(f'认证类型错误, 仅允许 {get_enum_values(AuthType)} 之一, 请检查认证配置文件')

@property
def bearer_token(self) -> str:
Expand All @@ -42,6 +41,8 @@ def bearer_token(self) -> str:
if 'json' in str(headers):
request_data.update({'json': request_data.pop('data')})
response = requests.session().post(**request_data)
token = jsonpath(response.json(), auth_data[f'{self.auth_type}']['token_key'])[0]
redis_client.set(f'{redis_client.prefix}:bearer_token', token, ex=timeout)
token = findall(auth_data[f'{self.auth_type}']['token_key'], response.json())
if not token:
raise ValueError('Token 获取失败,请检查接口响应或 token_key 表达式')
redis_client.set(f'{redis_client.prefix}:bearer_token', token[0], ex=timeout)
return token
4 changes: 2 additions & 2 deletions httpfpt/utils/relate_testcase_executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import sys
from typing import List, Dict, Union

from jsonpath import jsonpath
from jsonpath import findall
from pydantic import ValidationError

from httpfpt.common.log import log
Expand Down Expand Up @@ -242,7 +242,7 @@ def relate_testcase_set_var(testcase_data: dict) -> None:
log.debug(msg)
allure_step(msg, '此文件为空')
response = send_request.send_request(testcase_data, log_data=False, relate_testcase=True)
value = jsonpath(response, testcase_data['set_var_jsonpath'])
value = findall(testcase_data['set_var_jsonpath'], response)
if value:
VariableCache().set(testcase_data['set_var_key'], value[0])
else:
Expand Down
6 changes: 3 additions & 3 deletions httpfpt/utils/request/vars_extractor.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import os.path
import re

from jsonpath import jsonpath
from jsonpath import findall

from httpfpt.common.env_handler import get_env_dict, write_env_vars
from httpfpt.common.log import log
Expand Down Expand Up @@ -130,9 +130,9 @@ def teardown_var_extract(response: dict, extract: list, env: str) -> None:
key = et['key']
set_type = et['type']
json_path = et['jsonpath']
value = jsonpath(response, json_path)
value = findall(json_path, response)
if value:
value = value[0]
value = str(value[0])
else:
raise ValueError(f'jsonpath 取值失败, 表达式: {json_path}')
if set_type == VarType.CACHE:
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ dirty_equals==0.6.0
faker==13.15.0
httpx==0.23.0
jinja2==3.1.2
jsonpath==0.82.2
loguru==0.6.0
openpyxl==3.0.7
pre-commit==3.2.2
Expand All @@ -20,6 +19,7 @@ pytest-pretty==1.2.0
pytest-xdist==2.5.0
python-dateutil==2.8.2
python-dotenv==0.20.0
python-jsonpath==0.9.0
pyyaml==6.0.1
redis==4.5.4
requests==2.31.0
Expand Down

0 comments on commit 2a30826

Please sign in to comment.