为什么这个 Flutter 测试在 CodeMagic 上失败了?

Why does this Flutter test fails on CodeMagic?

当我尝试在 Codemagic 上测试构建时,测试失败。我尝试更改 widget_test.dart 代码,问题仍然没有解决。如何解决这个问题?

这是codemagic抛出的错误。

== QA ==

== flutter test --machine ==
{"protocolVersion":"0.1.1","runnerVersion":null,"pid":949,"type":"start","time":0}
{"suite":{"id":0,"platform":"vm","path":"/Users/builder/clone/test/widget_test.dart"},"type":"suite","time":1}
{"test":{"id":1,"name":"loading /Users/builder/clone/test/widget_test.dart","suiteID":0,"groupIDs":[],"metadata":{"skip":false,"skipReason":null},"line":null,"column":null,"url":null},"type":"testStart","time":3}
{"count":1,"type":"allSuites","time":7}
{"testID":1,"result":"success","skipped":false,"hidden":true,"type":"testDone","time":15317}
{"group":{"id":2,"suiteID":0,"parentID":null,"name":null,"metadata":{"skip":false,"skipReason":null},"testCount":1,"line":null,"column":null,"url":null},"type":"group","time":15341}
{"test":{"id":3,"name":"Counter increments smoke test","suiteID":0,"groupIDs":[2],"metadata":{"skip":false,"skipReason":null},"line":107,"column":3,"url":"package:flutter_test/src/widget_tester.dart","root_line":14,"root_column":3,"root_url":"file:///Users/builder/clone/test/widget_test.dart"},"type":"testStart","time":15343}
{"testID":3,"messageType":"print","message":"══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════\nThe following TestFailure object was thrown running a test:\n  Expected: exactly one matching node in the widget tree\n  Actual: ?:<zero widgets with text \"0\" (ignoring offstage widgets)>\n   Which: means none were found but one was expected\n\nWhen the exception was thrown, this was the stack:\n#4      main.<anonymous closure> (file:///Users/builder/clone/test/widget_test.dart:19:5)\n<asynchronous suspension>\n#5      testWidgets.<anonymous closure>.<anonymous closure> (package:flutter_test/src/widget_tester.dart:118:25)\n<asynchronous suspension>\n#6      TestWidgetsFlutterBinding._runTestBody (package:flutter_test/src/binding.dart:630:19)\n<asynchronous suspension>\n#9      TestWidgetsFlutterBinding._runTest (package:flutter_test/src/binding.dart:613:14)\n#10     AutomatedTestWidgetsFlutterBinding.runTest.<anonymous closure> (package:flutter_test/src/binding.dart:1010:24)\n#16     AutomatedTestWidgetsFlutterBinding.runTest (package:flutter_test/src/binding.dart:1007:15)\n#17     testWidgets.<anonymous closure> (package:flutter_test/src/widget_tester.dart:116:22)\n#18     Declarer.test.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:test_api/src/backend/declarer.dart:168:27)\n<asynchronous suspension>\n#19     Invoker.waitForOutstandingCallbacks.<anonymous closure> (package:test_api/src/backend/invoker.dart:250:15)\n<asynchronous suspension>\n#24     Invoker.waitForOutstandingCallbacks (package:test_api/src/backend/invoker.dart:247:5)\n#25     Declarer.test.<anonymous closure>.<anonymous closure> (package:test_api/src/backend/declarer.dart:166:33)\n#30     Declarer.test.<anonymous closure> (package:test_api/src/backend/declarer.dart:165:13)\n<asynchronous suspension>\n#31     Invoker._onRun.<anonymous closure>.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:test_api/src/backend/invoker.dart:400:25)\n<asynchronous suspension>\n#45     _Timer._runTimers (dart:isolate-patch/timer_impl.dart:382:19)\n#46     _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:416:5)\n#47     _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:172:12)\n(elided 28 frames from class _FakeAsync, package dart:async, package dart:async-patch, and package stack_trace)\n\nThis was caught by the test expectation on the following line:\n  file:///Users/builder/clone/test/widget_test.dart line 19\nThe test description was:\n  Counter increments smoke test\n════════════════════════════════════════════════════════════════════════════════════════════════════","type":"print","time":17092}
{"testID":3,"error":"Test failed. See exception logs above.\nThe test description was: Counter increments smoke test","stackTrace":"","isFailure":false,"type":"error","time":17119}
{"testID":3,"result":"error","skipped":false,"hidden":false,"type":"testDone","time":17134}
{"success":false,"type":"done","time":17231}


QA failed :|
Flutter test run failed.

== QA failed, ending build ==


Build failed :|
Test run failed: Flutter test run failed.

我的Widget_test文件代码是

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

import 'package:top100/main.dart';

void main() {
  testWidgets('Counter increments smoke test', (WidgetTester tester) async {
    // Build our app and trigger a frame.
    await tester.pumpWidget(MyApp());

    // Verify that our counter starts at 0.
    expect(find.text('0'), findsOneWidget);
    expect(find.text('1'), findsNothing);

    // Tap the '+' icon and trigger a frame.
    await tester.tap(find.byIcon(Icons.add));
    await tester.pump();

    // Verify that our counter has incremented.
    expect(find.text('0'), findsNothing);
    expect(find.text('1'), findsOneWidget);
  });
}

widget_test.dart文件是用Flutter默认工程创建的,有两个文本框和一个可以点击的图标。由于您修改了应用程序 UI,现在您可能会显示不同的元素并且测试失败,因为它需要模板项目元素,而您现在没有。您可以评论 testWidgets 方法以快速修复:

// This is a basic Flutter widget test.
//
// To perform an interaction with a widget in your test, use the WidgetTester
// utility that Flutter provides. For example, you can send tap and scroll
// gestures. You can also use WidgetTester to find child widgets in the widget
// tree, read text, and verify that the values of widget properties are correct.

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

import 'package:fin_app_flutter/main.dart';

void main() {
  /*
  testWidgets('Counter increments smoke test', (WidgetTester tester) async {
    // Build our app and trigger a frame.
    await tester.pumpWidget(MyApp());

    // Verify that our counter starts at 0.
    expect(find.text('0'), findsOneWidget);
    expect(find.text('1'), findsNothing);

    // Tap the '+' icon and trigger a frame.
    await tester.tap(find.byIcon(Icons.add));
    await tester.pump();

    // Verify that our counter has incremented.
    expect(find.text('0'), findsNothing);
    expect(find.text('1'), findsOneWidget);
  });
  */
}

记得在 Codemagic 上提交并同步您的分支。

发生这种情况是因为 Codemagic 正在尝试 运行 您可能没有的集成测试。请注意,集成测试不同于单元测试或小部件测试。集成测试由 Flutter Driver 运行,read more.

集成测试也称为“Flutter Driver 测试”。如果你做 flutter drive,Flutter 运行 会在你的项目中进行所有的集成测试。这是帮助命令的一个片段:

话虽如此,您收到该错误的原因是您的项目中没有任何集成测试。您所要做的就是在您的 Codemagic 工作流程中禁用集成测试:

我删除了测试文件夹和 运行 它,它工作正常。