pub.dev Verified Publisher / letstesttools.dev

Tools for testing.
Built by testing the tools.

testing as an adjective testing as a verb

We engineer high-performance property testing frameworks, and we torture-test developer tools to their breaking point. Automated counterexample shrinking, persistent regression databases, and widget sweeps for Dart and Flutter.

$ dart pub add dev:hegeltest
LETSTESTTOOLS RUNTIME METRICS STABLE
pub.dev Score 160 / 160 Across all published packages
Regression Replay Iteration 1 Zero search time via .hegel/
Native Core libhegel (Rust) Prebuilt via Dart Native Assets
CI Multi-Arch macOS · Linux · Win arm64 & x86_64 matrix verified
// OUR MISSION

The Dual Nature of LetsTestTools

Adjective

Testing Tools

We build industrial-grade developer software specifically designed for automated quality assurance. Property-based fuzzers, coverage-guided mutation engines, AST-aware shrinking algorithms, and stateful model checkers that relieve engineers from having to guess edge cases by hand.

What we produce: hegeltest, hegeltest_flutter
Verb + Object

Testing Tools

We test the developer tools themselves. Compilers, serialization pipelines, state management stores, widget layout engines, and FFI bridges are complex pieces of software prone to subtle regressions. We subject these tools to millions of chaotic adversarial inputs to verify they hold under pressure.

How we engineer: Zero-flakiness, formal invariants, stress CI
// TACTILE DEMONSTRATION

Experience Property Fuzzing & Shrinking

Watch the engine generate pseudorandom inputs, catch an unexpected assertion violation, mathematically shrink it to the single smallest counterexample, and persist it to disk.

hegel_runner --property="queue_invariants"
// Property under test: forall (List<int> xs) => xs.sum >= 0
// Ready to start. Click "Run Property Fuzz" to initiate the engine.
// VERIFIED REPOSITORIES

Published Packages

Distributed under the verified publisher identity letstesttools.dev on pub.dev.

hegeltest

v0.9.0

Core property-based testing and fuzzing engine for pure Dart. Features coverage-guided generation, automated binary shrinking, distribution coverage contracts, and persistent counterexample caching.

160/160 pub points MIT Dart Native Assets
  • Distribution Coverage Contracts: Enforce edge-case exploration guarantees with tc.cover() and conditional classification via tc.classify().
  • Weighted Sampling: Directly sample raw values and generator branches with sampledWeighted() and oneOfWeighted().
  • Persistent Database: Auto-caches discovered failures to .hegel/examples/ for instant regression verification on iteration 1.
  • Zero Native Setup: Bundles precompiled libhegel_c binaries for macOS, Linux, and Windows; SHA-256 verified via hook/build.dart.
  • Rich Generator Library: Primitives, text/regex, recursive collections, temporal dates, and IP networks.

hegeltest_flutter

v0.9.0

First-class Flutter integration for accessibility monkey fuzzing, responsive layout sweeps, distribution coverage contracts, state machine testing, and widget property verification.

160/160 pub points MIT flutter_test Native
  • hegelFlutterMonkeyTest: Traverses active SemanticsOwner accessibility trees and fuzzes actions with automated minimal step shrinking.
  • hegelFlutterLayoutSweepTest: Sweeps viewports, dynamic font scaling (TextScaler), and RTL/LTR directions to detect and shrink RenderFlex overflowed bugs.
  • Coverage & Weighted Combinators: Direct access to tc.cover(), tc.classify(), and weighted generators inside all Flutter test suites.
  • hegelFlutterWidgetTest: Run property fuzzing directly inside testWidgets with automatic zone and widget lifecycle binding.
  • Persistent Database: Auto-derives databaseKey from widget test descriptions; instantly replays failing UI configurations on iteration 1.
// PARADIGM COMPARISON

Manual Example Testing vs Property Fuzzing

Why leading software systems rely on randomized property testing to unearth edge cases before deployment.

Dimension Traditional Example Tests LetsTestTools Property Testing
Input Diversity 3–5 manual values (e.g. 0, 1, "test") Thousands of mutated, coverage-guided inputs
Regression Feedback Copy/paste reproduction strings by hand Saved to .hegel/ and replayed on iteration 1
Debugging Burden Massive noisy inputs with hundreds of irrelevant fields Automated shrinking isolates the single minimal failure
Flutter Widgets Fixed golden snapshots & manual tap paths Semantics monkey fuzzing & responsive layout sweeps across hundreds of viewports, font scales, and RTL/LTR directions
Execution Speed Interpreted Dart assertions High-throughput Rust fuzzing engine with zero FFI overhead
// PRODUCTION CODE

Clean, Idiomatic APIs

No convoluted DSLs or complex boilerplate. Just clean Dart functions that integrate seamlessly with your existing test runners.

import 'package:test/test.dart';
import 'package:hegeltest/hegeltest.dart';

void main() {
  hegelTest('payment handles currency matrix & zero amounts', (tc) {
    // Weighted domain generator
    final currency = tc.draw(sampledWeighted([(80, 'USD'), (15, 'EUR'), (5, 'JPY')]));
    final amount = tc.draw(integers(min: 0, max: 500000), label: 'amount');

    // Classify distributions conditionally
    tc.classify(amount == 0, 'zero_amount');
    tc.classify(amount > 250000, 'large_amount');

    // Coverage Contract: assert zero-amount edge cases tested >= 10%
    tc.cover(10.0, amount == 0, 'zero_amount_coverage');

    final invoice = createInvoice(amount: amount, currency: currency);
    expect(invoice.total, equals(amount));
  });
}
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:hegeltest_flutter/hegeltest_flutter.dart';

