Skip to content
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

Add new command-line option to specify a threshold for test duration printing #1910

Merged
merged 2 commits into from
Jul 6, 2020

Conversation

jbytheway
Copy link
Contributor

@jbytheway jbytheway commented Apr 13, 2020

Description

A test runner already has a --durations option to print durations. However, this isn't entirely satisfactory.

When there are many tests, this produces output spam which makes it hard to find the test failure output. Nevertheless, it is helpful to be informed of tests which are unusually slow.

Therefore, introduce a new option --min-duration that causes all durations above a certain threshold to be printed. This allows slow tests to be visible without mentioning every test.

In our CI we're currently emulating this with some ugly grep on the output, but this is a bit limited, and harder to use when running the tests outside of CI.

I've made a bunch of choices in this implementation that could have gone differently:

  • --min-duration is independent of --durations. Specifying either will cause things to be printed. I could have rolled them into a single option that takes either a string or numeric argument, or made --min-duration do nothing if --durations was not also given.
  • I made IConfig::shouldShowDuration a member function. It could have been a free function, but I wouldn't know where to put it.
  • --min-duration only affects the console and compact reporters, not e.g. the XML reporter, because I figured output spam is not an issue there.
  • It's tricky to test this change, because every test in SelfTest is so fast that it is printed as 0.000 s. So for now the test just verifies that no durations are printed if a minimum of 1s is specified. But it's written in such a way that it should do something more interesting if slower tests are ever added.

@jbytheway jbytheway changed the title Test time threshold printing Add new command-line option to specify a threshold for test duration printing Apr 13, 2020
@codecov
Copy link

codecov bot commented Apr 13, 2020

Codecov Report

Merging #1910 into master will increase coverage by 0.13%.
The diff coverage is 82.35%.

@@            Coverage Diff             @@
##           master    #1910      +/-   ##
==========================================
+ Coverage   88.61%   88.74%   +0.13%     
==========================================
  Files         138      138              
  Lines        5627     5629       +2     
==========================================
+ Hits         4986     4995       +9     
+ Misses        641      634       -7     

@jbytheway jbytheway force-pushed the test_time_threshold_printing branch from 6533c60 to 33d1568 Compare April 14, 2020 12:45
@@ -52,6 +52,7 @@ namespace Catch {
Verbosity verbosity = Verbosity::Normal;
WarnAbout::What warnings = WarnAbout::Nothing;
ShowDurations::OrNot showDurations = ShowDurations::DefaultForReporter;
double minDuration = -1;
Copy link
Member

Choose a reason for hiding this comment

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

I think having 0. mean "turned off" is fine here. If an user wants all durations to be shown, they can set up showDurations::Always.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm always leery of using a value that might possibly have been intended as valid for a sentinel value. You never know when there might be extra layers between the user and the value (e.g. a GUI or a wrapper script) which makes it less easy to pass other arguments.

@horenmar
Copy link
Member

horenmar commented May 15, 2020

I think IConfig::shouldShowDuration should be a free function somewhere in reporter interfaces/bases -- there is already precedent with some cross-reporter helpers being there.

For testing, I would suggest adding a hidden test non-approval test that sleeps for, say, 100 ms, and another that sleeps for 500 ms and then check that they are (not) reported as appropriate...

All in all the changes look reasonable, but I'll definitely need one more look later.

@horenmar
Copy link
Member

Some extra thoughts on combining -d and -D:

  • ShowDurations::Always should take priority over values set by -D.
  • ShowDurations::Never should suppress printing any durations. (I also see only one place it is used, and I have some doubts about the usefulness there)
  • This implies that setting -D is only valid if -d is not set. The question is, should Catch2 stop you from specifying both?

@jbytheway
Copy link
Contributor Author

For testing, I would suggest adding a hidden test non-approval test that sleeps for, say, 100 ms, and another that sleeps for 500 ms and then check that they are (not) reported as appropriate...

To verify I've understood you: by "hidden" do you mean "marked [.]"? So I could use e.g. `"[.min_duration_test]" for them and run them just when testing this feature?

@jbytheway
Copy link
Contributor Author

I think IConfig::shouldShowDuration should be a free function somewhere in reporter interfaces/bases -- there is already precedent with some cross-reporter helpers being there.

In include/reporters/catch_reporter_bases.hpp I see getFormatterDuration. Is that the sort of place you were thinking?

@jbytheway jbytheway force-pushed the test_time_threshold_printing branch from 33d1568 to 08af3e6 Compare June 2, 2020 02:08
@jbytheway
Copy link
Contributor Author

jbytheway commented Jun 2, 2020

This implies that setting -D is only valid if -d is not set. The question is, should Catch2 stop you from specifying both?

My instinct is not to prevent it. You might e.g. be calling the test runner through a wrapper script that uses -D and it would be annoying if you couldn't add -d to override.

@horenmar
Copy link
Member

horenmar commented Jun 2, 2020

In include/reporters/catch_reporter_bases.hpp I see getFormatterDuration. Is that the sort of place you were thinking?

Yes.

To verify I've understood you: by "hidden" do you mean "marked [.]"? So I could use e.g. `"[.min_duration_test]" for them and run them just when testing this feature?

And yes. You will also need [approvals] to prevent them from being run during approvals.

A test runner already has a --durations option to print durations.
However, this isn't entirely satisfactory.

When there are many tests, this produces output spam which makes it hard
to find the test failure output.  Nevertheless, it is helpful to be
informed of tests which are unusually slow.

Therefore, introduce a new option --min-duration that causes all
durations above a certain threshold to be printed.  This allows slow
tests to be visible without mentioning every test.
@jbytheway jbytheway force-pushed the test_time_threshold_printing branch from 08af3e6 to 336e27c Compare July 3, 2020 19:16
@jbytheway
Copy link
Contributor Author

I have refactored and updated the tests as suggested. Over to you.

@horenmar
Copy link
Member

horenmar commented Jul 6, 2020

There are some things I am still not quite happy with, but it will be fastest if I merge the PR as is and fix it later.

@nandanvasudevan
Copy link

nandanvasudevan commented Mar 16, 2022

Would it be possible to group the output according to the test case and tag?

@horenmar
Copy link
Member

@nandanvasudevan Everything is possible with a custom reporter. 🤷

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants