diff --git a/pkgs/test/CHANGELOG.md b/pkgs/test/CHANGELOG.md index 062691929..c61376337 100644 --- a/pkgs/test/CHANGELOG.md +++ b/pkgs/test/CHANGELOG.md @@ -2,6 +2,8 @@ * Make the labels for test loading more readable in the compact and expanded reporters, use gray instead of black. +* Print a command to re-run the failed test after each failure in the compact + reporter. * Fix the package config path used when running pre-compiled vm tests. ## 1.21.3 diff --git a/pkgs/test/test/runner/compact_reporter_test.dart b/pkgs/test/test/runner/compact_reporter_test.dart index b8ef11af1..ba0ff0203 100644 --- a/pkgs/test/test/runner/compact_reporter_test.dart +++ b/pkgs/test/test/runner/compact_reporter_test.dart @@ -5,7 +5,9 @@ @TestOn('vm') import 'dart:async'; +import 'dart:io'; +import 'package:path/path.dart' as p; import 'package:test/test.dart'; import 'package:test_descriptor/test_descriptor.dart' as d; @@ -426,6 +428,42 @@ void main() { For example, 'dart test --chain-stack-traces'.''', chainStackTraces: false); }); + + group('gives users a way to re-run failed tests', () { + final executablePath = p.absolute(Platform.resolvedExecutable); + + test('with simple names', () { + return _expectReport(''' + test('failure', () { + expect(1, equals(2)); + });''', ''' + +0: loading test.dart + +0: failure + +0 -1: failure [E] + Expected: <2> + Actual: <1> + + To run this test again: $executablePath test test.dart -p vm --plain-name 'failure' + + +0 -1: Some tests failed.'''); + }); + + test('escapes names containing single quotes', () { + return _expectReport(''' + test("failure with a ' in the name", () { + expect(1, equals(2)); + });''', ''' + +0: loading test.dart + +0: failure with a ' in the name + +0 -1: failure with a ' in the name [E] + Expected: <2> + Actual: <1> + + To run this test again: $executablePath test test.dart -p vm --plain-name 'failure with a '\\'' in the name' + + +0 -1: Some tests failed.'''); + }); + }); } Future _expectReport(String tests, String expected, diff --git a/pkgs/test_core/CHANGELOG.md b/pkgs/test_core/CHANGELOG.md index 6728e44e5..f94fbd16a 100644 --- a/pkgs/test_core/CHANGELOG.md +++ b/pkgs/test_core/CHANGELOG.md @@ -2,6 +2,8 @@ * Make the labels for test loading more readable in the compact and expanded reporters, use gray instead of black. +* Print a command to re-run the failed test after each failure in the compact + reporter. * Fix the package config path used when running pre-compiled vm tests. ## 0.4.15 diff --git a/pkgs/test_core/lib/src/runner/reporter/compact.dart b/pkgs/test_core/lib/src/runner/reporter/compact.dart index 509ff36e4..d4a1ba735 100644 --- a/pkgs/test_core/lib/src/runner/reporter/compact.dart +++ b/pkgs/test_core/lib/src/runner/reporter/compact.dart @@ -40,6 +40,10 @@ class CompactReporter implements Reporter { /// Windows or not outputting to a terminal. final String _gray; + /// The terminal escape code for cyan text, or the empty string if this is + /// Windows or not outputting to a terminal. + final String _cyan; + /// The terminal escape for bold text, or the empty string if this is /// Windows or not outputting to a terminal. final String _bold; @@ -132,6 +136,7 @@ class CompactReporter implements Reporter { _red = color ? '\u001b[31m' : '', _yellow = color ? '\u001b[33m' : '', _gray = color ? '\u001b[90m' : '', + _cyan = color ? '\u001b[36m' : '', _bold = color ? '\u001b[1m' : '', _noColor = color ? '\u001b[0m' : '' { _subscriptions.add(_engine.onTestStarted.listen(_onTestStarted)); @@ -214,6 +219,16 @@ class CompactReporter implements Reporter { if (message.type == MessageType.skip) text = ' $_yellow$text$_noColor'; _sink.writeln(text); })); + + liveTest.onComplete.then((_) { + var result = liveTest.state.result; + if (result != Result.error && result != Result.failure) return; + _sink.writeln(''); + _sink.writeln('$_bold${_cyan}To run this test again:$_noColor ' + '${Platform.executable} test ${liveTest.suite.path} ' + '-p ${liveTest.suite.platform.runtime.identifier} ' + "--plain-name '${liveTest.test.name.replaceAll("'", r"'\''")}'"); + }); } /// A callback called when [liveTest]'s state becomes [state].