-
Notifications
You must be signed in to change notification settings - Fork 256
Implement retry flaky steps #684
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
base: main
Are you sure you want to change the base?
Conversation
* retry failed pickles * revert some changes * use example steps from cck * update example * implement retry with godog.ErrRetry * unit test for retry flaky * Update flaky feature description * add --retry to CLI option * update test * update test for --retry cli option * update test * handle err without printing retry steps * storage methods to upsert step result * rename wording * revert change * update feature test (will remove this feature) * revert unused files * revert unused files * improve readability * remove unused code * cleanup
* retry failed pickles * revert some changes * use example steps from cck * update example * implement retry with godog.ErrRetry * unit test for retry flaky * Update flaky feature description * add --retry to CLI option * update test * update test for --retry cli option * update test * handle err without printing retry steps * storage methods to upsert step result * rename wording * revert change * update feature test (will remove this feature) * revert unused files * revert unused files * improve readability * remove unused code * cleanup * update changelog
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.
Some minor fixes suggested. However a larger question is, are you seeking conformance with standard cucumber execution / cck conformance (I know you might not be there yet).
The reason why, is that a lot of your implementation details surrounding the specific status is unique and not what all standard implementors do
_examples/retry-flaky/godogs_test.go
Outdated
sc.Step(`^a step that passes the second time`, func(ctx context.Context) (context.Context, error) { | ||
secondTimePass++ | ||
if secondTimePass < 2 { | ||
return ctx, fmt.Errorf("unexpected network connection, %w", godog.ErrRetry) |
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 stuff that will inevitably become part of living documentation I would make this more informative than obfuscating.
See https://github.com/cucumber/compatibility-kit/blob/main/devkit/samples/retry/retry.feature.ts (Which in itself probably could be a bit better)
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.
Right, I think I should just return godog.ErrRetry instead.
_examples/retry-flaky/godogs_test.go
Outdated
return ctx, nil | ||
}) | ||
|
||
fifthTimePass := 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.
This should be removed as we want this always to fail. The conditional below should also be removed. It should always return the formatted error
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.
Yes I agree, this folder is for examples, I should not add this case here (this case is supposed to be in unit test over here only).
internal/flags/flags.go
Outdated
@@ -46,4 +46,6 @@ built-in formatters are: | |||
specify SEED to reproduce the shuffling from a previous run | |||
--random=5738`) | |||
flagSet.Lookup(prefix + "random").NoOptDefVal = "-1" | |||
|
|||
flagSet.IntVar(&opts.MaxRetries, prefix+"retry", opts.MaxRetries, "retry n times when a step encounter error") |
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.
flagSet.IntVar(&opts.MaxRetries, prefix+"retry", opts.MaxRetries, "retry n times when a step encounter error") | |
flagSet.IntVar(&opts.MaxRetries, prefix+"retry", opts.MaxRetries, "Specify the number of times to retry failing tests (default: 0)") |
Make sure this is defaulting to 0
If you want to see where the original config parser is set with all of the messages check here: https://github.com/cucumber/cucumber-ruby/blob/main/lib/cucumber/cli/options.rb
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.
Yes it will be default 0. I'll update the message.
@@ -51,6 +53,7 @@ func Test_BindFlagsShouldRespectFlagOverrides(t *testing.T) { | |||
"--optOverrides.strict=false", | |||
"--optOverrides.no-colors=false", | |||
"--optOverrides.random=2", | |||
"--optOverrides.retry=3", |
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.
I'm not sure I agree with this assertion or infact the one above saying concurrency is 3. Are you taking your options parser and then adding whatever values you input? We want this to be a single source of truth, not something additive.
If I'm misunderstanding, feel free to ignore.
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.
Ah this is not concurrency option. In this test MaxRetries is set to 1 when initialize the option object and then we pass in CLI flags to override the option value, the goal is to make sure that CLI options work as expected.
@@ -61,4 +64,5 @@ func Test_BindFlagsShouldRespectFlagOverrides(t *testing.T) { | |||
assert.False(t, opts.Strict) | |||
assert.False(t, opts.NoColors) | |||
assert.Equal(t, int64(2), opts.Randomize) | |||
assert.Equal(t, 3, opts.MaxRetries) |
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.
Check here also. This might need updating. Although given this is the same as the above maybe this is just asserting that?
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.
Same as above, this is to make sure the MaxRetries option can be assigned via CLI.
internal/flags/options.go
Outdated
@@ -80,6 +80,9 @@ type Options struct { | |||
|
|||
// ShowHelp enables suite to show CLI flags usage help and exit. | |||
ShowHelp bool | |||
|
|||
// MaxRetries is used to retry the number of time when a step is failed. Default is 0 retry. |
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.
// MaxRetries is used to retry the number of time when a step is failed. Default is 0 retry. | |
// MaxRetries is the number of times you can retry failing tests. Default is 0. |
|
||
fifthTimePass := 0 | ||
ctx.Step(`^a step that always fails`, func(ctx context.Context) (context.Context, error) { | ||
fifthTimePass++ |
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 looks like duplicate info from above. Is there a way to avoid defining this twice.
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 forgot, this file is unit tests for the framework itself. So this case here is to cover the case step retried all attempts but still fail.
@luke-hill I agree that this implementation works for the specific status Do you mean that other standard implementors will also implement such approaches as well? If it is the case, then this PR is to implement the approach using So I do want to conform the cucumber standard for implementations, but I don't want to make so many different changes in one PR 😄 |
🤔 What's changed?
ErrRetry
MaxRetries
attempts⚡️ What's your motivation?
Discussed here.
🏷️ What kind of change is this?
♻️ Anything particular you want feedback on?
📋 Checklist:
This text was originally generated from a template, then edited by hand. You can modify the template here.