pytest测试Slack API时无法返回自定义错误原因的解决问询
如何修改Slack API的pytest测试脚本以返回自定义错误信息?
问题背景
我用Python的Slack SDK编写pytest测试脚本,用于验证Slack API请求的有效性,希望测试失败时返回Slack WebClient提供的具体失败原因。但故意使用错误API token测试时,仅收到通用的请求失败提示,而非包含具体原因的自定义信息。
现有代码
import sys import time import pytest from slack_sdk import WebClient, errors import ssl slack_token = 'xoxb-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' channel_id = "C00000000" ssl_context = ssl.create_default_context() ssl_context.check_hostname = False ssl_context.verify_mode = ssl.CERT_NONE client = WebClient(token=slack_token, ssl=ssl_context) def test_api_call(status=True): """ Test which checks whether or not the API call to conversations_history returns and 'ok' status. If it fails, the error message will be returned. """ result = client.conversations_history( channel = channel_id, inclusive = True, oldest = str(time.time()-3600), latest = str(time.time()), limit = 100 ) assert result["ok"] == status, \ f"Expected {status}. Actual status {result['ok']}. Response text {result['error']}"
当前错误输出
test_alerts.py:25: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../../.local/share/virtualenvs/new_project-RFzzfWjC/lib/python3.10/site-packages/slack_sdk/web/client.py:2488: in conversations_history return self.api_call("conversations.history", http_verb="GET", params=kwargs) ../../.local/share/virtualenvs/new_project-RFzzfWjC/lib/python3.10/site-packages/slack_sdk/web/base_client.py:156: in api_call return self._sync_send(api_url=api_url, req_args=req_args) ../../.local/share/virtualenvs/new_project-RFzzfWjC/lib/python3.10/site-packages/slack_sdk/web/base_client.py:187: in _sync_send return self._urllib_api_call( ../../.local/share/virtualenvs/new_project-RFzzfWjC/lib/python3.10/site-packages/slack_sdk/web/base_client.py:317: in _urllib_api_call ).validate() _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <slack_sdk.web.slack_response.SlackResponse object at 0x101a8d1b0> def validate(self): """Check if the response from Slack was successful. Returns: (SlackResponse) This method returns it's own object. e.g. 'self' Raises: SlackApiError: The request to the Slack API failed. """ if self.status_code == 200 and self.data and (isinstance(self.data, bytes) or self.data.get("ok", False)): return self msg = f"The request to the Slack API failed. (url: {self.api_url})" > raise e.SlackApiError(message=msg, response=self) E slack_sdk.errors.SlackApiError: The request to the Slack API failed. (url: https://www.slack.com/api/conversations.history) E The server responded with: {'ok': False, 'error': 'invalid_auth'} ../../.local/share/virtualenvs/new_project-RFzzfWjC/lib/python3.10/site-packages/slack_sdk/web/slack_response.py:199: SlackApiError ====================================================================== short test summary info ====================================================================== FAILED test_alerts.py::test_api_call - slack_sdk.errors.SlackApiError: The request to the Slack API failed. (url: https://www.slack.com/api/conversations.history) ========================================================================= 1 failed in 1.04s =========================================================================
期望输出
FAILED test_alerts.py::test_api_call - slack_sdk.errors.SlackApiError: Expected True. Actual status False. Response text invalid_auth ========================================================================= 1 failed in 1.04s =========================================================================
Slack API官方错误响应示例
{ "ok": false, "error": "invalid_auth" }
解决方案
问题出在Slack SDK的默认行为:当API返回ok: false时,WebClient会自动抛出SlackApiError异常,你的断言代码根本没机会执行。要获取自定义错误信息,需要捕获这个异常并从中提取具体错误数据。
修改后的代码如下:
import sys import time import pytest from slack_sdk import WebClient, errors import ssl slack_token = 'xoxb-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' channel_id = "C00000000" ssl_context = ssl.create_default_context() ssl_context.check_hostname = False ssl_context.verify_mode = ssl.CERT_NONE client = WebClient(token=slack_token, ssl=ssl_context) def test_api_call(status=True): """测试conversations_history API调用是否返回'ok'状态,失败时返回具体错误原因""" try: result = client.conversations_history( channel = channel_id, inclusive = True, oldest = str(time.time()-3600), latest = str(time.time()), limit = 100 ) assert result["ok"] == status, \ f"Expected {status}. Actual status {result['ok']}. Response text {result['error']}" except errors.SlackApiError as e: # 从异常响应中提取Slack返回的具体错误信息 response_data = e.response.data assert response_data["ok"] == status, \ f"Expected {status}. Actual status {response_data['ok']}. Response text {response_data['error']}"
修改说明
- 添加
try-except块捕获SlackApiError异常,确保API失败时不会直接终止测试 - 从异常对象的
e.response.data中获取完整的Slack响应数据,包含ok和error字段 - 在异常处理块中执行相同的断言逻辑,构造自定义的错误提示信息
这样测试失败时,pytest就会输出你期望的包含具体错误原因的提示。
内容的提问来源于stack exchange,提问作者Keith Cozart
相关产品推荐
相关产品推荐

