live_test_view 0.2.1 copy "live_test_view: ^0.2.1" to clipboard
live_test_view: ^0.2.1 copied to clipboard

Watch Flutter widget tests render live in your editor. Companion package for the Live Test View VS Code extension.

live_test_view #

Streams rendered frames from your Flutter widget tests so the Live Test View VS Code extension can replay them live in an editor panel. On its own — without the extension driving it — this package does nothing observable at all.

Live Test View demo

Install #

flutter pub add --dev live_test_view
dart run live_test_view:install

The installer writes test/flutter_test_config.dart for you. If that file already exists, it won't be overwritten — the installer instead prints the one-line change needed to wrap your existing testExecutable:

Future<void> testExecutable(FutureOr<void> Function() testMain) =>
    liveTestView(() => yourExistingSetup(testMain));

What the config file does #

flutter_test_config.dart is a special file package:test looks for and, if present, uses to wrap every test in the directory. The generated file looks like this:

import 'dart:async';

import 'package:live_test_view/live_test_view.dart';

Future<void> testExecutable(FutureOr<void> Function() testMain) =>
    liveTestView(testMain);

liveTestView checks the LIVE_TEST_VIEW environment variable. When it's unset (every normal flutter test run, including CI), it just calls testMain() and returns — see "the silence invariant" below. When the Live Test View extension runs a test, it sets LIVE_TEST_VIEW=1 in the child process's environment; liveTestView then attaches a persistent frame callback that snapshots the render tree after every paint, encodes each snapshot as PNG, and writes it to stdout as a single line prefixed with ##LTV## followed by JSON (v, seq, testTimeMs, w, h, png). The extension's test runner reads these lines back out; you never need to parse them yourself.

The silence invariant #

This package is designed so that adding it can never change your test suite's behavior or output under a plain flutter test run. With LIVE_TEST_VIEW unset, liveTestView is a pass-through: no frame callback is registered, nothing is written to stdout, and the only cost is one environment-variable check. This is covered by an end-to-end test that asserts a run without the flag is byte-for-byte identical, stdout included, to a run without the package wired in at all.

Companion extension #

This package only captures and streams frames — it has no UI of its own. Pair it with the "Live Test View" VS Code extension, which adds the "▶ Live View" CodeLens, runs your tests, and renders the captured frames in a scrubbable timeline panel.

Fonts #

flutter test renders all text with a placeholder font (every glyph a solid box) unless something loads real fonts in. When LIVE_TEST_VIEW=1, liveTestView does this for you before testMain runs, via loadRealFonts():

  • Roboto — resolved from the running Flutter SDK's own cache (bin/cache/artifacts/material_fonts), so it works with any SDK install without the project needing to bundle it.
  • Every family in the test build's FontManifest.json — this covers project fonts declared under flutter: fonts: in pubspec.yaml, package-bundled fonts, and MaterialIcons. Each family is loaded independently; if one fails (bad asset, malformed manifest entry), a ##LTV## warning line is emitted naming it and the rest of the manifest still loads.

google_fonts is not covered by either mechanism and can't be made to work here. It isn't in FontManifest.json — it fetches its .ttf over HTTP the first time GoogleFonts.xxx() is called, as a fire-and-forget Future the widget doesn't await. Two things make this unrecoverable inside flutter test:

  1. flutter_test installs a global HttpOverrides that makes every HTTP request in the process return a fake 400, so the fetch always fails.
  2. The fetch is initiated inside flutter_test's FakeAsync-controlled zone (during widget build()). Bypassing the HTTP mock and awaiting the request from a real zone afterward (binding.runAsync) doesn't help — it deadlocks, because the pending Future is entangled with a fake clock that nothing is advancing anymore. There's no sequencing trick around this from outside google_fonts.

If a project needs google_fonts text to render in Live Test View, bundle the actual .ttf files as assets and set GoogleFonts.config.allowRuntimeFetching = false in the app. That routes google_fonts through the local asset bundle instead of the network — the same FontManifest.json-backed path above, which already works. This is google_fonts' own recommended setup for golden/widget tests generally: https://pub.dev/packages/google_fonts#offline-support-and-cache

Requirements #

  • Flutter >= 3.16
  • Dart SDK >= 3.2

License #

MIT — see LICENSE.

0
likes
150
points
56
downloads

Documentation

API reference

Publisher

verified publisheranirudhsingh.in

Weekly Downloads

Watch Flutter widget tests render live in your editor. Companion package for the Live Test View VS Code extension.

Repository

License

MIT (license)

Dependencies

flutter, flutter_test

More

Packages that depend on live_test_view