首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么一些Flutter小部件测试在一起执行时会失败,但会单独通过?

为什么一些Flutter小部件测试在一起执行时会失败,但会单独通过?
EN

Stack Overflow用户
提问于 2021-08-31 11:38:15
回答 2查看 457关注 0票数 3

在同一个文件中有多个测试,并且一个接一个地运行测试时。某些类型的测试会失败,但当单独运行时,相同的测试会通过。

这是我目前的测试文件,虽然有点长:

代码语言:javascript
复制
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:rec/Components/Inputs/text_fields/DniTextField.dart';
import 'package:rec/Helpers/Validators.dart';

import '../../test_utils.dart';

void main() {
  testWidgets('DniTextField works with invalid DNI', (WidgetTester tester) async {
    var key = GlobalKey<DniTextFieldState>();
    var formKey = GlobalKey<FormState>();
    var onChangedResult;

    var widget = Form(
      key: formKey,
      child: DniTextField(
        key: key,
        onChange: (String value) {
          onChangedResult = value;
        },
        validator: (s) => Validators.verifyIdentityDocument(s),
      ),
    );
    await tester.pumpWidget(
      TestUtils.wrapPublicRoute(widget),
    );
    await tester.pumpAndSettle();

    // Test that widget has at least rendered
    TestUtils.widgetExists(widget);

    // Enter text into field with
    var widgetFinder = find.byWidget(widget);
    await tester.tap(widgetFinder);
    await tester.showKeyboard(widgetFinder);
    await tester.enterText(widgetFinder, 'invaliddni');

    await tester.pumpAndSettle();

    expect(onChangedResult, 'invaliddni');

    expect(formKey.currentState.validate(), false);
  });

  testWidgets('DniTextField works with valid DNI', (WidgetTester tester) async {
    var key = GlobalKey<DniTextFieldState>();
    var formKey = GlobalKey<FormState>();
    var onChangedResult;

    var widget = Form(
      key: formKey,
      child: DniTextField(
        key: key,
        onChange: (String value) {
          onChangedResult = value;
        },
        validator: (s) => Validators.verifyIdentityDocument(s),
      ),
    );
    await tester.pumpWidget(
      TestUtils.wrapPublicRoute(widget),
    );
    await tester.pumpAndSettle();

    // Enter text into field
    var widgetFinder = find.byType(DniTextField);
    await tester.tap(widgetFinder);
    await tester.showKeyboard(widgetFinder);
    await tester.enterText(widgetFinder, '80008000k');

    await tester.pumpAndSettle();

    expect(onChangedResult, '80008000k');

    expect(formKey.currentState.validate(), true);
  });

  testWidgets('DniTextField works with valid DNI with trailing space', (WidgetTester tester) async {
    var key = GlobalKey<DniTextFieldState>();
    var formKey = GlobalKey<FormState>();
    var onChangedResult;

    var widget = Form(
      key: formKey,
      child: DniTextField(
        key: key,
        onChange: (String value) {
          onChangedResult = value;
        },
        validator: (s) => Validators.verifyIdentityDocument(s),
      ),
    );
    await tester.pumpWidget(TestUtils.wrapPublicRoute(widget));
    await tester.pumpAndSettle();

    // Enter text into field
    var widgetFinder = find.byWidget(widget);
    await tester.tap(widgetFinder);
    await tester.showKeyboard(widgetFinder);
    await tester.enterText(widgetFinder, '80008000k ');

    await tester.pumpAndSettle();

    // The value emitted by the field, should be free of trailing whitespace
    expect(onChangedResult, '80008000k');

    expect(formKey.currentState.validate(), true);
  });
}

如果我像这样运行:

代码语言:javascript
复制
$ flutter test test/Components/inputs/dni_text_field_test.dart

第一个测试通过了,但接下来的两个测试没有通过,并显示了以下错误:

代码语言:javascript
复制
══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
The following assertion was thrown running a test:
The finder "zero widgets with the given widget
(DniTextField-[LabeledGlobalKey<DniTextFieldState>#0fb86]) (ignoring offstage widgets)" (used in a
call to "tap()") could not find any matching widgets.

When the exception was thrown, this was the stack:
#0      WidgetController._getElementPoint (package:flutter_test/src/controller.dart:902:7)
#1      WidgetController.getCenter (package:flutter_test/src/controller.dart:841:12)
#2      WidgetController.tap (package:flutter_test/src/controller.dart:273:18)
#3      main.<anonymous closure> (file:///[masked]/test/Components/inputs/dni_text_field_test.dart:99:18)
<asynchronous suspension>
<asynchronous suspension>
(elided one frame from package:stack_trace)

如果我注释掉第一个测试,那么第二个测试通过了,但是第三个没有通过。正如我所说的,如果我单独运行它们,测试就会通过。

我找不到任何关于这件事的信息,甚至一件事也找不到。也许这里有人能给我指引正确的方向。我是Flutter小部件测试的新手,所以我可能会错过一些重要的东西。

到目前为止,我找到的唯一解决方案是将每个测试放在单独的文件中。但这并不理想,最好将相关的测试包含在同一个文件中。Flutter的例子表明,每个文件都允许进行多个测试,这是应该的。

Flutter版本: 2.4.0-5.0.pre.87

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-08-31 19:35:19

好了,我找到了解决方案和原因,修复了this问题和this SO问题。

主要问题是使用从JSON文件加载的本地化。解决方案是用tester.runAsync()包装每个测试

代码语言:javascript
复制
testWidgets('widget test 2', (WidgetTester tester) async {
  await tester.runAsync(() async {
    // tests
  });
});
票数 3
EN

Stack Overflow用户

发布于 2021-08-31 12:19:15

我认为当不同的测试没有创建不同的小部件实例(或者它们在其他方面存在冲突)时,就会出现这个问题,但有一个转变可能会对您有所帮助。

如果你想创建一个运行所有测试的按钮,你可以创建一个bash (或windows上的cmd )文件,它会按顺序运行所有的测试。

示例all_tests.cmd

代码语言:javascript
复制
dart test_1.dart
dart test_2.dart
dart test_3.dart

这不是最清晰的解决方案,但它可能第一次起作用。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68997984

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档