void main() {
  hegelFlutterWidgetTest('card layout never overflows under dynamic padding', (tc, tester) async {
    final paddingHorizontal = tc.draw(integers(min: 0, max: 96)).toDouble();
    final paddingVertical = tc.draw(integers(min: 0, max: 48)).toDouble();
    final label = tc.draw(text(minSize: 1, maxSize: 80));

    await tester.pumpWidget(
      MaterialApp(
        home: Center(
          child: Padding(
            padding: EdgeInsets.symmetric(horizontal: paddingHorizontal, vertical: paddingVertical),
            child: Text(label),
          ),
        ),
      ),
    );

    // Verify widget rendered without throwing layout overflow assertions
    expect(find.byType(Text), findsOneWidget);
  });
}
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:hegeltest_flutter/hegeltest_flutter.dart';

void main() {
  // Traverses SemanticsOwner tree & fuzzes actions (taps, inputs, scrolls)
  hegelFlutterMonkeyTest(
    'fuzzes checkout workflow without unhandled exceptions',
    createWidget: (tc) => const CheckoutApp(),
    steps: 25,
    allowedActions: [
      SemanticsAction.tap,
      SemanticsAction.setText,
      SemanticsAction.scrollDown,
    ],
    invariant: (tc, tester) async {
      // Invariant checked after every fuzzed action sequence
      expect(find.byType(CheckoutApp), findsOneWidget);
    },
  );
  // On crash, Hegel's engine automatically shrinks down to minimal steps:
  // 1. tap on "Add Coupon" (id=14)
  // 2. setText on "Coupon Code" (id=18) with "DISCOUNT99"
  // 3. tap on "Apply" (id=19) => throws RangeError
}
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:hegeltest_flutter/hegeltest_flutter.dart';

void main() {
  // Sweeps screen sizes, TextScaler (font sizes), & RTL/LTR directions
  hegelFlutterLayoutSweepTest(
    'user profile card never overflows across screens and text scales',
    sweepConfig: const LayoutSweepConfig(
      minWidth: 320,
      maxWidth: 1024,
      minHeight: 480,
      maxHeight: 1200,
      minTextScale: 0.8,
      maxTextScale: 2.5,
    ),
    builder: (tc, sample) => const UserProfileCard(),
  );
  // Catches "A RenderFlex overflowed by X pixels" & shrinks viewport/scale:
  // Layout invariant violated:
  //   Configuration: LayoutSample(320.0x480.0, textScale: 2.10x, direction: rtl)
  //   Error: A RenderFlex overflowed by 14 pixels on the right.
}
import 'package:flutter_test/flutter_test.dart';
import 'package:hegeltest_flutter/hegeltest_flutter.dart';

class BoundedQueueMachine extends StateMachine {
  final queue = <int>[];

  @override
  List<StateRule> get rules => [
    StateRule('enqueue', execute: (tc) {
      final item = tc.draw(integers());
      queue.add(item);
    }),
    StateRule('dequeue', precondition: () => queue.isNotEmpty, execute: (tc) {
      queue.removeAt(0);
    }),
  ];

  @override
  List<StateInvariant> get invariants => [
    StateInvariant('queue size is non-negative', check: (tc) {
      expect(queue.length, greaterThanOrEqualTo(0));
    }),
  ];
}

void main() {
  hegelFlutterStatefulTest('queue satisfies invariants', () => BoundedQueueMachine());
}
# Instant regression replay across GitHub Actions CI
name: Test Suite
on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Cache Hegel Counterexamples
        uses: actions/cache@v4
        with:
          path: .hegel/
          key: hegel-${{ runner.os }}-${{ github.ref_name }}
          restore-keys: hegel-${{ runner.os }}-

      - run: flutter test # Replays failing counterexamples on iteration 1!
// FOUNDATIONAL DESIGN

Engineered from the Metal Up

How LetsTestTools harnesses native fuzzing without burdening developers with Rust build toolchains.

01

Dart Native Assets (Hook Engine)

Using Dart's modern hook/build.dart build hook, precompiled native libraries (libhegel_c) are automatically verified via SHA-256 sidecars and packaged into your test artifact. Contributors never need cargo or a C toolchain installed.

02

Zero-Allocation FFI Interop

Execution data, mutations, and seed buffers are passed across Dart FFI via high-speed native pointers with pinned memory. Generators achieve millions of draws per second with negligible garbage collection overhead.

03

Deterministic Replay Database

Every discovered counterexample is hashed and persisted to .hegel/examples/. An automated .gitignore prevents repository pollution. When your test runs again locally or in CI, Phase.reuse executes the failure immediately.

// TELEMETRY & BENCHMARKS

Torture-Tested Throughput

Property testing shouldn't stall your test suite. Built on a native Rust engine with zero-copy FFI, Hegel delivers orders of magnitude higher throughput than pure-Dart generators.

90M+ ops/s
PRNG Choice Throughput
Native choice byte streams driving property execution with zero garbage collection overhead.
250k+ iter/s
Property Loop Execution
Full end-to-end property iterations drawing 64-bit integer boundaries with identity assertions.
< 55 ms
Automated Shrinking
Deterministic byte-level binary shrinking reduces complex failures to minimal reproducing inputs.
0.28 ms
Regression DB Replay
3,400+ replays/sec from .hegel/ cache on iteration 1, catching regressions instantaneously.
REPRODUCE BENCHMARKS LOCALLY Zero-Dependency Runner
dart run benchmark/run_benchmarks.dart --format=markdown View Full Benchmark Report →