TestSprite — 현지화된 개발 검토 및 피드백
Source: Dev.to
프로젝트 배경
국내·해외 사용자를 대상으로 하는 관리 백오피스(React + Node.js)로, 주문 금액, 기간 범위 필터, 다국어 전환, CSV 내보내기 등의 기능을 포함하고 있습니다. 기존에 국제화 테스트를 할 때는 언어를 수동으로 전환하고, 시스템 타임존을 바꾸고, 입력기를 이용해 직접 입력해 보는 식으로 진행했으며, 효율이 낮고 놓치는 부분이 많았습니다. TestSprite는 “실행 가능한 Dev Review”에 더 가깝습니다. 실제 프로젝트에서 자동화 테스트를 한 번 실행한 뒤, 개발 관점에서 실현 가능한 피드백을 제공해 주며, 특히 기능 회귀와 현지화 세부 사항을 동시에 신경 써야 하는 팀에 적합합니다.
접속 단계
- 테스트 환경에 staging 데이터 세트(다중 통화 주문, 다양한 언어 사용자 포함)를 준비합니다.
- 테스트 진입 URL과 로그인 방식(테스트 계정)을 설정합니다.
- 커버할 핵심 경로를 지정합니다: 로그인 → 주문 목록 → 주문 상세 → 내보내기 → 언어 전환 → 개인 설정.
- 테스트 중
locale과timezoneId를 명시적으로 설정하고, UI 문구와 숫자 포맷에 대한 어서션을 수행합니다(모든 팀이 최소한으로 해야 할 집합을 권장).
코드 예시
import { test, expect } from '@playwright/test';
test.use({
locale: 'zh-CN',
timezoneId: 'Asia/Shanghai',
});
test('주문 금액과 날짜가 zh-CN에서 올바르게 표시되는지 확인', async ({ page }) => {
await page.goto(process.env.STAGING_URL!);
await page.getByLabel('邮箱').fill('test@demo.com');
await page.getByLabel('密码').fill('123456');
await page.getByRole('button', { name: '登录' }).click();
await page.getByRole('link', { name: '订单' }).click();
// 금액: zh-CN에서는 일반적으로 1,234.56 또는 ¥1,234.56(제품 정의에 따라) 형태를 기대합니다.
const priceText = await page.locator('[data-testid="order-price"]').first().innerText();
expect(priceText).toMatch(/(¥|¥)?\s?\d{1,3}(,\d{3})*(\.\d{2})?/);
// 날짜: 현지화된 포맷 또는 명시적인 yyyy-MM-dd 형식이 포함되는지 확인합니다.
const dateText = await page.locator('[data-testid="order-createdAt"]').first().innerText();
expect(dateText).toMatch(/\d{4}[-/]\d{1,2}[-/]\d{1,2}/);
});
실행 결과 스크린샷
실제 스크린샷으로 교체 후 게시
![]()
스크린샷 내용에 포함될 권장 항목: 프로젝트 URL(가리기 가능), 테스트 케이스 목록, 실행 결과(pass/fail), 최소 한 개의 현지화 관련 알림.
발견된 문제와 수정 제안
시간 표시 불일치
- 문제: 리스트 페이지는
new Date(iso).toLocaleString()(브라우저 타임존)을 사용하고, 상세 페이지는 백엔드에서 렌더링된 UTC 문자열을 사용해Asia/Shanghai에서는 +8시간 오차가 발생합니다. 특히 날짜가 넘어갈 때 문제가 크게 드러납니다. - 수정 제안:
- 프론트엔드에서 UTC + 타임존 라이브러리(
date-fns-tz또는luxon)를 사용해 일관되게 포맷합니다. - 혹은 백엔드에서 ISO 8601 형식만 반환하고, 프론트엔드에서 일관된 포맷으로 표시합니다.
- UI에 타임존을 명시(예: “GMT+8”)하면 다국가 환경에서 매우 중요합니다.
- 프론트엔드에서 UTC + 타임존 라이브러리(
금액 포맷 불안정
- 문제:
en-US환경에서 가끔1234,5와 같이 소수점이 불안정하게 표시됩니다. 이는 직접 구현한Number(value).toFixed(2).replace('.', ',')로직 때문입니다. - 수정 제안:
Intl.NumberFormat을 사용합니다:
export function formatCurrency(
value: number,
locale: string,
currency: string
) {
return new Intl.NumberFormat(locale, {
style: 'currency',
currency,
maximumFractionDigits: 2,
}).format(value);
}
// zh-CN + CNY => ¥1,234.56
// de-DE + EUR => 1.234,56 €
비 ASCII 입력으로 인한 백엔드 오류
- 문제: UI에서는 중국어·아랍어 입력이 가능하지만, 요청 파라미터가 백엔드에서 잘못 encode/decode 되어 검색 결과가 비어 있습니다.
- 수정 제안: 백엔드에서 모든 문자에 대해 UTF-8 인코딩/디코딩을 일관되게 적용합니다.
번역 누락
- 문제: 언어를
ja-JP로 전환했을 때, “Export CSV”와 같은 버튼이 여전히 번역되지 않은 상태입니다. - 수정 제안: TestSprite의 “번역 누락 스캔” 기능을 활용해 i18n에 포함되지 않은 노드를 한눈에 모아 확인하고, 하나씩 수정합니다.
적용 가능한 시나리오
- 이미 staging 환경이 구축돼 있고, 자동화 수단으로 한 번 “개발자 중심 리뷰”를 진행하고 싶을 때.
- 제품이 다수 지역 사용자를 대상으로 하며, 시간·통화·숫자·입력기 문제를 자주 겪는 경우.
- 팀이 현지화 검사를 “배포 전 급하게 하는” 방식에서 “지속적으로 발견하는” 방식으로 전환하고자 할 때.
향후 계획
TestSprite를 배포 전 체크리스트에 포함시킵니다: 매 배포 전 핵심 경로를 한 번 실행하고, zh-CN, en-US, de-DE 세 가지 locale과 다양한 타임존을 고정적으로 커버해 “보이는 건 문제 없고, 지역만 바꾸면 바로 붕괴”하는 숨은 버그를 조기에 발견합니다.