Skip to content

Conversation

@mwbrooks
Copy link
Member

@mwbrooks mwbrooks commented Apr 7, 2025

Summary

Depends on PR #7 and ready for review when PR #7 is merged.

This pull request updates testutil.TableTestCommand to use a mocked context and executes the command with the provided context.

Currently, the testutil.TableTestCommand doesn't define a context. This has 2 drawbacks:

  1. Each test uses it's own context.Background() and must manually mock the context to include required value that are initialized when a CLI command is run (e.g. SessionID).
  2. Mocked context values - typically done in .Setup(...) - are not available to the Cobra command or any cmd.Context() calls.

By having testutil.TableTestCommand mock the context, pass it to .Setup, and then execute the command with the same context, we match how the CLI initializes and executes a command in main.go and cmd/root.go.

A small improvement may be for the .Setup to return a ctx. However, this is only important when the context is modified and we don't do that right now.

Requirements

@mwbrooks mwbrooks added code health M-T: Test improvements and anything that improves code health semver:patch Use on pull requests to describe the release version increment labels Apr 7, 2025
@mwbrooks mwbrooks added this to the Next Release milestone Apr 7, 2025
@mwbrooks mwbrooks self-assigned this Apr 7, 2025
Copy link
Member Author

@mwbrooks mwbrooks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hope the 200 lines don't scare you off. It should be easy scrolling and I've left a few comments to guide you through the repetition to the important parts!

ExpectedAsserts func(*testing.T, *shared.ClientsMock) // Optional
ExpectedError error // Optional
ExpectedErrorStrings []string // Optional
Setup func(*testing.T, context.Context, *shared.ClientsMock, *shared.ClientFactory) // Optional
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: 💠 This is the main change of the pull request and the arguments below are only showing as changed because the comment indentation was adjusted by the formatter.

for name, tt := range commandTests {
t.Run(name, func(t *testing.T) {
// Create mocks
ctxMock := slackcontext.MockContext(t.Context())
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: Here we mock the context with the standard values that a new CLI process will initialize.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉 It's so neat that this can be used for both setup and execution. One context for all!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea, it's nice. I wonder how we can document that values set in MockContext are the values "guaranteed" to exist when a Cobra command executes (cmd.ExecuteContext(ctx))? Perhaps we can document this in the header of slackcontext.go? For example, Golang's context.go has a large comment block above the package context to explain the usage of it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow I'm fascinated with the godoc standards of this upstream. I know go claims to not have ideal standards here, but we should feel generous with this documentation! 📚 ✨

// Setup custom mocks (higher priority than default mocks)
if tt.Setup != nil {
tt.Setup(t, clientsMock, clients)
tt.Setup(t, ctxMock, clientsMock, clients)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: Here we pass the mocked context into .Setup and in the future we could return the ctx in case it's been modified by .Setup

// Execute the command
cmd.SetArgs(tt.CmdArgs)
err := cmd.Execute()
err := cmd.ExecuteContext(ctxMock)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: ⚡ We now execute the command with the context, so that cmd.Context() will return this context. This matches how root.go executes the CLI with cmd.ExecuteContext(ctx).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One small change to arguments and one giant change for testing commands 🚀 ✨

"errors if not run in a project directory": {
ExpectedError: slackerror.New(slackerror.ErrInvalidAppDirectory),
Setup: func(t *testing.T, cm *shared.ClientsMock, cf *shared.ClientFactory) {
Setup: func(t *testing.T, ctx context.Context, cm *shared.ClientsMock, cf *shared.ClientFactory) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: This change is made about 200 times 😆 Scroll down to the very bottom to see the updates to testutil.TableTestCommand that implement this feature. ⬇️

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Praises @mwbrooks! This is a tedious but meaningful change 🎁

Base automatically changed from mbrooks-slackcontext to main April 8, 2025 23:31
@mwbrooks mwbrooks marked this pull request as ready for review April 8, 2025 23:39
@mwbrooks mwbrooks requested a review from a team as a code owner April 8, 2025 23:39
Copy link
Member

@zimeg zimeg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧪 What a wonderful and focused PR this is for testing improvements.

I'm excited for this as more commands begin to follow this table testing pattern and the code being tested uses a single context. These are all great changes being made 🚢 💨

"errors if not run in a project directory": {
ExpectedError: slackerror.New(slackerror.ErrInvalidAppDirectory),
Setup: func(t *testing.T, cm *shared.ClientsMock, cf *shared.ClientFactory) {
Setup: func(t *testing.T, ctx context.Context, cm *shared.ClientsMock, cf *shared.ClientFactory) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Praises @mwbrooks! This is a tedious but meaningful change 🎁

// Execute the command
cmd.SetArgs(tt.CmdArgs)
err := cmd.Execute()
err := cmd.ExecuteContext(ctxMock)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One small change to arguments and one giant change for testing commands 🚀 ✨

for name, tt := range commandTests {
t.Run(name, func(t *testing.T) {
// Create mocks
ctxMock := slackcontext.MockContext(t.Context())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉 It's so neat that this can be used for both setup and execution. One context for all!

@mwbrooks
Copy link
Member Author

mwbrooks commented Apr 9, 2025

Thanks for taking the time to review this PR @zimeg! 🙇🏻 I agree, it'll be nice to get our tests to be more consistent. I didn't expect this work to move that forward, but it is! 🧪

@mwbrooks mwbrooks merged commit 4098541 into main Apr 9, 2025
6 checks passed
@mwbrooks mwbrooks deleted the mbrooks-slackcontext-tabletestcommand branch April 9, 2025 17:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

code health M-T: Test improvements and anything that improves code health semver:patch Use on pull requests to describe the release version increment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants