是否有方法限制Flutter中的堆栈跟踪信息



我正试图找到一种方法,使颤振单元测试失败消息对我更有用。

现在,在一个简单的测试中,它不做任何有用的事情,将产生一个50多行对我来说毫无用处的东西的堆栈跟踪。我不关心Flutter框架做了什么来运行我的测试,我关心的是我可以控制什么,在这个例子中是前两行。

目前它是这样做的:

══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
The following TestFailure object was thrown running a test:
Expected: <true>
Actual: <false>
When the exception was thrown, this was the stack:
#4      main.<anonymous closure> (file:///D:/disclaimer_screen_test.dart:57:5)
<asynchronous suspension>
#5      main.<anonymous closure> (file:///D:/disclaimer_screen_test.dart)
#6      testWidgets.<anonymous closure>.<anonymous closure> (package:flutter_test/src/widget_tester.dart:146:29)
<asynchronous suspension>
#7      testWidgets.<anonymous closure>.<anonymous closure> (package:flutter_test/src/widget_tester.dart)
#8      TestWidgetsFlutterBinding._runTestBody (package:flutter_test/src/binding.dart:784:19)
<asynchronous suspension>
#11     TestWidgetsFlutterBinding._runTest (package:flutter_test/src/binding.dart:764:14)
#12     AutomatedTestWidgetsFlutterBinding.runTest.<anonymous closure> (package:flutter_test/src/binding.dart:1173:24)
#13     FakeAsync.run.<anonymous closure>.<anonymous closure> (package:fake_async/fake_async.dart:178:54)
#18     withClock (package:clock/src/default.dart:48:10)
#19     FakeAsync.run.<anonymous closure> (package:fake_async/fake_async.dart:178:22)
#24     FakeAsync.run (package:fake_async/fake_async.dart:178:7)
#25     AutomatedTestWidgetsFlutterBinding.runTest (package:flutter_test/src/binding.dart:1170:15)
#26     testWidgets.<anonymous closure> (package:flutter_test/src/widget_tester.dart:138:24)
#27     Declarer.test.<anonymous closure>.<anonymous closure> (package:test_api/src/backend/declarer.dart:175:19)
<asynchronous suspension>
#28     Declarer.test.<anonymous closure>.<anonymous closure> (package:test_api/src/backend/declarer.dart)
#33     Declarer.test.<anonymous closure> (package:test_api/src/backend/declarer.dart:173:13)
#34     Invoker.waitForOutstandingCallbacks.<anonymous closure> (package:test_api/src/backend/invoker.dart:231:15)
#39     Invoker.waitForOutstandingCallbacks (package:test_api/src/backend/invoker.dart:228:5)
#40     Invoker._onRun.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:test_api/src/backend/invoker.dart:383:17)
<asynchronous suspension>
#41     Invoker._onRun.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:test_api/src/backend/invoker.dart)
#46     Invoker._onRun.<anonymous closure>.<anonymous closure> (package:test_api/src/backend/invoker.dart:370:9)
#47     Invoker._guardIfGuarded (package:test_api/src/backend/invoker.dart:415:15)
#48     Invoker._onRun.<anonymous closure> (package:test_api/src/backend/invoker.dart:369:7)
#55     Invoker._onRun (package:test_api/src/backend/invoker.dart:368:11)
#56     LiveTestController.run (package:test_api/src/backend/live_test_controller.dart:153:11)
#57     RemoteListener._runLiveTest.<anonymous closure> (package:test_api/src/remote_listener.dart:256:16)
#62     RemoteListener._runLiveTest (package:test_api/src/remote_listener.dart:255:5)
#63     RemoteListener._serializeTest.<anonymous closure> (package:test_api/src/remote_listener.dart:208:7)
#81     _GuaranteeSink.add (package:stream_channel/src/guarantee_channel.dart:125:12)
#82     new _MultiChannel.<anonymous closure> (package:stream_channel/src/multi_channel.dart:159:31)
#86     CastStreamSubscription._onData (dart:_internal/async_cast.dart:85:11)
#120    new _WebSocketImpl._fromSocket.<anonymous closure> (dart:_http/websocket_impl.dart:1145:21)
#128    _WebSocketProtocolTransformer._messageFrameEnd (dart:_http/websocket_impl.dart:338:23)
#129    _WebSocketProtocolTransformer.add (dart:_http/websocket_impl.dart:232:46)
#139    _Socket._onData (dart:io-patch/socket_patch.dart:2044:41)
#148    new _RawSocket.<anonymous closure> (dart:io-patch/socket_patch.dart:1580:33)
#149    _NativeSocket.issueReadEvent.issue (dart:io-patch/socket_patch.dart:1076:14)
(elided 111 frames from dart:async and package:stack_trace)
This was caught by the test expectation on the following line:
file:///D:/disclaimer_screen_test.dart line 57
The test description was:
someScreen Widget Test
════════════════════════════════════════════════════════════════════════════════════════════════════
Test failed. See exception logs above.
The test description was: someScreen Widget Test
✖ someScreen Widget Test
Exited (1)

理想情况下,我想限制或删除堆栈跟踪,使其看起来像这样:

══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
The following TestFailure object was thrown running a test:
Expected: <true>
Actual: <false>
This was caught by the test expectation on the following line:
file:///D:/disclaimer_screen_test.dart line 57
The test description was:
someScreen Widget Test
════════════════════════════════════════════════════════════════════════════════════════════════════
Test failed. See exception logs above.
The test description was: someScreen Widget Test
✖ someScreen Widget Test
Exited (1)

这样我就能得到所有相关的信息,而不会受到我无法控制的东西的噪音,而且老实说,这些东西并没有坏。我相信这个框架和第三方包是按照预期工作的,如果不是,我就会做不同的调查。

我找到了defaultStackFilter方法,但这似乎是一个内部颤振方法,而不是我可以控制的东西,也许我只是不理解它。

是否有一种方法来改变堆栈输出作为一个整体,或者一种在单元测试环境中禁用它的方法?

提前感谢!

详细说明Randal Schwartz的回答,下面是我使用的完整代码:

import 'package:stack_trace/stack_trace.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
FlutterError.onError = (FlutterErrorDetails details) {
print("Error :  ${details.exception}");
print(Trace.from(details.stack!).terse);
};
Chain.capture(() async {
runApp(MyApp()); // starting point of app
}, onError: (error, stackTrace) {
print("Async Error :  $error");
print(stackTrace.terse);
});
}

这里包含了另一个答案,解释了如何拦截在Flutter上下文中发生的同步和异步错误。

这使我们能够完全控制错误的显示方式。我特别欣赏这一点,特别是在异步情况下,以前的堆栈跟踪不包含任何由我编写的代码。现在它正确地指向我发起的网络调用。

这种方法似乎应该是标准实践,因为它大大减少了搜索错误原因的时间和精力。

是…pub中的stack_trace包如下:

您可以使用trace .terse进一步清理堆栈跟踪。这将Dart核心库中的多个堆栈帧折叠在一起,因此只有直接从用户代码调用的核心库方法是可见的。

非常方便。

最新更新