avatarDaniel Varga

Summary

The web content discusses a method for running Dart VM tests with dart:html by using optional imports and a compatible package, despite the default unavailability of dart:html in the stand-alone VM.

Abstract

The article titled "Dart VM tests with dart:html — yes, you can!" addresses the challenge of running Dart VM tests that require the dart:html library, which is not natively supported on the stand-alone VM. The author explains that while tests can be run in a browser using pub with the -p somebrowser flag, this approach has drawbacks such as the need for a browser, slower execution, and potential unnecessary browser functionality dependencies. The solution proposed involves using optional imports, which allow for platform-specific imports based on a condition. This condition can be set through a -D flag or the DART_VM_OPTIONS environment variable. The author illustrates this with a use-case, demonstrating how to modify a test to use package:html for VM compatibility. The article concludes with a note on the importance of ensuring compatibility between package replacements and the original dart:html functionality for reliable tests.

Opinions

  • The author acknowledges the inconvenience of not being able to run tests with dart:html on the VM by default.
  • Running tests in a browser is seen as less efficient due to slower execution and the necessity of having a browser available.
  • The author has concerns about the use of optional imports as a solution, indicating a desire for community feedback on this approach.
  • There is an emphasis on the need for a transformer or similar mechanism to ensure server-compatible imports are used consistently.
  • The author suggests that the package:html can serve as a compatible replacement for dart:html in many cases, facilitating VM testing.
  • The importance of checking for compatibility between package:html and dart:html is highlighted to maintain test reliability.

Dart VM tests with `dart:html` — yes, you can!

Well, sort of. Let me clarify what I mean by yes, you can. By default, running VM tests doesn’t allow for dart:html import. If you try, you will see a message similar to this:

Unable to spawn isolate: The built-in library 'dart:html' is not available on the stand-alone VM.

You can still run such tests in a browser (Dart won’t leave you hanging) by simply passing -p somebrowser to pub. More info about supported platforms here. However, this has some drawbacks:

  • you must have some kind of browser to run them
  • they are always slower than VM tests
  • sometimes you just need a super-small subset of browser functionality to get going
  • sometimes dart:html features are completely unused, transitive dependency that should not have any effect or impact on the test results*

I build Angular Dart applications with complex business logic. A lot of the code is completely decoupled from the browser that can be easily unit-tested, however some have that annoying transitive import somewhere deep in the code. A way I found to deal with this is via optional imports. A side note: I still have concerns about this approach and will be interested to read community response to it.

* You will need a transformer or similar mechanics to go over source files and make sure that server compatible imports are used — everywhere.

The magic of optional imports

Or you might see them as “configuration specific imports”. A quick google search will reveal poor results to understand it. In short, the syntax looks like this:

import "something.dart" if (condition) "other.dart";

Very useful if your application/package targets multiple platforms such as browsers, NodeJS (eg. DartSass) or DartVM.

condition is evaluated to true by passing a -D flag to dart command.

dart -Dcondition=true my_app.dart

or by setting a special DART_VM_OPTIONS environment variable. This latter is particularly useful if you intend to run your app via pub or other build tools. (again, search for this in google site:dartlang.org "DART_VM_OPTIONS" )

A simple use-case

Consider the following piece of code and the test to it.

All it does: naively extracts textual content split by space from a piece of markup. One could go to great lengths to make this functionality VM compatible by parsing, sanitizing the input or could go the quicker route: use what we already got to do the same.

One problem: won’t run on VM.

Let’s alter it (patch syntax ahead)

-import 'dart:html';
+import 'dart:html' if (dart_vm) 'package:html/dom.dart';

With the modification of that one line — symbols that are normally in dart:html and is only available in the browser — are available on the VM as well. package:html offers a lot of the same (mostly compatible) functionality.

To run this test, the following one-liner can be used to set the appropriate VM flag and lunch it via pub.

DART_VM_OPTIONS=-Ddart_vm=true pub run test test/extract_test.dart

On windows you can do the same

set DART_VM_OPTIONS=-Ddart_vm=true
pub run test test\extract_test.dart

Test reliability matter

A personal note: there are things to consider when using this method. Developers should check if such package replacements can be made. Eg. implementations are compatible with each-other.

All in all, I hope you find the information useful. Thanks for the read!

Dartlang
Dart
Software Testing
Recommended from ReadMedium