Adding a Vitest test system to the Autowini WEB integration project
web-www-front is an integration project created at Autowini to separate the existing JSP-based legacy pages into React and improve them.
These are the main pages separated so far:
- Filter search page
- Unified search page
- Wishlist page (MyWini)
- Shipping information page
- PartWini unified search page
- PartWini filter search page
While working on this project, I kept asking myself, “Do we need to introduce test code?”
🤔 Is test code really necessary?
In recent job postings from many companies, you often see phrases like "experience writing test code" or "TDD experience preferred."
I have also contributed test code and benchmark code to libraries from Korean fintech companies, Toss's es-toolkit and NaverPay's hidash, but I had not brought tests into our in-house projects.
The reason was that I had thoughts like, "There isn't even enough time to build and maintain features, and now I'm supposed to write test code too?" and "Can't I just build it perfectly without writing tests?"
Recently, though, I had some time left over during QA after migrating the PartWini filter search page, so I decided to try adding test code to a real project.
Along the way, there were a few things I had to think through.
💡 1. Which test framework should I use?
The first thing I thought about was choosing a test tool. I weighed Jest against Vitest, and chose Vitest because I was more familiar with it from earlier open source contributions and, above all, because of its excellent compatibility with Vite environments.
📁 2. Where should the test files go?
I had to decide whether to put test files next to each file or manage them all together in a separate tests folder.
The current project structure looks like this:
src/
┣ domains/
┃ ┣ PartFilterSearch/
┃ ┃ ┣ api/
┃ ┃ ┣ components/
┃ ┃ ┣ utils/With this structure, I decided it was efficient to create a __tests__ directory inside each domain's subfolders.
This approach has these advantages:
- Related code and tests live together, which improves readability during maintenance
- Import paths are short and the structure is simple
- When a domain is deleted, its tests can be cleaned up with it
📂 In other words, I wanted to keep “a test structure that carries over the strengths of the project structure.”
🧪 3. Do I need to test every edge case?
What I thought about most while writing tests was "How far should I test?"
For example, here is a global utility function:
/**
* @description Returns numeric price data as a string with thousands separators (,)
* @param price numeric price data
* @returns {string} price string with thousands separators (,)
*/
export const formatPrice = (price: number | null): string => {
if (price === null) return '*,***';
return price.toLocaleString();
};This function formats the price value received from the API. Values like Infinity, -Infinity, and NaN have no chance of coming from the API, so I did not include them in the test cases. I thought verifying even absurd values could lower test efficiency, and that unnecessary tests actually make things look cluttered.
⚙️ An example of the test code I wrote
Below is part of the test code I wrote for existing global utility functions.
import { describe, expect, test } from 'vitest';
import { formatPrice, formatUpperToFirstLetter } from '../formatUtils';
describe('formatPrice', () => {
test('숫자를 천 단위로 콤마(,)를 포함한 문자열로 반환한다', () => {
expect(formatPrice(0)).toBe('0');
expect(formatPrice(1234)).toBe('1,234');
expect(formatPrice(1234567)).toBe('1,234,567');
});
test('값이 null일 경우 *,*** 문자열을 반환한다', () => {
expect(formatPrice(null)).toBe('*,***');
});It is short and simple, but while writing the tests I found a few interesting things.
For example, the function used to return '*,***' with a !price check, which meant there was an edge case where it also returned the wrong result when price was 0.
Writing tests let me find logic gaps like this, and I really felt that test code is not just a verification tool but a tool for improving code quality. Along the way, I also made side improvements to the function, such as adding JsDoc comments, specifying a clear return type, and fixing the condition.

🔍 Closing thoughts
What I took away from this is that test code is not a “waste of time” but a reliable safety net that makes development more efficient.
Of course, I don't think every function or component needs tests. But I came to think that parts likely to be refactored or with complex logic should have tests.
Also, writing test code efficiently naturally leads you to follow the Single Responsibility Principle (SRP), which I think in turn leads to code that is easy to test and easy to maintain.
I plan to keep writing test cases and to work toward code that is prepared in advance for exceptions that can occur in production.
- #Autowini
- #Vitest
- #testing
- #test code
- #frontend
- #frontend developer Sungjun Um