1
votes

I made a minimum reproducible example to illustrate my issue :

Thanks to Gunthers's answer How to get the full stack trace for async execution, I was able to print the full trace including every function called till the root of the test.

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:stack_trace/stack_trace.dart';

late WidgetTester tester;
void expectFoo() {
  expect(find.text('Foos'), findsOneWidget);
}

Future<void> build() async {
  await tester.pumpWidget(Column(
    children: [
      CircularProgressIndicator(),
      Text('Foo', textDirection: TextDirection.ltr),
    ],
  ));
  await tester.pumpAndSettle(); // <- This fails the test
  expectFoo(); // <- This also fails the test but comment above line first
}

Future<void> setup() async {
  await build();
}

Future<void> testIfFooIsThere() async {
  await setup();
}

void main() {
  testWidgets('Stack trace', (WidgetTester _tester) async {
    tester = _tester;
    await Chain.capture(() async {
      await testIfFooIsThere();
    }, onError: (e, stack) {
      print(e);
      print("Chain ${Trace.from(stack).terse}");
      throw e;
    });
  });
}

With this code, it is meant to fail the test at pumpAndSettle(). Here is the trace:

══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
The following assertion was thrown running a test:
pumpAndSettle timed out

When the exception was thrown, this was the stack:
#1      WidgetTester.pumpAndSettle.<anonymous closure> (package:flutter_test/src/widget_tester.dart:651:11)
#3      TestAsyncUtils.guard.completionHandler (package:flutter_test/src/test_async_utils.dart:111:16)
#17     WidgetTester.pumpAndSettle.<anonymous closure> (package:flutter_test/src/widget_tester.dart:0:0)
#21     TestAsyncUtils.guard (package:flutter_test/src/test_async_utils.dart:114:19)
#22     WidgetTester.pumpAndSettle (package:flutter_test/src/widget_tester.dart:646:27)
#23     build (file:///Users/samran/AndroidStudioProjects/flit_ride/test/widget_test_stack.dart:17:16)
#26     setup (file:///Users/samran/AndroidStudioProjects/flit_ride/test/widget_test_stack.dart:22:9)
#27     testIfFooIsThere (file:///Users/samran/AndroidStudioProjects/flit_ride/test/widget_test_stack.dart:26:9)
#28     main.<anonymous closure>.<anonymous closure> (file:///Users/samran/AndroidStudioProjects/flit_ride/test/widget_test_stack.dart:33:13)
#29     main.<anonymous closure>.<anonymous closure> (file:///Users/samran/AndroidStudioProjects/flit_ride/test/widget_test_stack.dart:32:25)
#36     main.<anonymous closure> (file:///Users/samran/AndroidStudioProjects/flit_ride/test/widget_test_stack.dart:32:17)
#37     main.<anonymous closure> (file:///Users/samran/AndroidStudioProjects/flit_ride/test/widget_test_stack.dart:30:30)
#38     testWidgets.<anonymous closure>.<anonymous closure> (package:flutter_test/src/widget_tester.dart:156:29)
(elided 25 frames from dart:async, dart:async-patch, and package:stack_trace)

The test description was:
  Stack trace

As you can see from the above trace, I get every function in the stack trace up to testWidgets > testIfFooIsThere > setup > build

So now when I comment this line await tester.pumpAndSettle(); // <- This fails the test , I expect get an assertion error at expect(find.text('Foos'), findsOneWidget);

But the Stack trace only includes build and expectFoo

══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
The following TestFailure object was thrown running a test:
  Expected: exactly one matching node in the widget tree
  Actual: _TextFinder:<zero widgets with text "Foos" (ignoring offstage widgets)>
   Which: means none were found but one was expected

When the exception was thrown, this was the stack:
#1      fail (package:test_api/src/frontend/expect.dart:153:31)
#2      _expect (package:test_api/src/frontend/expect.dart:148:3)
#3      expect (package:test_api/src/frontend/expect.dart:57:3)
#4      expect (package:flutter_test/src/widget_tester.dart:441:3)
#5      expectFoo (file:///Users/samran/AndroidStudioProjects/flit_ride/test/widget_test.dart:7:3)
#6      build (file:///Users/samran/AndroidStudioProjects/flit_ride/test/widget_test.dart:18:3)
#9      main.<anonymous closure>.<anonymous closure> (file:///Users/samran/AndroidStudioProjects/flit_ride/test/widget_test.dart:0:0)
#16     main.<anonymous closure> (file:///Users/samran/AndroidStudioProjects/flit_ride/test/widget_test.dart:32:17)
#17     main.<anonymous closure> (file:///Users/samran/AndroidStudioProjects/flit_ride/test/widget_test.dart:30:30)
#18     testWidgets.<anonymous closure>.<anonymous closure> (package:flutter_test/src/widget_tester.dart:156:29)
(elided 8 frames from dart:async, dart:async-patch, and package:stack_trace)

The test description was:
  Stack trace

Why ??

What should I do to make the second error trace behave like the first ?

Ultimately, my goal is to print every function with their line numbers from testWidgets up to the line that errored out, whenever an error occurred during the test. An alternative solution would be welcomed

I'm struggling to see the differences between the 2 stack traces. Are you sure you copy/pasted the right trace?cameron1024
my bad. you're right. I fixed itTSR