In my CLI tool, Repo-snapshot which is built using TypeScript and Vite, I decided to implement unit tests to ensure my functions work correctly and handle edge cases. For testing, I chose Vitest along with @vitest/coverage-v8.
Why I Chose These Tools
Vitest: Vitest is a modern unit testing framework specifically designed for Vite projects. It integrates seamlessly with TypeScript, is fast, and supports features like mocking, snapshots, and coverage.
@vitest/coverage-v8: This plugin provides detailed code coverage reporting using V8’s built-in coverage tool. It helped me identify which parts of my code were fully tested and which were not.
I chose these tools because they fit perfectly with the TypeScript + Vite environment of my CLI tool and allowed me to write tests efficiently without extra configuration overhead.
Setting Up Vitest in My Project
Here’s how I set up Vitest and coverage in my project:
- Install dependencies:
pnpm add -D vitest @vitest/coverage-v8
-
Configure Vitest:
I created a
vitest.config.tsfile in my project root:
import { defineConfig } from "vitest/config";
export default defineConfig({
test: {
coverage: {
enabled: true,
provider: "v8",
include: ["src/**/*.ts"],
exclude: ["tests/**", "node_modules/**"],
},
},
});
-
Update TypeScript config:
I modified
tsconfig.jsonto include test files and support ES modules for tests:
{
// Visit https://aka.ms/tsconfig to read more about this file
"compilerOptions": {
// File Layout
"rootDir": "./",
"outDir": "./dist",
// Environment Settings
// See also https://aka.ms/tsconfig/module
"module": "nodenext",
"target": "ES2020",
// For nodejs:
"types": ["node", "vitest", "vitest/globals"],
// Other Outputs
"sourceMap": true,
"declaration": true,
"declarationMap": true,
// Stricter Typechecking Options
"noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": true,
// Recommended Options
"esModuleInterop": true,
"strict": true,
"jsx": "react-jsx",
"verbatimModuleSyntax": false,
"isolatedModules": true,
"noUncheckedSideEffectImports": true,
"moduleDetection": "force",
"skipLibCheck": true,
},
"include": ["src", "tests"],
// Ignore tests and node_modules
"exclude": ["node_modules", "dist"]
}
-
Add test scripts in
package.json:
{
"scripts": {
"test": "vitest run",
"test:watch": "vitest --watch",
"coverage": "vitest run --coverage"
}
}
After this setup, I could run all tests with:
pnpm test
Or test a specific file:
pnpm test tests/file-utils.test.ts
Writing test cases for my CLI tool was a learning experience. Some functions were straightforward, but others had tricky edge cases. For example, one function that parsed repository paths could fail if a user entered an unexpected format. I had to think carefully about input validation, which was an “aha!” moment—writing tests made me anticipate situations I hadn’t considered.
There were times I got stuck on mocking parts of the CLI output. Stepping away and revisiting the problem later helped me find simpler, cleaner solutions. This taught me that unit testing isn’t just about catching bugs—it also improves your design and code clarity.
During testing, I uncovered a few interesting scenarios:
- Projects containing a TOML config file required careful handling in tests to avoid errors.
- Edge cases for file paths on different operating systems required me to handle both forward slashes (
/) and backward slashes (\).
These discoveries proved the value of testing even small utility functions—tests caught potential runtime errors before users did.
Before this project, I had very little hands-on experience with unit testing. Through this process, I learned:
- Unit testing helps catch bugs early and improves the reliability of your code.
- Even small functions deserve tests to handle unexpected input or edge cases.
- Testing encourages better design and foresight in programming.
Going forward, I plan to write unit tests for almost every function or class I contribute to, as it saves time and effort in the long run and makes projects more robust.
Conclusion:
This experience with Vitest showed me that testing is not just an optional step—it is an essential part of software development. I now feel much more confident incorporating tests into my future projects, and I understand how they can prevent subtle bugs and improve overall code quality.
Top comments (0)