【问题标题】:Dart/Flutter Web unit testing errors: Error: Not found: 'dart:html'Dart/Flutter Web 单元测试错误:错误:未找到:'dart:html'
【发布时间】:2020-01-18 19:18:42
【问题描述】:

我正在开发一个 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

这是 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

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

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

这是错误信息:

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.

如果我注释掉这个新测试,错误仍然存​​在。如果我注释掉测试和相关导入,其余两个测试将运行并通过。

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

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");
  });
}

这是具有我正在尝试测试的方法的类 (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();
  }
}

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

  flutter_test:
    sdk: flutter

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

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

【问题讨论】:

  • 单元测试无权访问 dart:html 除非你在浏览器中运行它们
  • 来自pub.dev/packages/test: "默认情况下,测试在 Dart VM 中运行,但您也可以通过传递 pub run test -p chrome path/to/test.dart 在浏览器中运行它们。test 将负责启动浏览器并加载测试,所有结果都会像VM测试一样在命令行上报告。事实上,你甚至可以用一个命令在两个平台上运行测试:pub run test -p "chrome,vm" path/to/test.dart"
  • 在浏览器上运行它们以进行 Web 集成测试的任何方式,我正在运行如下命令:flutter drive --target=test_driver/file_storage.dart -v --use-existing- app=/localhost:53201

标签: flutter dart flutter-test flutter-web


【解决方案1】:

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

【讨论】:

  • 谢谢,这正是发生在我身上的事情!
  • 我已经多次犯过这个错误了。我认为总是在尝试导入 @required 时
  • 或者你可能错误地添加了一些你不应该添加的其他包
【解决方案2】:

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

flutter test --platform chrome

【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      问题的出现是因为,正如我的技术负责人所指出的,“单元测试无权访问 dart:html。除非您在浏览器中运行它们。”

      来自 pub.dev/packages/test:

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

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

      【讨论】:

      • 这个答案需要改进,因为它没有解决以前的测试通过但新的测试没有通过的原因。问题是dart:html 何时何地被导入?我已将它导入另一个文件,但删除导入并没有解决问题,因此我认为它是由某些依赖项导入的。
      【解决方案5】:

      import 'dart:html'; 更改为import 'package:http/http.dart' as http;

      然后将pubspec.yaml文件依赖改为

      dependencies:
      flutter:
      sdk: flutter
      http:
      

      然后点击pub get

      【讨论】:

      • 谢谢你最好的
      【解决方案6】:

      我遇到了完全相同的问题。我的问题是我导入了package:url_launcher_web/url_launcher_web.dart,显然你不应该这样做。无论如何,这是一个未使用的导入,所以我将其删除,然后我的手机就可以正常工作了。

      要修复它,删除它,问题就会解决。

      为什么会出现这个错误: 当不需要导入时,分析器会生成此诊断信息,因为导入库中没有引用任何导入的名称。

      示例

      以下代码会产生此诊断信息,因为在

      中没有定义任何内容
      dart:async
      

       在库中被引用:

      import 'dart:async';
      
      void main() {}
      

      常见修复

      如果不需要导入,则将其删除。

      如果打算使用某些导入的名称,则添加缺少的代码。

      【讨论】:

        【解决方案7】:

        如果您同时进行网络和移动测试,另一种解决方案是在测试文件的顶部添加 @TestOn('browser')
        这是完整的doc

        【讨论】:

          【解决方案8】:

          当语言模式不合适时,有时会发生此错误。确保“选择语言模式”(图中黄色圆圈)处于正确模式。对于这种情况,我认为应该是 HTML

          【讨论】:

            【解决方案9】:

            您在哪个文件中添加了 import 'dart:html' 只需将其删除,然后再次执行代码。我认为问题会得到解决。在此之后,我解决了我的问题。

            【讨论】:

              猜你喜欢
              • 2022-09-29
              • 2020-12-26
              • 2018-08-05
              • 1970-01-01
              • 2018-12-27
              • 1970-01-01
              • 1970-01-01
              • 2022-11-15
              • 1970-01-01
              相关资源
              最近更新 更多