Dart/Flutter Web 单元测试错误:错误:未找到:'dart:html'

ski*_*erg 21 dart flutter flutter-test flutter-web

我正在开发 Flutter Web 应用程序,但在运行测试时遇到问题。

Flutter 1.7.8+hotfix.4 • channel stable • git@github.com:flutter/flutter.git
Framework • revision 20e59316b8 (9 weeks ago) • 2019-07-18 20:04:33 -0700
Engine • revision fee001c93f
Tools • Dart 2.4.0
Run Code Online (Sandbox Code Playgroud)

这是 pubspec.yaml:

name: web_flutter
description: An app built using Flutter for web

environment:
  # You must be using Flutter >=1.5.0 or Dart >=2.3.0
  sdk: '>=2.3.0-dev.0.1 <3.0.0'

dependencies:
  flutter_web: any
  flutter_web_ui: any
  provider: any
  rxdart: ^0.22.0
  http: ^0.12.0+2
  json_annotation: ^2.4.0
  intl: 0.15.8


dev_dependencies:
  build_runner: ^1.4.0
  build_web_compilers: ^2.0.0
  pedantic: ^1.0.0
  json_serializable: ^3.0.0
  test: any

flutter:
  uses-material-design: true

dependency_overrides:
  flutter_web:
    git:
      url: https://github.com/flutter/flutter_web
      path: packages/flutter_web
  flutter_web_ui:
    git:
      url: https://github.com/flutter/flutter_web
      path: packages/flutter_web_ui
  provider:
    git:
      url: https://github.com/kevmoo/provider
      ref: flutter_web

Run Code Online (Sandbox Code Playgroud)

我编写了几个测试,当我pub run test在 IDE 的终端(VS Code)或终端应用程序中运行时,这些测试都通过了。

我遇到问题的测试需要从项目中导入一些包。有了这个测试,我得到了错误,其他两个测试没有运行。我还没有找到任何指向解决方案的东西。

这是错误消息:

