-
Notifications
You must be signed in to change notification settings - Fork 186
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(test): enhance logs and final test report in case of failing tests #563
Conversation
86fbe90
to
8ea4910
Compare
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.
Hey @agacemi, thanks for this great contribution.
Everything looks good to me.
One question to @felangel: this is based on naming the top groups in the .test_runner
file
to be the actual unchanged path of the test files, not snaked cases as they are now. Would that be a problem?
The bundle is out dated; would you mind updating it @agacemi?
3730d93
to
d2681cb
Compare
7821cf3
to
254ae59
Compare
@renancaraujo as this PR modifies .test_runner_bundle.dart, could you indicate me the cleaner way to modify it. |
Now that we have an unbundled brick in the codebase, the changes should be made on it, and then you could run |
d9fc5e5
to
c211159
Compare
@renancaraujo Rebase done. It's right, after brick unbundeling, it's more easier |
test/src/cli/flutter_cli_test.dart
Outdated
@@ -459,7 +467,8 @@ void main() { | |||
'test/counter/cubit/counter_cubit_test.dart 16:7 main.<fn>.<fn>\n', | |||
'\x1B[2K\rCounterCubit initial state is 0 /my_app/test/counter/cubit/counter_cubit_test.dart (FAILED)', | |||
'\x1B[2K\rFailing Tests:\n' | |||
'\x1B[2K\r - [FAILED] test/counter/cubit/counter_cubit_test.dart:16:7\n' | |||
'\x1B[2K\r - /my_app/test/counter/cubit/counter_cubit_test.dart \n' |
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.
Does this /
mean that it will always show the absolute path, I wonder if we can get the relative path based on the current directory. That would make the test output cleaner while keeping the info still useful
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, in the final report, we show always the absolute path and failing tests by each file. My purpose is that the final report keeps the same format in the log before the summary (in the log, full path is used). Paths are clickable from terminal inside IDE to open it. However, I agree that is information is less useful in case of log on CI.
I looked in the code how I can get only relative path. I didn't find a reliable approach because we can have also recursive excution via "--recursive" flag.
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.
We can just make it relative to the Directory.current
, which will work for the --recursive
flag as that runs from the current directory
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.
Done using path.relative. Fixtures changed to be dynamic according to command working directory..
@renancaraujo After rebase, I lost your approval ^^
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.
@wolfenrain @renancaraujo are there any other points to deal with?
f6f4147
to
1551929
Compare
@@ -10,7 +10,7 @@ import 'package:flutter_test/flutter_test.dart'; | |||
{{/tests}} | |||
void main() { | |||
{{#isFlutter}} goldenFileComparator = _TestOptimizationAwareGoldenFileComparator();{{/isFlutter}} | |||
{{#tests}} group('{{#snakeCase}}{{{.}}}{{/snakeCase}}', () { {{#snakeCase}}{{{.}}}{{/snakeCase}}.main(); }); | |||
{{#tests}} group('{{{.}}}', () { {{#snakeCase}}{{{.}}}{{/snakeCase}}.main(); }); |
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.
What is the reason for changing the group name to the path?
This could potentially fail if for some reason the path has a '
in it, then the string would not be valid.
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.
In the algorithm that build the final report, I would like be able to construct the full file name and keep the initial file name with package. I use the same string that used from import.
As I explains in the PR description, my goal is that the report in using or without using optimization is the same. In fact, optimization is the implementation detail that seem to me useful to hide.
I can't find a example of problematic case
Here an example of what generated for counter example.
// GENERATED CODE - DO NOT MODIFY BY HAND
// Consider adding this file to your .gitignore.
import 'dart:io';
import 'package:flutter_test/flutter_test.dart';
import 'app_test.dart' as app_test_dart;
import 'counter/cubit/counter_cubit_test.dart' as counter_cubit_counter_cubit_test_dart;
import 'counter/view/counter_page_test.dart' as counter_view_counter_page_test_dart;
import 'counter/view/counter_view_test.dart' as counter_view_counter_view_test_dart;
void main() {
goldenFileComparator = _TestOptimizationAwareGoldenFileComparator();
group('app_test.dart', () { app_test_dart.main(); });
group('counter/cubit/counter_cubit_test.dart', () { counter_cubit_counter_cubit_test_dart.main(); });
group('counter/view/counter_page_test.dart', () { counter_view_counter_page_test_dart.main(); });
group('counter/view/counter_view_test.dart', () { counter_view_counter_view_test_dart.main(); });
}
class _TestOptimizationAwareGoldenFileComparator extends LocalFileComparator {
final List<String> goldenFilePaths;
_TestOptimizationAwareGoldenFileComparator()
: goldenFilePaths = _goldenFilePaths,
super(_testFile);
static Uri get _testFile {
final basedir =
(goldenFileComparator as LocalFileComparator).basedir.toString();
return Uri.parse("$basedir/.test_optimizer.dart");
}
static List<String> get _goldenFilePaths =>
Directory.fromUri((goldenFileComparator as LocalFileComparator).basedir)
.listSync(recursive: true, followLinks: true)
.whereType<File>()
.map((file) => file.path)
.where((path) => path.endsWith('.png'))
.toList();
@override
Uri getTestUri(Uri key, int? version) {
final keyString = key.path;
return Uri.parse(goldenFilePaths
.singleWhere((goldenFilePath) => goldenFilePath.endsWith(keyString)));
}
}
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.
Can we exclude this change from this PR as it's not directly related and is susceptible to issues as @wolfenrain pointed out?
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.
@felangel In my opinion it's related. Otherwise, the final report is less clear. Below an example of report if I exclude this change. The file name will be counter_cubit_counter_cubit_test_dart
CounterCubit initial state is 0 /Users/abdelaziz_gacemi/Devhome/GitProjects/opensource/bloc/examples/flutter_counter/test/counter_cubit_counter_cubit_test_dart (FAILED)
00:02 +13 -1: Some tests failed.
Failing Tests:
- test/counter_cubit_counter_cubit_test_dart
- [FAILED] CounterCubit initial state is 0
The template '{{{.}}}' is already used for generate import line.
import 'counter/cubit/counter_cubit_test.dart' as counter_cubit_counter_cubit_test_dart;
group('counter/cubit/counter_cubit_test.dart', () { counter_cubit_counter_cubit_test_dart.main();
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.
@felangel @wolfenrain I rebased from main branch to get the last commit to deal with special character.. I made some tests with a file name that contains ' like widget'_special_test.dart. Below, results:
- with
flutter test
: KO - with
very_good test
in main branch: KO - like main branch, on my branch is KO
The generated .test_optimizer.dat look like this:
import 'widget[1]_special_test.dart' as _a;
import 'widget\'_special_test.dart' as _b;
import 'widget_test.dart' as _c;
void main() {
goldenFileComparator = _TestOptimizationAwareGoldenFileComparator();
group('widget[1]_special_test.dart', () { _a.main(); });
group('widget\'_special_test.dart', () { _b.main(); });
group('widget_test.dart', () { _c.main(); });
}
and the obtained error look like:
test/.test_optimizer.dart:10:8: Error: Error when reading 'test/widget': No such file or directory
import 'widget'_special_test.dart' as _b;
^
test/.test_optimizer.dart:16:48: Error: Undefined name '_b'.
group('widget'_special_test_dart', () { _b.main(); });
^^
Could we exclude this special use case from the scope of this PR as this case is also problematic case for flutter test
and very_good test
on main branch
Thank you
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 am fine with keeping it like it is then if we are already using this and therefore having this issue.
What do you think @renancaraujo?
1551929
to
d1e9b4a
Compare
Description
In our company, we use very_good client for test. Log clarty are importants to identify quickly how many tests fails and why.
In addition the two other PRs (enabling ansi color #534, and fix multiline test name #535 ), this PR aims to enhance the three fellowing aspects of
very_good test
logs.Final report in case of failed tests
Currently, very_good_test shows test file paths.
This PRs, we list failing tests grouped by test file name. We think that's better for developer experience.
More comprehensible logs even optimisation is applied
When optimization is applied, very_good generates and uses .test_runner.test. Log show this detail of implementation and make logs less clear and file link that reference .test_runner.dart useless because this file is removed at the end of execution.
In this PR, we hide this detail of implementaiton. Logs are the same with or without optimization.
Fix log in case of blocTest and more generally if exception is thrown from a zone.
Current algorithm extracts the test class path from the exception trace. This choice has a limitation in case of exception thrown inside a zone. For this reason, in case of failed test using blocTest, the test file name will be wrong and will be always
- [FAILED] package:bloc_test/src/bloc_test.dart:155:5
In this PR, we fix this issue.
Type of Change