測試

使用 @textjs/app/testing 在畫面外渲染應用程式、按下按鍵並斷言影格。

@textjs/app/testing(或 @textjs/react/testing)會在畫面外渲染你的應用程式、按下按鍵,並以文字回傳影格。測試執行時不需要瀏覽器或 DevTools。

counter.test.tsxtsx
import { afterEach, expect, test } from "bun:test";import { cleanup, render } from "@textjs/app/testing";import { Counter } from "./counter";afterEach(cleanup);test("counts up", async () => {  const app = await render(<Counter />, { cols: 40, rows: 6 });  await app.press("up up");  expect(app.lastFrame()).toContain("count = 2");});

任何支援 async 測試的測試執行器都能使用,包括 Bun、Vitest 和 Jest。

渲染

方法說明
render(el, { cols, rows, theme })在畫面外掛載(預設 80×24)
lastFrame()純文字形式的影格
lines()以各列組成陣列的影格
frames目前為止所有不同的影格
toAnsi()用於快照的全彩 ANSI
cell(x, y){ char, fg, bg, attrs }
locate(text)第一個符合項目的 { x, y }
rerender(el) / unmount()更新或卸載

renderToString(el, options) 渲染一次並回傳文字。

輸入

await app.press("down");await app.press("ctrl+k");      // modifiersawait app.press("g g");         // a sequenceawait app.press("G");           // Shift+Gawait app.type("hello\n");      // one key per character, \n is Enterawait app.paste("multi\nline");await app.wheel(3);await app.resize(120, 36);

每次呼叫都在 act() 內執行,並完成產生的影格輸出,因此下一個斷言能取得更新結果。

時間

await app.wait(300);                    // real time passes, then frames flushawait app.waitForText("Deployed");      // poll until the frame contains itawait app.waitFor(() => expect(saved).toBe(true), { timeout: 2000 });

動畫、載入指示器和短暫通知使用真實計時器,因此使用 wait 和 waitFor 才能可靠地觀察這些效果。

快照

expect(app.lastFrame()).toMatchSnapshot();expect(app.toAnsi()).toMatchSnapshot(); // colors too

影格會裁去右側和底部的空白,因此快照不會因空白而反覆變動。

在 GitHub 編輯此頁