Testing
Run oscli flows in Vitest without touching stdin or process.exit.
cli.test() gives you a programmatic harness for the real CLI. It runs the
same code paths, but replaces stdin, stdout, stderr, and process exit behavior
so your tests stay deterministic.
Vitest example
import { describe, expect, it } from "vitest";
import { createCLI } from "@oscli-dev/oscli";
describe("init flow", () => {
it("stores the provided project name", async () => {
const cli = createCLI((b) => ({
description: "test",
prompts: {
name: b.text().label("Name"),
},
}));
cli.command("init", async () => {
await cli.prompt.name();
cli.success(`Created ${cli.storage.name}`);
});
const result = await cli.test({
argv: ["init"],
inputs: { name: "my-app" },
});
expect(result.storage.name).toBe("my-app");
expect(result.output).toContain("Created my-app");
expect(result.exitCode).toBe(0);
});
});TestOptions
Prop
Type
TestResult
Prop
Type
Test flow
Use this order when writing tests around a CLI.
Create the CLI in the test
Build the same CLI object you use in production code.
Run cli.test()
Pass inputs, flags, and argv to
drive the flow.
Assert on the result
Check storage, flags, output, and
exitCode directly.
Test mode always behaves like non-TTY output. Prompt summary lines are still written to the captured buffer so you can assert on them.