-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Proposal: Testing framework for Bubble Tea applications (charm-test) #1654
Copy link
Copy link
Open
Description
Problem
There is no standard way to test Bubble Tea applications. Developers either:
- Test manually (slow, not CI-friendly)
- Call
Update()manually and inspect model internals (brittle, verbose) - Skip testing TUI logic entirely
Other UI frameworks have dedicated testing tools (React Testing Library, Flutter widget tests), but Bubble Tea has none.
Proposed Solution
charm-test — a testing framework that simulates the Bubble Tea runtime without a real terminal.
func TestLoginForm(t *testing.T) {
sim := charmtest.New(NewLoginModel())
sim.Type("user@email.com")
sim.SendKey("tab")
sim.Type("password123")
sim.SendKey("enter")
charmtest.RequireViewContains(t, sim, "Welcome")
charmtest.RequireSnapshot(t, sim) // golden file comparison
}Features
- Simulator — drives Model synchronously through Init/Update/View (no goroutines, deterministic)
- Input simulation —
SendKey("enter"),Type("hello"),Resize(80, 24) - Assertions —
RequireView(),RequireViewContains(),RequireViewLines()with automatic ANSI stripping - Snapshot testing — golden file comparison with
CHARM_TEST_UPDATE=1to refresh - Debugging —
DumpView(),DumpMessages()for test failure diagnosis
Design Principles
- Deterministic: same input → same output, always
- Fast: microseconds per test, not seconds
- Simple: one import, one constructor
- ANSI-aware: all comparisons strip escape sequences
Working POC
https://github.com/junhinhow/charm-test
Includes a complete counter example with 5 test cases. Bilingual docs (EN/PT-BR).
Questions
- Would this fit as an official package (e.g.
charm.land/bubbletea/v2/test)? - Or better as a standalone community package?
- Should the Simulator also handle async commands (timers, HTTP) via a mock clock?
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels