-
Notifications
You must be signed in to change notification settings - Fork 250
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: improve test speed #1017
feat: improve test speed #1017
Conversation
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #1017 +/- ##
=======================================
Coverage 91.76% 91.76%
=======================================
Files 181 181
Lines 6312 6312
=======================================
Hits 5792 5792
Misses 520 520 ☔ View full report in Codecov by Sentry. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
THIS IS FANTASTIC! Thank you so much for drastically improving the speed and the stability too! We definitely should go with this approach!
@@ -221,4 +221,4 @@ async def test_url_verification(self): | |||
|
|||
assert response.status_code == 200 | |||
assert response.headers.get("content-type") == "application/json;charset=utf-8" | |||
assert_auth_test_count(self, 1) | |||
assert_auth_test_count(self, 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed, this should be zero, but perhaps this had been wrong due to the current test runner mechanism's behavior, right? Nice improvement 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yess, I suspect this may be caused by the current test runner mechanism's behavior but I need to dig into each individual test to see what the expected behavior should be and why these values are different, there seem to be a few like these 🤔
tests/mock_web_api_server.py
Outdated
self.wfile.write("OK".encode("utf-8")) | ||
return | ||
|
||
if path == "/received_requests.json": | ||
if path == "/health": |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you using this endpoint? If we no longer need this, you can simply remove it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point 💯 I did add this to try and see if it would be more reliable to ensure the mock_web_api_server
responds with a success response before running the tests, there was no notable difference here
self.received_requests = {} | ||
|
||
def get(self, key, default=None): | ||
while not self.queue.empty(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is quite a wise approach 👍
tests/mock_web_api_server.py
Outdated
@@ -253,9 +257,22 @@ def stop(self): | |||
self.join() | |||
|
|||
|
|||
class ReceivedRequestsHandler: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is a matter of preference but this class does not handle anything but it just stores the received requests. If I named this, it would be a simpler one such as "ReceivedRequests" or "SavedReceivedRequests"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree 💯
tests/mock_web_api_server.py
Outdated
def setup_mock_web_api_server(test: TestCase): | ||
test.server_started = threading.Event() | ||
test.thread = MockServerThread(test) | ||
test.received_requests_handler = ReceivedRequestsHandler(Queue()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the same reason I mentioned above, test.received_requests.get("/auth.test")
sounds more natural to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree 💯
@@ -77,7 +74,7 @@ class TestExecutor(Executor): | |||
|
|||
def test_valid_single_auth(self): | |||
app = App(signing_secret="valid", client=self.web_client) | |||
assert app != None | |||
assert app is not None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good catch
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
True, but I think I'll remove these changes in order to simplify the PR, I can do this in a follow up
@@ -38,9 +39,9 @@ def handle_app_mention(say): | |||
response = app.dispatch(request) | |||
assert response.status == 200 | |||
assert_auth_test_count(self, 1) | |||
sleep(1) # wait a bit after auto ack() | |||
sleep(0.5) # wait a bit after auto ack() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this still necessary?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yess this is still required since we are asserting that an endpoint was not executed
If we validate without waiting we may assert the request was not sent before it gets sent
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I see. that makes sense
Co-authored-by: Kazuhiro Sera <[email protected]>
Co-authored-by: Kazuhiro Sera <[email protected]>
…amBergamin/bolt-python into reduce-sleep-time-in-tests
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great to me 👍 You can merge this PR at any time
@@ -38,9 +39,9 @@ def handle_app_mention(say): | |||
response = app.dispatch(request) | |||
assert response.status == 200 | |||
assert_auth_test_count(self, 1) | |||
sleep(1) # wait a bit after auto ack() | |||
sleep(0.5) # wait a bit after auto ack() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I see. that makes sense
@seratch I understood why some
I'm assuming the changes regarding the auth_test assertion count now reflect the behavior of bolt python |
Flow up to the discussion started in #1015
This PR aims to improvement on the
mock_web_api_server
by making it more robust and attempts to reduce the time spent sleeping in test ("Run tests without aiohttp")This is achieved by incorporating a solution that allows for waiting up to a specified duration (X amount of time) to confirm the receipt of requests, instead of waiting for a fixed period and then confirming the reception of requests.
Previously, the test located in "Run tests without aiohttp" required 93 seconds for execution. With these changes, the tests can now be completed in just 24 seconds, resulting in a nearly fourfold reduction in wait time.
Similar changes can be applied to asynchronous test and similar reduction in wait time can also be expected for this as well
NOTE: adding content length header to the
mock_web_api_server
drastically improved request reliabilityBefore
After
Feedback
The code can be made clearer and there may be some changes that are not necessary, please point out anything that seems relevant
Is this approach worth implementing?
Category (place an
x
in each of the[ ]
)slack_bolt.App
and/or its core componentsslack_bolt.async_app.AsyncApp
and/or its core componentsslack_bolt.adapter
/docs
Requirements (place an
x
in each[ ]
)Please read the Contributing guidelines and Code of Conduct before creating this issue or pull request. By submitting, you are agreeing to those rules.
./scripts/install_all_and_run_tests.sh
after making the changes.