From cf8d28d63ec1472fe7a9f5452511847f436f3ce0 Mon Sep 17 00:00:00 2001 From: Jon Samwell Date: Fri, 8 Jan 2021 17:20:30 +1100 Subject: [PATCH] feat(integration_test): more progress with reporting --- .flutter-plugins-dependencies | 2 +- CHANGELOG.md | 13 ++- .../integration_response_data.json | 2 +- .../integration_test/features/counter.feature | 7 +- .../gherkin/steps/table_step.dart | 11 +++ .../integration_test/gherkin_suite_test.dart | 17 +++- .../gherkin_suite_test.g.dart | 21 ++--- example_with_integration_test/pubspec.lock | 4 +- .../gherkin_suite_test_generator.dart | 24 ++--- .../gherkin_integration_test_runner.dart | 92 +++++++++++++++---- pubspec.lock | 4 +- pubspec.yaml | 2 +- 12 files changed, 143 insertions(+), 56 deletions(-) create mode 100644 example_with_integration_test/integration_test/gherkin/steps/table_step.dart diff --git a/.flutter-plugins-dependencies b/.flutter-plugins-dependencies index fbb9b26..7ddbb1f 100644 --- a/.flutter-plugins-dependencies +++ b/.flutter-plugins-dependencies @@ -1 +1 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"integration_test","path":"C:\\\\Google\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\integration_test-1.0.1\\\\","dependencies":[]}],"android":[{"name":"integration_test","path":"C:\\\\Google\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\integration_test-1.0.1\\\\","dependencies":[]}],"macos":[],"linux":[],"windows":[],"web":[]},"dependencyGraph":[{"name":"integration_test","dependencies":[]}],"date_created":"2021-01-08 11:27:21.268830","version":"1.22.5"} \ No newline at end of file +{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"integration_test","path":"C:\\\\Google\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\integration_test-1.0.1\\\\","dependencies":[]}],"android":[{"name":"integration_test","path":"C:\\\\Google\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\integration_test-1.0.1\\\\","dependencies":[]}],"macos":[],"linux":[],"windows":[],"web":[]},"dependencyGraph":[{"name":"integration_test","dependencies":[]}],"date_created":"2021-01-08 16:39:37.431562","version":"1.22.5"} \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index bb3e8d7..489ef63 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -55,7 +55,18 @@ part 'gherkin_suite_test.g.dart'; @GherkinTestSuite() void main() { executeTestSuite( - FlutterTestConfiguration.DEFAULT([]), + FlutterTestConfiguration.DEFAULT([]) + ..reporters = [ + StdoutReporter(MessageLevel.error) + ..setWriteLineFn(print) + ..setWriteFn(print), + ProgressReporter() + ..setWriteLineFn(print) + ..setWriteFn(print), + TestRunSummaryReporter() + ..setWriteLineFn(print) + ..setWriteFn(print), + ], app.main, ); } diff --git a/example_with_integration_test/integration_response_data.json b/example_with_integration_test/integration_response_data.json index 6cad329..e174586 100644 --- a/example_with_integration_test/integration_response_data.json +++ b/example_with_integration_test/integration_response_data.json @@ -1,3 +1,3 @@ { - "gherkin_results": "{\"test\":\"moo\"}" + "gherkin_results": "{\"test\":\"moo1\"}" } \ No newline at end of file diff --git a/example_with_integration_test/integration_test/features/counter.feature b/example_with_integration_test/integration_test/features/counter.feature index 14b8cdc..349449f 100644 --- a/example_with_integration_test/integration_test/features/counter.feature +++ b/example_with_integration_test/integration_test/features/counter.feature @@ -1,6 +1,11 @@ Feature: Counter + @tag1 @tag_two Scenario: User can increment the counter Given I expect the "counter" to be "0" When I tap the "increment" button - Then I expect the "counter" to be "1" \ No newline at end of file + Then I expect the "counter" to be "1" + Given the table + | Header One | Header Two | Header Three | + | 1 | 2 | 3 | + | 4 | 5 | 6 | \ No newline at end of file diff --git a/example_with_integration_test/integration_test/gherkin/steps/table_step.dart b/example_with_integration_test/integration_test/gherkin/steps/table_step.dart new file mode 100644 index 0000000..88e1f43 --- /dev/null +++ b/example_with_integration_test/integration_test/gherkin/steps/table_step.dart @@ -0,0 +1,11 @@ +import 'package:flutter_gherkin/flutter_gherkin.dart'; +import 'package:gherkin/gherkin.dart'; + +StepDefinitionGeneric givenTheTable() { + return given1( + 'the table', + (table, context) async { + // do something with the table data + }, + ); +} diff --git a/example_with_integration_test/integration_test/gherkin_suite_test.dart b/example_with_integration_test/integration_test/gherkin_suite_test.dart index 63f2438..6beba5c 100644 --- a/example_with_integration_test/integration_test/gherkin_suite_test.dart +++ b/example_with_integration_test/integration_test/gherkin_suite_test.dart @@ -5,12 +5,27 @@ import 'package:gherkin/gherkin.dart'; // The application under test. import 'package:example_with_integration_test/main.dart' as app; +import 'gherkin/steps/table_step.dart'; + part 'gherkin_suite_test.g.dart'; @GherkinTestSuite() void main() { executeTestSuite( - FlutterTestConfiguration.DEFAULT([]), + FlutterTestConfiguration.DEFAULT([ + givenTheTable(), + ]) + ..reporters = [ + StdoutReporter(MessageLevel.error) + ..setWriteLineFn(print) + ..setWriteFn(print), + ProgressReporter() + ..setWriteLineFn(print) + ..setWriteFn(print), + TestRunSummaryReporter() + ..setWriteLineFn(print) + ..setWriteFn(print), + ], app.main, ); } diff --git a/example_with_integration_test/integration_test/gherkin_suite_test.g.dart b/example_with_integration_test/integration_test/gherkin_suite_test.g.dart index 259c867..83e310e 100644 --- a/example_with_integration_test/integration_test/gherkin_suite_test.g.dart +++ b/example_with_integration_test/integration_test/gherkin_suite_test.g.dart @@ -21,16 +21,10 @@ class _CustomGherkinIntegrationTestRunner extends GherkinIntegrationTestRunner { group( 'Counter:', () { - testWidgets( + runScenario( 'User can increment the counter', - (WidgetTester tester) async { - final dependencies = await createTestDependencies( - configuration, - tester, - ); - - await startApp(tester); - + ['@tag1', '@tag_two'], + (TestDependencies dependencies) async { await runStep( 'Given I expect the "counter" to be "0"', [], @@ -52,9 +46,14 @@ class _CustomGherkinIntegrationTestRunner extends GherkinIntegrationTestRunner { dependencies, ); - cleanupScenarioRun(dependencies); + await runStep( + 'Given the table', + [], + Table.fromJson( + '[{"Header One":"1","Header Two":"2","Header Three":"3"},{"Header One":"4","Header Two":"5","Header Three":"6"}]'), + dependencies, + ); }, - timeout: scenarioExecutionTimeout, ); }, ); diff --git a/example_with_integration_test/pubspec.lock b/example_with_integration_test/pubspec.lock index 26c73ba..903850d 100644 --- a/example_with_integration_test/pubspec.lock +++ b/example_with_integration_test/pubspec.lock @@ -235,8 +235,8 @@ packages: dependency: transitive description: path: "." - ref: "59b9db42e917927ccb8d1265e6cb8fe93ddbb73a" - resolved-ref: "59b9db42e917927ccb8d1265e6cb8fe93ddbb73a" + ref: "80c03137d883637b2526e16a945009d76c3cbd85" + resolved-ref: "80c03137d883637b2526e16a945009d76c3cbd85" url: "https://github.com/jonsamwell/dart_gherkin.git" source: git version: "1.1.10" diff --git a/lib/src/flutter/code_generation/generators/gherkin_suite_test_generator.dart b/lib/src/flutter/code_generation/generators/gherkin_suite_test_generator.dart index 9580fb4..3b67510 100644 --- a/lib/src/flutter/code_generation/generators/gherkin_suite_test_generator.dart +++ b/lib/src/flutter/code_generation/generators/gherkin_suite_test_generator.dart @@ -130,21 +130,12 @@ class FeatureFileTestGeneratorVisitor extends FeatureFileVisitor { } '''; static const String SCENARIO_TEMPLATE = ''' - testWidgets( + runScenario( '{{scenario_name}}', - (WidgetTester tester) async { - final dependencies = await createTestDependencies( - configuration, - tester, - ); - - await startApp(tester); - + {{tags}}, + (TestDependencies dependencies) async { {{steps}} - - cleanupScenarioRun(dependencies); }, - timeout: scenarioExecutionTimeout, ); '''; static const String STEP_TEMPLATE = ''' @@ -197,13 +188,12 @@ class FeatureFileTestGeneratorVisitor extends FeatureFileVisitor { } @override - Future visitScenario( - String name, - Iterable tags - ) async { + Future visitScenario(String name, Iterable tags) async { _flushScenario(); _currentScenarioCode = _replaceVariable(SCENARIO_TEMPLATE, 'scenario_name', name); + _currentScenarioCode = + _replaceVariable(_currentScenarioCode, 'tags', '[${tags.map((e) => "'$e'").join(', ')}]'); } @override @@ -221,7 +211,7 @@ class FeatureFileTestGeneratorVisitor extends FeatureFileVisitor { code = _replaceVariable( code, 'step_table', - 'null', + table == null ? 'null' : 'Table.fromJson(\'${table.toJson()}\')', ); _stepBuffer.writeln(code); diff --git a/lib/src/flutter/runners/gherkin_integration_test_runner.dart b/lib/src/flutter/runners/gherkin_integration_test_runner.dart index 5f86eaa..cdc16f1 100644 --- a/lib/src/flutter/runners/gherkin_integration_test_runner.dart +++ b/lib/src/flutter/runners/gherkin_integration_test_runner.dart @@ -7,11 +7,11 @@ import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; -class _TestDependencies { +class TestDependencies { final World world; final AttachmentManager attachmentManager; - _TestDependencies( + TestDependencies( this.world, this.attachmentManager, ); @@ -25,6 +25,8 @@ abstract class GherkinIntegrationTestRunner { Iterable _executableSteps; Iterable _customParameters; + IntegrationTestWidgetsFlutterBinding _binding; + Reporter get reporter => _reporter; Hook get hook => _hook; @@ -46,28 +48,82 @@ abstract class GherkinIntegrationTestRunner { } Future run() async { - final binding = IntegrationTestWidgetsFlutterBinding.ensureInitialized() + _binding = IntegrationTestWidgetsFlutterBinding.ensureInitialized() as IntegrationTestWidgetsFlutterBinding; - try { - await _reporter.onTestRunStarted(); - onRun(); - } finally { - _safeInvokeFuture(() async => await reporter.onTestRunFinished()); - _safeInvokeFuture(() async => await _hook.onAfterRun(configuration)); - _safeInvokeFuture(() async => await reporter.dispose()); - setTestResultData(binding); - } + await _reporter.onTestRunStarted(); + onRun(); + + tearDownAll(() { + onRunComplete(); + }); } void onRun(); + void onRunComplete() { + _safeInvokeFuture(() async => await reporter.onTestRunFinished()); + _safeInvokeFuture(() async => await hook.onAfterRun(configuration)); + setTestResultData(_binding); + _safeInvokeFuture(() async => await reporter.dispose()); + } + void setTestResultData(IntegrationTestWidgetsFlutterBinding binding) { binding.reportData = { - 'gherkin_results': jsonEncode({'test': 'moo'}) + 'gherkin_results': jsonEncode({'test': 'moo1'}) }; } + @protected + void runScenario( + String name, + Iterable tags, + Future Function(TestDependencies dependencies) runTest, + ) { + testWidgets( + 'User can increment the counter', + (WidgetTester tester) async { + final debugInformation = RunnableDebugInformation('', 0, name); + final scenarioTags = + (tags ?? Iterable.empty()).map((t) => Tag(t, 0)); + final dependencies = await createTestDependencies( + configuration, + tester, + ); + + await startApp(tester); + + await reporter.onScenarioStarted( + StartedMessage( + Target.scenario, + name, + debugInformation, + scenarioTags, + ), + ); + + await runTest(dependencies); + + await _reporter.onScenarioFinished( + ScenarioFinishedMessage( + name, + debugInformation, + true, + ), + ); + + await _hook.onAfterScenario( + configuration, + name, + scenarioTags, + ); + + cleanupScenarioRun(dependencies); + }, + timeout: scenarioExecutionTimeout, + ); + } + @protected Future startApp(WidgetTester tester) async { appMainFunction(); @@ -75,7 +131,7 @@ abstract class GherkinIntegrationTestRunner { } @protected - Future<_TestDependencies> createTestDependencies( + Future createTestDependencies( TestConfiguration configuration, WidgetTester tester, ) async { @@ -92,7 +148,7 @@ abstract class GherkinIntegrationTestRunner { (world as FlutterWorld).setAppAdapter(WidgetTesterAppDriverAdapter(tester)); - return _TestDependencies( + return TestDependencies( world, attachmentManager, ); @@ -103,7 +159,7 @@ abstract class GherkinIntegrationTestRunner { String step, Iterable multiLineStrings, dynamic table, - _TestDependencies dependencies, + TestDependencies dependencies, ) async { final executable = _executableSteps.firstWhere( (s) => s.expression.isMatch(step), @@ -152,7 +208,7 @@ abstract class GherkinIntegrationTestRunner { } @protected - void cleanupScenarioRun(_TestDependencies dependencies) { + void cleanupScenarioRun(TestDependencies dependencies) { _safeInvokeFuture( () async => await dependencies.attachmentManager.dispose()); _safeInvokeFuture(() async => await dependencies.world.dispose()); @@ -234,7 +290,7 @@ abstract class GherkinIntegrationTestRunner { Future _onAfterStepRun( String step, StepResult result, - _TestDependencies dependencies, + TestDependencies dependencies, ) async { await _hook.onAfterStep( dependencies.world, diff --git a/pubspec.lock b/pubspec.lock index 15a7cc0..6e9c5dc 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -165,8 +165,8 @@ packages: dependency: "direct main" description: path: "." - ref: "59b9db42e917927ccb8d1265e6cb8fe93ddbb73a" - resolved-ref: "59b9db42e917927ccb8d1265e6cb8fe93ddbb73a" + ref: "80c03137d883637b2526e16a945009d76c3cbd85" + resolved-ref: "80c03137d883637b2526e16a945009d76c3cbd85" url: "https://github.com/jonsamwell/dart_gherkin.git" source: git version: "1.1.10" diff --git a/pubspec.yaml b/pubspec.yaml index 7b39e96..66b6ffb 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -27,7 +27,7 @@ dependencies: gherkin: git: url: https://github.com/jonsamwell/dart_gherkin.git - ref: 59b9db42e917927ccb8d1265e6cb8fe93ddbb73a + ref: 80c03137d883637b2526e16a945009d76c3cbd85 # ref: code_gen_changes dev_dependencies: