Repository navigation
Conversation
|
Thanks for the contribution! Before we can merge this, we need @Mohith26 to sign the Salesforce Inc. Contributor License Agreement. |
Member
|
Thanks @Mohith26 for putting this together! 🙇 It's a big addition, so we're discussing it as a team and will follow up here. |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds
slack_bolt.testing, built-in support for unit testing Bolt apps without connecting to Slack (#380). It follows the approach Bolt's owntests/scenario_testsuse (a local mock server plus signed requests), packaged so app developers don't have to rebuild it. No new dependencies; the server uses the standard library.MockSlackServer: an in-process HTTP server that stands in for the Web API and forresponse_url. It records every API call (method, parsed args, token) and every message posted to aresponse_url.auth.testreturns a bot installation by default, other methods return{"ok": true}, andset_response()sets canned responses, includingok: falseerrors that raiseSlackApiErrorlike the real API.BoltTestClient(app, server): builds signed requests for events, messages, slash commands, block actions, global and message shortcuts, and view submissions, and sends them throughapp.dispatch(). It returns aDispatchResultwith the ackstatus/body/json, plus the API calls andrespond()bodies that request caused.AsyncBoltTestClient(inslack_bolt.testing.async_client, so sync users don't import aiohttp) does the same forAsyncApp.slack_bolt.testing.payloads: the payload builders on their own, plusto_http_body()andsigned_headers().Example:
Requests go through the full middleware chain (request verification, authorization, listener matching). Two design choices worth flagging:
BoltTestClientruns listeners and lazy listeners inline (anInlineExecutoron the app's listener runner), so side effects are done when the call returns even withprocess_before_response=False. The async client instead waits for the tasks the dispatch started, with a timeout.app.client.base_urlat the mock server, so apps created at import time with a real token (andtoken_verification_enabled=False) can be tested without restructuring.There is a new docs page,
docs/english/concepts/testing.md, linked from the sidebar. I posted the design on #380 first; happy to rename things, trim the scope (for example ship only the payload builders and server first), or move it to a separate package if you'd rather not add public API toslack_bolt.Testing
tests/slack_bolt/testing/test_testing.pyandtests/slack_bolt_async/testing/test_async_testing.py(19 tests): recorded calls and canned responses, error responses, slash command ack +respond(),say()from a message listener, listeners that finish after ack withprocess_before_response=False, lazy listeners, block actions andviews.open, view submissionresponse_actionerrors, both shortcut types, 404 for unhandled requests and 401 for a bad signature, 500 for a listener error, an app created with a default client, payload encoding and signatures, and the async timeout.pytest tests/slack_bolt tests/slack_bolt_async tests/scenario_tests tests/scenario_tests_async: 849 passed../scripts/format.sh --no-install,./scripts/lint.sh --no-install: clean.mypy slack_bolt/testing: no issues. The full./scripts/run_mypy.shonly reports errors in adapter modules whose optional dependencies I don't have installed../scripts/install_all_and_run_tests.sh, so the adapter test suites (which need the optional framework dependencies) were not run locally. This change doesn't touch adapters.I used an AI assistant (Claude) while writing this; I reviewed and tested all of it.
Category
slack_bolt.Appand/or its core componentsslack_bolt.async_app.AsyncAppand/or its core componentsslack_bolt.adapter/docsRequirements
./scripts/install_all_and_run_tests.shafter making the changes. (See Testing: core and scenario suites run, adapter suites not run locally.)