pytest-api-framework-alpha 0.3.6__tar.gz → 0.3.7__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pytest_api_framework_alpha-0.3.6 → pytest_api_framework_alpha-0.3.7}/PKG-INFO +1 -1
- {pytest_api_framework_alpha-0.3.6 → pytest_api_framework_alpha-0.3.7}/framework/base_class.py +69 -3
- {pytest_api_framework_alpha-0.3.6 → pytest_api_framework_alpha-0.3.7}/framework/conftest.py +5 -1
- {pytest_api_framework_alpha-0.3.6 → pytest_api_framework_alpha-0.3.7}/framework/http_client.py +1 -0
- pytest_api_framework_alpha-0.3.7/framework/utils/lark_util.py +71 -0
- {pytest_api_framework_alpha-0.3.6 → pytest_api_framework_alpha-0.3.7}/pytest_api_framework_alpha.egg-info/PKG-INFO +1 -1
- {pytest_api_framework_alpha-0.3.6 → pytest_api_framework_alpha-0.3.7}/pytest_api_framework_alpha.egg-info/SOURCES.txt +1 -0
- {pytest_api_framework_alpha-0.3.6 → pytest_api_framework_alpha-0.3.7}/setup.py +1 -1
- {pytest_api_framework_alpha-0.3.6 → pytest_api_framework_alpha-0.3.7}/framework/__init__.py +0 -0
- {pytest_api_framework_alpha-0.3.6 → pytest_api_framework_alpha-0.3.7}/framework/db/__init__.py +0 -0
- {pytest_api_framework_alpha-0.3.6 → pytest_api_framework_alpha-0.3.7}/framework/db/mysql_db.py +0 -0
- {pytest_api_framework_alpha-0.3.6 → pytest_api_framework_alpha-0.3.7}/framework/db/redis_db.py +0 -0
- {pytest_api_framework_alpha-0.3.6 → pytest_api_framework_alpha-0.3.7}/framework/exceptions.py +0 -0
- {pytest_api_framework_alpha-0.3.6 → pytest_api_framework_alpha-0.3.7}/framework/exit_code.py +0 -0
- {pytest_api_framework_alpha-0.3.6 → pytest_api_framework_alpha-0.3.7}/framework/extract.py +0 -0
- {pytest_api_framework_alpha-0.3.6 → pytest_api_framework_alpha-0.3.7}/framework/global_attribute.py +0 -0
- {pytest_api_framework_alpha-0.3.6 → pytest_api_framework_alpha-0.3.7}/framework/render_data.py +0 -0
- {pytest_api_framework_alpha-0.3.6 → pytest_api_framework_alpha-0.3.7}/framework/report.py +0 -0
- {pytest_api_framework_alpha-0.3.6 → pytest_api_framework_alpha-0.3.7}/framework/script.py +0 -0
- {pytest_api_framework_alpha-0.3.6 → pytest_api_framework_alpha-0.3.7}/framework/startapp.py +0 -0
- {pytest_api_framework_alpha-0.3.6 → pytest_api_framework_alpha-0.3.7}/framework/utils/__init__.py +0 -0
- {pytest_api_framework_alpha-0.3.6 → pytest_api_framework_alpha-0.3.7}/framework/utils/common.py +0 -0
- {pytest_api_framework_alpha-0.3.6 → pytest_api_framework_alpha-0.3.7}/framework/utils/date_util.py +0 -0
- {pytest_api_framework_alpha-0.3.6 → pytest_api_framework_alpha-0.3.7}/framework/utils/encrypt.py +0 -0
- {pytest_api_framework_alpha-0.3.6 → pytest_api_framework_alpha-0.3.7}/framework/utils/log_util.py +0 -0
- {pytest_api_framework_alpha-0.3.6 → pytest_api_framework_alpha-0.3.7}/framework/utils/mock_util.py +0 -0
- {pytest_api_framework_alpha-0.3.6 → pytest_api_framework_alpha-0.3.7}/framework/utils/yaml_util.py +0 -0
- {pytest_api_framework_alpha-0.3.6 → pytest_api_framework_alpha-0.3.7}/framework/validate.py +0 -0
- {pytest_api_framework_alpha-0.3.6 → pytest_api_framework_alpha-0.3.7}/pytest_api_framework_alpha.egg-info/dependency_links.txt +0 -0
- {pytest_api_framework_alpha-0.3.6 → pytest_api_framework_alpha-0.3.7}/pytest_api_framework_alpha.egg-info/requires.txt +0 -0
- {pytest_api_framework_alpha-0.3.6 → pytest_api_framework_alpha-0.3.7}/pytest_api_framework_alpha.egg-info/top_level.txt +0 -0
- {pytest_api_framework_alpha-0.3.6 → pytest_api_framework_alpha-0.3.7}/setup.cfg +0 -0
{pytest_api_framework_alpha-0.3.6 → pytest_api_framework_alpha-0.3.7}/framework/base_class.py
RENAMED
|
@@ -64,7 +64,7 @@ class BaseTestCase(ExtendBaseTestCase):
|
|
|
64
64
|
data = RenderData(data).render()
|
|
65
65
|
data.request.url = self.replace_domain(data.request.url, domain)
|
|
66
66
|
try:
|
|
67
|
-
self.response = getattr(app_http, account).request(data=data, kwargs
|
|
67
|
+
self.response = getattr(app_http, account).request(data=data, **kwargs)
|
|
68
68
|
except AttributeError as e:
|
|
69
69
|
raise GetAccountError(e)
|
|
70
70
|
if self.response.status_code in UNAUTHORIZED_CODE:
|
|
@@ -194,11 +194,77 @@ class BaseTestCase(ExtendBaseTestCase):
|
|
|
194
194
|
"""
|
|
195
195
|
return set_customized_kytmock(self.context.get("env"), request_id, payment_type, risk_level, is_delayed)
|
|
196
196
|
|
|
197
|
-
def mock_mq_message(self,target_exchange,exchange_type,message,routing_key:str=None):
|
|
197
|
+
def mock_mq_message(self, target_exchange, exchange_type, message, routing_key: str = None):
|
|
198
198
|
"""
|
|
199
199
|
target_exchange:目标交换机名称
|
|
200
200
|
exchange_type:交换机类型,枚举:fanout,direct,topic,header
|
|
201
201
|
message:消息体,json格式
|
|
202
202
|
routing_key: 路由关键字,默认为null
|
|
203
203
|
"""
|
|
204
|
-
return
|
|
204
|
+
return mock_mq(self.context.get("env"), target_exchange, exchange_type, message, routing_key)
|
|
205
|
+
|
|
206
|
+
def regenerate_hot_wallet_for_psp(self, participant_code):
|
|
207
|
+
"""
|
|
208
|
+
|
|
209
|
+
:param participant_code: partner或end-user的code
|
|
210
|
+
:return:
|
|
211
|
+
"""
|
|
212
|
+
# 删除wallet_service中的钱包
|
|
213
|
+
self.logger.info(f"重置{participant_code}热钱包")
|
|
214
|
+
wallet_service = self.mysql_conn(db=self.db.DB_WALLET_SERVICE)
|
|
215
|
+
wallet_service.execute(
|
|
216
|
+
f"delete from tbl_wallet_coin where wallet_key in (select wallet_key from tbl_wallet where participant_code='{participant_code}');")
|
|
217
|
+
wallet_service.execute(f"delete from tbl_wallet where participant_code='{participant_code}';")
|
|
218
|
+
# 删除blockchain_service中的钱包
|
|
219
|
+
self.mysql_conn(self.db.DB_BLOCKCHAIN_SERVICE).execute(
|
|
220
|
+
f"delete from hot_wallethsm where participant_code='{participant_code}';")
|
|
221
|
+
# 删除crm中钱包
|
|
222
|
+
crm = self.mysql_conn(db=self.db.DB_CAMP_CRM)
|
|
223
|
+
crm.execute(
|
|
224
|
+
f"delete from tbl_crypto_wallet where id in (select wallet_id from tbl_participant_crypto_wallet where participant_code='{participant_code}');")
|
|
225
|
+
crm.execute(f"delete from tbl_participant_crypto_wallet where participant_code='{participant_code}';")
|
|
226
|
+
|
|
227
|
+
# 重新生成新钱包
|
|
228
|
+
self.post(
|
|
229
|
+
app="camp_admin",
|
|
230
|
+
account="admin",
|
|
231
|
+
url="/prod-api/crm/participant/createHotWallet.do",
|
|
232
|
+
json={"participantCode": participant_code}
|
|
233
|
+
)
|
|
234
|
+
assert self.response.code == 0
|
|
235
|
+
|
|
236
|
+
def regenerate_hot_wallet_for_buyer(self, partner_account, merchant_participant_code, buyer_participant_code):
|
|
237
|
+
"""
|
|
238
|
+
|
|
239
|
+
:param partner_account: partner账号
|
|
240
|
+
:param merchant_participant_code: merchant code
|
|
241
|
+
:param buyer_participant_code: buyer code
|
|
242
|
+
:return:
|
|
243
|
+
"""
|
|
244
|
+
# 删除wallet_service中的钱包
|
|
245
|
+
self.logger.info(f"重置{buyer_participant_code}热钱包")
|
|
246
|
+
wallet_service = self.mysql_conn(db=self.db.DB_WALLET_SERVICE)
|
|
247
|
+
wallet_service.execute(
|
|
248
|
+
f"delete from tbl_wallet_coin where wallet_key in (select wallet_key from tbl_wallet where participant_code='{buyer_participant_code}');")
|
|
249
|
+
wallet_service.execute(f"delete from tbl_wallet where participant_code='{buyer_participant_code}';")
|
|
250
|
+
# 删除blockchain_service中的钱包
|
|
251
|
+
self.mysql_conn(self.db.DB_BLOCKCHAIN_SERVICE).execute(
|
|
252
|
+
f"delete from hot_wallethsm where participant_code='{buyer_participant_code}';")
|
|
253
|
+
# 删除crm中钱包
|
|
254
|
+
crm = self.mysql_conn(db=self.db.DB_CAMP_CRM)
|
|
255
|
+
crm.execute(
|
|
256
|
+
f"delete from tbl_crypto_wallet where id in (select crypto_wallet_id from tbl_buyer_crypto_wallet where participant_code='{buyer_participant_code}');")
|
|
257
|
+
crm.execute(f"delete from tbl_buyer_crypto_wallet where participant_code='{buyer_participant_code}';")
|
|
258
|
+
|
|
259
|
+
# 重新生成新钱包
|
|
260
|
+
self.post(
|
|
261
|
+
app="psp_api",
|
|
262
|
+
account=partner_account,
|
|
263
|
+
url="/v1.0/crm/deposit/createWallet",
|
|
264
|
+
json={
|
|
265
|
+
"participantCode": merchant_participant_code,
|
|
266
|
+
"buyerId": buyer_participant_code,
|
|
267
|
+
"expiry": 0
|
|
268
|
+
}
|
|
269
|
+
)
|
|
270
|
+
assert self.response.code == 200
|
|
@@ -25,6 +25,7 @@ from framework.exit_code import ExitCode
|
|
|
25
25
|
from framework.db.mysql_db import MysqlDB
|
|
26
26
|
from framework.db.redis_db import RedisDB
|
|
27
27
|
from framework.utils.log_util import logger
|
|
28
|
+
from framework.utils.lark_util import LarkUtil
|
|
28
29
|
from framework.utils.yaml_util import CachedYamlLoader
|
|
29
30
|
from framework.exceptions import MysqlDBError, RedisDBError
|
|
30
31
|
from framework.global_attribute import CONTEXT, CONFIG, _FRAMEWORK_CONTEXT
|
|
@@ -522,11 +523,13 @@ def pytest_terminal_summary(terminalreporter, exitstatus, config):
|
|
|
522
523
|
terminalreporter.write(f"用例通过率: {pass_rate}%\n", green=True, bold=True)
|
|
523
524
|
terminalreporter.write("====================================\n", blue=True, bold=True)
|
|
524
525
|
CONTEXT.set("summary", {
|
|
526
|
+
"total": total,
|
|
525
527
|
"passed": passed,
|
|
526
528
|
"failed": failed,
|
|
527
529
|
"skipped": skipped,
|
|
528
|
-
"
|
|
530
|
+
"pass_rate": pass_rate
|
|
529
531
|
})
|
|
532
|
+
# LarkUtil(settings.LARK_WEBHOOK).send_test_report(total=total, passed=passed, failed=failed, skipped=skipped)
|
|
530
533
|
|
|
531
534
|
|
|
532
535
|
def pytest_exception_interact(node, call, report):
|
|
@@ -577,6 +580,7 @@ def inner_login(app):
|
|
|
577
580
|
expire_time = datetime.now() + timedelta(seconds=token_expiry)
|
|
578
581
|
_FRAMEWORK_CONTEXT.set(app=app, key="expire_time", value=expire_time)
|
|
579
582
|
|
|
583
|
+
|
|
580
584
|
def login():
|
|
581
585
|
def safe_call(func, name):
|
|
582
586
|
try:
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import requests
|
|
2
|
+
import json
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class LarkUtil:
|
|
6
|
+
def __init__(self, webhook: str):
|
|
7
|
+
self.webhook = webhook
|
|
8
|
+
self.headers = {"Content-Type": "application/json"}
|
|
9
|
+
|
|
10
|
+
def send_text(self, text: str, at_ids=None):
|
|
11
|
+
data = {
|
|
12
|
+
"msg_type": "text",
|
|
13
|
+
"content": {"text": text},
|
|
14
|
+
}
|
|
15
|
+
if at_ids:
|
|
16
|
+
data["at"] = {"open_ids": at_ids}
|
|
17
|
+
return requests.post(self.webhook, data=json.dumps(data), headers=self.headers)
|
|
18
|
+
|
|
19
|
+
def send_markdown(self, title: str, markdown_text: str):
|
|
20
|
+
"""发送 Markdown 消息"""
|
|
21
|
+
|
|
22
|
+
data = {
|
|
23
|
+
"msg_type": "interactive",
|
|
24
|
+
"card": {
|
|
25
|
+
"header": {
|
|
26
|
+
"template": "blue",
|
|
27
|
+
"title": {"tag": "plain_text", "content": title}
|
|
28
|
+
},
|
|
29
|
+
"elements": [
|
|
30
|
+
{
|
|
31
|
+
"tag": "markdown",
|
|
32
|
+
"content": markdown_text
|
|
33
|
+
}
|
|
34
|
+
]
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
resp = requests.post(self.webhook, headers=self.headers, data=json.dumps(data))
|
|
39
|
+
return resp.text
|
|
40
|
+
|
|
41
|
+
def send_test_report(self, total: int, passed: int, failed: int, skipped: int, report_url: str = None):
|
|
42
|
+
"""自动化测试结果消息(Markdown)"""
|
|
43
|
+
try:
|
|
44
|
+
pass_rate = round(passed / (total - skipped) * 100, 2)
|
|
45
|
+
except ZeroDivisionError:
|
|
46
|
+
pass_rate = 0
|
|
47
|
+
markdown = f"""
|
|
48
|
+
**执行统计:**
|
|
49
|
+
**执行用例总数:** {total}
|
|
50
|
+
**通过用例数:** {passed}
|
|
51
|
+
**失败用例数:** {failed}
|
|
52
|
+
**跳过用例数:** {skipped}
|
|
53
|
+
**用例通过率:** {pass_rate}%
|
|
54
|
+
"""
|
|
55
|
+
if report_url:
|
|
56
|
+
markdown += f"\n\t**测试报告:** 👉 [点击查看测试报告]({report_url})"
|
|
57
|
+
return self.send_markdown("自动化测试结果", markdown)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
if __name__ == "__main__":
|
|
61
|
+
# 你的飞书群机器人 Webhook URL
|
|
62
|
+
WEBHOOK = "https://open.larksuite.com/open-apis/bot/v2/hook/27de2bf2-fa0d-49e7-8ff3-a3e3ad8cf2d7"
|
|
63
|
+
bot = LarkUtil(WEBHOOK)
|
|
64
|
+
|
|
65
|
+
bot.send_test_report(
|
|
66
|
+
total=20,
|
|
67
|
+
passed=18,
|
|
68
|
+
failed=1,
|
|
69
|
+
skipped=1,
|
|
70
|
+
report_url="http://your-report/index.html"
|
|
71
|
+
)
|
|
File without changes
|
{pytest_api_framework_alpha-0.3.6 → pytest_api_framework_alpha-0.3.7}/framework/db/__init__.py
RENAMED
|
File without changes
|
{pytest_api_framework_alpha-0.3.6 → pytest_api_framework_alpha-0.3.7}/framework/db/mysql_db.py
RENAMED
|
File without changes
|
{pytest_api_framework_alpha-0.3.6 → pytest_api_framework_alpha-0.3.7}/framework/db/redis_db.py
RENAMED
|
File without changes
|
{pytest_api_framework_alpha-0.3.6 → pytest_api_framework_alpha-0.3.7}/framework/exceptions.py
RENAMED
|
File without changes
|
{pytest_api_framework_alpha-0.3.6 → pytest_api_framework_alpha-0.3.7}/framework/exit_code.py
RENAMED
|
File without changes
|
|
File without changes
|
{pytest_api_framework_alpha-0.3.6 → pytest_api_framework_alpha-0.3.7}/framework/global_attribute.py
RENAMED
|
File without changes
|
{pytest_api_framework_alpha-0.3.6 → pytest_api_framework_alpha-0.3.7}/framework/render_data.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pytest_api_framework_alpha-0.3.6 → pytest_api_framework_alpha-0.3.7}/framework/utils/__init__.py
RENAMED
|
File without changes
|
{pytest_api_framework_alpha-0.3.6 → pytest_api_framework_alpha-0.3.7}/framework/utils/common.py
RENAMED
|
File without changes
|
{pytest_api_framework_alpha-0.3.6 → pytest_api_framework_alpha-0.3.7}/framework/utils/date_util.py
RENAMED
|
File without changes
|
{pytest_api_framework_alpha-0.3.6 → pytest_api_framework_alpha-0.3.7}/framework/utils/encrypt.py
RENAMED
|
File without changes
|
{pytest_api_framework_alpha-0.3.6 → pytest_api_framework_alpha-0.3.7}/framework/utils/log_util.py
RENAMED
|
File without changes
|
{pytest_api_framework_alpha-0.3.6 → pytest_api_framework_alpha-0.3.7}/framework/utils/mock_util.py
RENAMED
|
File without changes
|
{pytest_api_framework_alpha-0.3.6 → pytest_api_framework_alpha-0.3.7}/framework/utils/yaml_util.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|