pub run test                                                                                         MyMac@MyMac
00:06 +0 -1: loading test/service_test.dart [E]                                                                                                                          
  Failed to load "test/service_test.dart":
  Unable to spawn isolate: file:///Users/MyMac/.pub-cache/git/flutter_web-c04fb502b842859de07e36954a9390465a5426c0/packages/flutter_web_ui/lib/ui.dart:12:8: Error: Not found: 'dart:html'
  import 'dart:html' as html;
         ^
  file:///Users/MyMac/.pub-cache/git/flutter_web-c04fb502b842859de07e36954a9390465a5426c0/packages/flutter_web_ui/lib/src/engine.dart:11:8: Error: Not found: 'dart:html'
  import 'dart:html' as html;
         ^
  file:///Users/MyMac/.pub-cache/git/flutter_web-c04fb502b842859de07e36954a9390465a5426c0/packages/flutter_web/lib/src/services/asset_bundle.dart:7:8: Error: Not found: 'dart:html'
  import 'dart:html' show HttpRequest;
         ^
  file:///Users/MyMac/.pub-cache/git/flutter_web-c04fb502b842859de07e36954a9390465a5426c0/packages/flutter_web_ui/lib/src/engine.dart:12:8: Error: Not found: 'dart:js'
  import 'dart:js' as js;
         ^
  file:///Users/MyMac/.pub-cache/git/flutter_web-c04fb502b842859de07e36954a9390465a5426c0/packages/flutter_web_ui/lib/src/engine.dart:13:8: Error: Not found: 'dart:js_util'
  import 'dart:js_util' as js_util;
         ^
  file:///Users/MyMac/.pub-cache/git/flutter_web-c04fb502b842859de07e36954a9390465a5426c0/packages/flutter_web_ui/lib/src/ui/compositing.dart:20:9: Error: Type 'html.Element' not found.
    final html.Element webOnlyRootElement;
          ^^^^^^^^^^^^
  file:///Users/MyMac/.pub-cache/git/flutter_web-c04fb502b842859de07e36954a9390465a5426c0/packages/flutter_web_ui/lib/src/engine.dart:177:37: Error: Type 'html.NodeTreeSanitizer' not found.
  class _NullTreeSanitizer implements html.NodeTreeSanitizer {
                                      ^^^^^^^^^^^^^^^^^^^^^^
  file:///Users/MyMac/.pub-cache/git/flutter_web-c04fb502b842859de07e36954a9390465a5426c0/packages/flutter_web_ui/lib/src/engine.dart:179:21: Error: Type 'html.Node' not found.
    void sanitizeTree(html.Node node) {}
                      ^^^^^^^^^
  file:///Users/MyMac/.pub-cache/git/flutter_web-c04fb502b842859de07e36954a9390465a5426c0/packages/flutter_web_ui/lib/src/engine/bitmap_canvas.dart:26:9: Error: Type 'html.Element' not found.
    final html.Element rootElement = html.Element.tag('flt-canvas');
          ^^^^^^^^^^^^
  file:///Users/MyMac/.pub-cache/git/flutter_web-c04fb502b842859de07e36954a9390465a5426c0/packages/flutter_web_ui/lib/src/engine/bitmap_canvas.dart:28:3: Error: Type 'html.CanvasElement' not found.
    html.CanvasElement _canvas;
    ^^^^^^^^^^^^^^^^^^
00:06 +0 -1: Some tests failed.
Run Code Online (Sandbox Code Playgroud)

如果我注释掉这个新测试,错误仍然存​​在。如果我注释掉测试和相关的导入,剩下的两个测试就会运行并通过。

这是测试文件(我把有问题的代码注释掉了,这样你更容易看到——我希望)。

import 'package:test/test.dart';
import 'package:http/http.dart';
import 'package:http/testing.dart';
import 'dart:convert';
import 'package:web_flutter/services/service.dart';
// These are the package imports that cause errors:
import 'package:web_flutter/model/model.dart';
import 'package:web_flutter/data/tenant_view_model.dart';

void main(){

  test("getSubmission returns ResponseData{}", () async {
    // Arrange: setup the test
    final _service = Service();

    _service.httpClient = MockClient((request) async {
      final responseData = {
        "id": "some_id",
        "state": "processed",
        "test": true,
        "editable": false,
        "expires_at": "2019-09-19T03:40:22Z",
        "processed_at": "2019-09-12T03:40:22Z",
        "batch_id": "",
        "download_url": "downloadURl.com",
        "permanent_download_url": "permanentdownloadURL.com"
      };
      return Response(json.encode(responseData),200);
    });

    // Act
    final response = await _service.getSubmission("submissionID");

    // Assert
    expect(response.download_url, "downloadURL.com");
  });
  test("generateForm returns SubmissionResponse{}", () async {
    // Arrange: setup the test
    final _service = Service();

    _service.httpClient = MockClient((request) async {
      final submissionResponse = {
        "status": "success",
        "submission": {
          "id": "some_id",
          "state": "pending",
          "test": false,
          "editable": false,
          "expired": false,
          "expires_at": null,
          "metadata": {
            "foo": 123,
            "bar": "baz"
          },
          "processed_at": null,
          "batch_id": null,
          "data_requests": [],
          "download_url": null,
          "permanent_download_url": null
        }
      };
      return Response(json.encode(submissionResponse),200);
    });

    // Act
    final response = await _service.generateForm(42, "templateID");

    // Assert
    expect(response.submission.id, "some_id");
  });

  test('Tenant View Model generateForm returns tenantVM.submission.submission.id', () async {
    // Arrange
    final _service = Service();
    Tenant tenant;
    tenant.id = 42;

    _service.httpClient = MockClient((request) async {
      final submissionResponse = {
        "status": "success",
        "submission": {
          "id": "some_id",
          "state": "pending",
          "test": false,
          "editable": false,
          "expired": false,
          "expires_at": null,
          "metadata": {
            "foo": 123,
            "bar": "baz"
          },
          "processed_at": null,
          "batch_id": null,
          "data_requests": [],
          "download_url": null,
          "permanent_download_url": null
        }
      };
      return Response(json.encode(submissionResponse),200);
    });
    TenantViewModel tenantVM = TenantViewModel(tenant, _service);

    // Act
    await tenantVM.generateForm("templateID");

    // Assert
    expect(tenantVM.submission.submission.id, "some_id");
  });
}

Run Code Online (Sandbox Code Playgroud)

这是具有我要测试的方法的类 ( generateForm())。

import 'package:flutter_web/cupertino.dart';
import 'package:web_flutter/model/model.dart';
import 'package:web_flutter/services/service.dart';

class TenantViewModel with ChangeNotifier {
  Tenant _tenant;
  Property _property;
  Service _service;
  SubmissionResponse _submission;
  ResponseData _responseData;

  TenantViewModel(this._tenant, this._service);

  bool get isNew => _tenant.id == null;

  set tenant(Tenant tenant) {
    if (_tenant != tenant) {
      _tenant = tenant;
      notifyListeners();
    }
  }

  Tenant get tenant => _tenant;

  set property(Property property) {
    _tenant.propertyId = property.id;
    notifyListeners();
  }

  Property get property => _property;

  set submission(SubmissionResponse submission) {
    if (_submission != submission) {
      _submission = submission;
      notifyListeners();
    }
  }

  SubmissionResponse get submission => _submission;

  set responseData(ResponseData responseData) {
    if (_responseData != responseData) {
      _responseData = responseData;
      notifyListeners();
    }
  }

  ResponseData get responseData => _responseData;

  Future generateForm(String templateID) async {
    SubmissionResponse submission;

    submission = await _service.generateForm(_tenant.id, templateID);
    this.submission = submission;

    notifyListeners();
  }

  Future getSubmission(String submissionID) async {
    ResponseData responseData;

    responseData = await _service.getSubmission(submissionID);
    this.responseData = responseData;

    notifyListeners();
  }

  Future save() async {
    Tenant updatedTenant;
    if (tenant.isNew) {
      updatedTenant = await _service.createTenant(_tenant);
      this.tenant = updatedTenant;
    } else {
      updatedTenant = await _service.updateTenant(tenant);
      this.tenant = updatedTenant;
    }
    notifyListeners();
  }

  Future refresh() async {
    if (isNew) {
      return;
    }
    var updatedTenant = await _service.getTenant(_tenant.id);
    if (_tenant.propertyId != null) {
      _property = await _service.getProperty(_tenant.propertyId);
    }
    _tenant = updatedTenant;
    notifyListeners();
  }
}
Run Code Online (Sandbox Code Playgroud)

我尝试过: import 'package:flutter_test/flutter_test.dart';在测试文件中并将其添加到 pubspec.yaml 中:

  flutter_test:
    sdk: flutter
Run Code Online (Sandbox Code Playgroud)

这些会导致各种错误,因为我使用的是 Flutter Web,而不是 Flutter。谁能看到我哪里出错了?

我知道我正在进行的测试可能是错误的,但我什至无法让它运行并失败。

小智 41

我在开发移动应用程序时遇到了类似的问题,但结果是我不小心导入了包dart.html。我刚刚删除它,我能够运行该程序。

  • 谢谢,这也正是发生在我身上的事情! (9认同)
  • 如果我们需要 dart.html 怎么办? (2认同)

Sup*_*ana 16

当您尝试导入 @required 之类的内容时,可能会发生这种情况。然后flutter就会不小心把import dart.html代码放到上面了。只需从代码中删除它即可解决您的问题。


Joh*_*ips 14

由于您正在为使用 dart:html 包的 web 运行 flutter 测试,因此您必须针对正确的平台。

flutter test --platform chrome


ski*_*erg 3

问题的出现是因为,正如我的技术主管指出的那样,“单元测试无法访问dart:html. 除非您在浏览器中运行它们。”

来自 pub.dev/packages/test:

“默认情况下,测试在 Dart VM [虚拟机] 中运行,但您也可以通过传递 来在浏览器中运行它们pub run test -p chrome path/to/test.darttest将负责启动浏览器并加载测试,所有结果都将报告在命令行就像 VM 测试一样。事实上,您甚至可以使用单个命令在两个平台上运行测试:pub run test -p "chrome,vm" path/to/test.dart

为了解决我的特定问题,我使用 进行了测试pub run test test/print_reports_card_test.dart -p chrome