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-inlibrary'dart:html'isnot 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 testtest/extract_test.dart
On windows you can do the same
setDART_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!