Skip to content

Commit 4d562a7

Browse files
authored
Merge pull request #119 from OpenTestSolar/bugfix/pytest-fix-parse-datadrive-bug
修复解析数据驱动问题
2 parents 676c735 + f205296 commit 4d562a7

5 files changed

Lines changed: 48 additions & 10 deletions

File tree

‎pytest/pyproject.toml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "testsolar-pytestx"
3-
version = "0.1.78"
3+
version = "0.1.79"
44
description = "Pytest tool for TestSolar"
55
authors = [
66
{name = "asiazhang2002", email = "asiazhang2002@gmail.com"},

‎pytest/src/testsolar_pytestx/converter.py‎

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from loguru import logger
66

77
CASE_DRIVE_SEPARATOR = "→"
8+
NAME_ATTR_PREFIX = "name="
89

910

1011
def selector_to_pytest(test_selector: str) -> str:
@@ -18,26 +19,34 @@ def selector_to_pytest(test_selector: str) -> str:
1819
# 只要出现 /[ 就说明该 selector 是一个真实的参数化用例节点,
1920
# 即使数据驱动数据中包含 "="(例如 sample_rate=0),也不应该被误判为属性筛选
2021
data_drive_flag = "/["
22+
# 数据驱动里的 & 属于数据内容(例如 [demand_name=测试&author_name=xx]),
23+
# 只有不含数据驱动标记时,& 才表示属性筛选:tests/hello_test.py?name=xxxTest&tag=prod
24+
is_attr_filter = data_drive_flag not in testcase
2125

2226
if "&" in testcase:
2327
testcase_attrs = testcase.split("&")
2428
for attr in testcase_attrs:
25-
if "name=" in attr: # tests/hello_test.py?name=xxxTest&tag=prod
26-
testcase = attr[5:]
29+
# 属性名只会出现在片段开头,不能用 in 判断:数据驱动中的参数名
30+
# (例如 demand_name=测试、product_name=xx)同样包含 name=,
31+
# 误判后 attr[len(NAME_ATTR_PREFIX):] 会把用例名截断
32+
if is_attr_filter and attr.startswith(NAME_ATTR_PREFIX):
33+
# tests/hello_test.py?name=xxxTest&tag=prod
34+
testcase = attr[len(NAME_ATTR_PREFIX) :]
2735
break
28-
elif "=" not in attr: # tests/hello_test.py?xxxTest&
36+
elif is_attr_filter and "=" not in attr:
37+
# tests/hello_test.py?xxxTest&tag=prod
2938
testcase = attr
3039
break
3140
else:
3241
# 所有属性均包含 "=",无法区分属性筛选与参数化用例
33-
if data_drive_flag not in testcase:
42+
if is_attr_filter:
3443
# 不含数据驱动标记,判定为纯属性筛选
3544
# tests/hello_test.py?test_hello_world&tag=prod
3645
return path
3746
else:
38-
if testcase.startswith("name="): # tests/hello_test.py?name=xxxTest
39-
testcase = testcase[5:]
40-
elif "=" in testcase and data_drive_flag not in testcase:
47+
if testcase.startswith(NAME_ATTR_PREFIX): # tests/hello_test.py?name=xxxTest
48+
testcase = testcase[len(NAME_ATTR_PREFIX) :]
49+
elif "=" in testcase and is_attr_filter:
4150
# tests/hello_test.py?tag=prod
4251
# 注意:参数化数据中可能包含 "=",例如
4352
# tests/test_asr_websocket.py?TestAsrWebSocket/test_sample_rate_parametrized/[0-default-sample_rate=0-False]

‎pytest/tests/test_converter.py‎

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,35 @@ def test_selector_to_pytest_with_equal_sign_in_http_datadrive(self):
9090
"tests/test_asr_http.py::TestASRRecognize::test_recognize_audio_format[summary_context-base64-pcm]",
9191
)
9292

93+
def test_selector_to_pytest_with_name_attr_in_datadrive(self):
94+
# 回归场景:数据驱动中包含 & 且参数名以 name= 结尾(demand_name=/mcn_name=/product_name=)
95+
# 不能被当成属性筛选,否则用例名会被截断(attr[5:])
96+
re = selector_to_pytest(
97+
"tests/qq/settlement/test_settlement.py?TestSettlementWalletMcnSettleFlow/test_settlement_wallet_mcn_settle_flow/[demand_name=测试&author_name=频道--发布&author_id=14124598&pay_status=2-expected=code:0]"
98+
)
99+
self.assertEqual(
100+
re,
101+
"tests/qq/settlement/test_settlement.py::TestSettlementWalletMcnSettleFlow::test_settlement_wallet_mcn_settle_flow[demand_name=\\u6d4b\\u8bd5&author_name=\\u9891\\u9053--\\u53d1\\u5e03&author_id=14124598&pay_status=2-expected=code:0]",
102+
)
103+
104+
# name= 出现在后面的参数上,同样不能截断用例名
105+
re = selector_to_pytest(
106+
"tests/qq/settlement/test_settlement.py?TestSettlementWalletAuthorPersonalSettleFlow/test_settlement_wallet_author_personal_settle_flow/[pay_status=2&demand_name=测试&demand_type=3-expected=code:0]"
107+
)
108+
self.assertEqual(
109+
re,
110+
"tests/qq/settlement/test_settlement.py::TestSettlementWalletAuthorPersonalSettleFlow::test_settlement_wallet_author_personal_settle_flow[pay_status=2&demand_name=\\u6d4b\\u8bd5&demand_type=3-expected=code:0]",
111+
)
112+
113+
re = selector_to_pytest(
114+
"tests/qq/settlement/test_settlement.py?TestSettlementBfcPersonList/test_settlement_bfc_person_list/[pay_status=2&mcn_name=中国移动通信集团江苏有限公司-expected=code:0]"
115+
)
116+
self.assertTrue(
117+
re.startswith(
118+
"tests/qq/settlement/test_settlement.py::TestSettlementBfcPersonList::test_settlement_bfc_person_list[pay_status=2&mcn_name="
119+
)
120+
)
121+
93122
def test_selector_to_pytest_with_utf8_string(self):
94123
re = selector_to_pytest(
95124
"/data/tests/tests/test_data_drive_zh_cn.py?aa/bb/test_include/[中文-中文汉字]"

‎pytest/testtool.yaml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ schemaVersion: 1.0
22
name: pytest
33
nameZh: pytest自动化测试
44
lang: python
5-
version: '0.1.78'
5+
version: '0.1.79'
66
langType: INTERPRETED
77
description: |-
88
pytest是一个成熟的全功能Python测试工具,可以帮助您编写更好的程序。此测试工具允许您在TestSolar上运行pytest。

‎pytest/uv.lock‎

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)