소개
GitHub - bingual/sveltekit5: svelte5, 기타 라이브러리 테스트
svelte5, 기타 라이브러리 테스트. Contribute to bingual/sveltekit5 development by creating an account on GitHub.
github.com
해당 프로젝트는 최신 `Svelte 5`와 `SvelteKit`을 기반으로 구축된 프로젝트로, 클린 코드와 유지 보수를 중점적으로 고려한 웹 애플리케이션입니다.
성능 최적화, 재사용 가능한 컴포넌트 설계, 모듈화, 메모리 누수 관리, 중복 제거, 테스트 코드 작성을 목표로 하여 효율적인 개발 환경을 구성하는데 초점을 맞춘 기능 테스트가 목표입니다.
`Svelte 5` 는 2024년 10월 19일 정식으로 릴리즈 되었습니다.
한국에서는 `React`, `Vue`, `Next`와는 다르게 인지도가 낮지만 빠르고 편리하며 프레임워크 내에서 자체적으로 제공하는 기능이 많아 개발 경험이 좋기에 해외에서는 핫한 프레임워크 중 하나입니다.
현재 사용하는 `Svelte 5` 및 기타 라이브러리들은 베타 버전도 포함하고 있기에 버그가 있을 수 있습니다.
앞으로 연재될 Svelte 5 포스팅들은 단순히 기능을 구현하는 것만이 아니라 어떻게 해야 효율적으로 기능들을 구현하고 사용 및 관리하는지에 대해 설명을 진행할 예정입니다.
Sveltekit, Prisma, Tailwind, Auth 등등 해당 프로젝트에 사용되는 라이브러리에 대한 설명은 없으므로 공식문서를 참고 바랍니다.
프로젝트 구조
prisma/ # Prisma 관련 설정 및 파일 폴더
e2e/ # E2E 테스트 코드 폴더
src/ # 소스 코드 루트 폴더
├── lib/ # 재사용 가능한 라이브러리 코드 폴더
│ ├── auth.ts # Oauth 코드
│ ├── prisma.ts # Prisma 인스턴스 코드
│ ├── supabaseClient.ts # Supabase 관련 코드
│ ├── utils/ # 유틸리티 코드 폴더
│ └── components/ # Svelte 컴포넌트 폴더
├── routes/ # SvelteKit 라우팅 폴더
└── tests/ # 유닛 테스트 코드 폴더
명시되지 않은 코드 구조가 있을 수 있습니다.
내용 요약
설명은 간단하게 진행되니 자세한 설명은 참조하는 링크를 참고해 주세요.
- `vitest` 및 테스트 코드 설명
- `happy-dom`을 이용한 브라우저 `mock` 적용
- `clients` `servers` 테스트 코드 환경 분리
https://github.com/capricorn86/happy-dom
Vitest 설명
기존에는 Jest와 같은 테스팅 프레임 워크를 많이 사용했었습니다. 하지만 Vite가 번들러 중 가장 성능이 우수하고 개발자 경험이 좋기 때문에 Vitest라는 차세대 테스트 프레임워크를 사용함으로 좀 더 나은 테스트 환경과 생산성을 가져갈 수 있습니다.
`jest`는 각 빌드에 따라 맞는 설정을 해야 할 필요성도 있고 모킹과 스냅샷 기능을 사용하기 위해 별 다른 설정이 더 필요합니다. 하지만 `vite`를 번들러로 사용한다면 `vitest` 하나만으로 전부 해결할 수 있습니다.
예전 `ssr`과 다르게 매우 발달한 현재 `ssr` 기능을 테스트 하기에도 가장 적합하죠.
테스트 코드를 작성하는 이유는 무엇일까요?
기존에 완성해놓은 기능이 있다면 언젠가는 이 기능을 리팩터링을 하거나 업데이트를 해야 하는 경우가 생깁니다.
해당 기능에 대한 개발문서가 없다면 그 기능에 얽혀있는 수 많은 함수가 제대로 작동하는지 매번 직접 확인을 해보는 불필요한 디버깅을 위한 시간이 발생하게 됩니다. 개발 문서가 있더라도 여러 테스트케이스가 제대로 작동하는지 알기가 힘드며 그 함수의 기능을 파악하는 데에도 시간이 걸리고 기능이 변경되면 그에 맞춰 문서도 변경되어야만 하죠.
즉 온전히 개발하는것에 집중하기보다 완성된 기능을 유지보수 하는데에 더 시간이 많이 쓰이는 경우가 발생하게 됩니다.
하지만 해당 기능에 사용되는 함수들에 여러 테스트 케이스를 사전에 미리 작업을 해놓고 테스트 코드를 작성하게 된다면?
- 개별 함수나 모듈이 예상대로 동작하는지 검증하여 버그를 사전에 방지합니다.
- 기존 코드의 동작을 유지하면서 안전하게 수정 및 개선할 수 있습니다.
- 반복적인 수동 테스트를 줄이고, 자동화된 검증을 통해 개발 효율을 높입니다.
- 테스트 코드 자체가 기능을 설명하는 예제가 되어, 코드 이해도를 높입니다.
- 새로운 변경 사항이 기존 기능에 영향을 미치지 않도록 검증합니다.
- 배포 전 자동화된 테스트를 통해 예상치 못한 오류를 줄입니다.
유닛 테스트는 코드의 안정성, 유지보수성, 개발 생산성을 높이는 필수적인 도구입니다.
Vitest 사용 예제
`vite.config.ts`
export default defineConfig({
...
test: {
include: ['src/**/*.{test,spec}.{js,ts}'],
environment: 'happy-dom',
},
});
브라우저 환경을 모킹하기 위해 happy-dom 패키지를 설치해주고 환경설정을 해줍니다.
`src/tests/servers/`, `src/tests/clients/` 각각 서버, 클라이언트 환경을 분리해 줍니다.
[Svelte] 구독 기능을 이용한 토스트 메시지 구현 해당 파트에서 로컬 스토리지 매니저를 만들었습니다. 이 함수를 가지고 간단하게 어떻게 테스트 코드를 작성하는지 살펴볼까요?
`clients/variables.spec.ts`
import { localStorageManager } from '$lib/utils/variables';
import { beforeEach, describe, expect, it, vi } from 'vitest';
vi.mock('$app/environment', () => ({
browser: true,
}));
describe('localStorageManager (Browser 환경)', () => {
const mockKey = 'testKey';
const mockValue = { name: 'test', age: 30 };
beforeEach(() => {
localStorage.clear();
});
it('객체를 localStorage에 저장할 수 있어야 한다', () => {
const { saveToLocalStorage, loadFromLocalStorage } = localStorageManager();
saveToLocalStorage(mockKey, mockValue);
const storedValue = loadFromLocalStorage(mockKey);
expect(storedValue).toEqual(mockValue);
});
it('존재하지 않는 키에 대해 null을 반환해야 한다', () => {
const { loadFromLocalStorage } = localStorageManager();
const result = loadFromLocalStorage('nonExistentKey');
expect(result).toBeNull();
});
it('localStorage를 비울 수 있어야 한다', () => {
const { saveToLocalStorage, clearLocalStorage, loadFromLocalStorage } = localStorageManager();
saveToLocalStorage(mockKey, mockValue);
clearLocalStorage();
const result = loadFromLocalStorage(mockKey);
expect(result).toBeNull();
});
});
해당 함수가 제대로 작동하는지 확인하기 위해서는 브라우저 환경에서 실행하고 직접 로컬 스토리지에 값이 등록되어있는지 확인해야 하니 `browser`을 활성화합니다.
`servers/variables.spec.ts`
vi.mock('$app/environment', () => ({
browser: false,
}));
describe('localStorageManager (Non-Browser 환경)', () => {
const mockKey = 'testKey';
const mockValue = { name: 'test', age: 30 };
beforeEach(() => {
localStorage.clear();
});
it('브라우저 환경이 아니라면 undefined를 반환해야한다.', () => {
const { saveToLocalStorage, clearLocalStorage, loadFromLocalStorage } = localStorageManager();
saveToLocalStorage(mockKey, mockValue);
clearLocalStorage();
const result = loadFromLocalStorage(mockKey);
expect(result).toBeUndefined();
});
});
만약 Non-Broswer 환경이라면 따로 모킹을 해주면 됩니다.
`describe`: 테스트 그룹
`it`: 단위 테스트 블록
`expect`: 검증 함수
메서드 사용법은 링크를 참조하세요.
테스트를 위한 그룹을 만들고 해당 그룹에서 `it`과 `expect`를 이용한 테스트 케이스를 여러 개 만들고 검증합니다.
테스트 코드는 너무 복잡하게 작성하는 것이 아니라 가독성에 포인트를 맞추고 작업을 해야 읽기도 쉽고 검증하기에도 편합니다.
마무리
이렇게 각 단위의 테스트 케이스별, 그룹별, 파일별, 감시 기능을 통해서 테스트해볼 수가 있습니다.
`감시` 기능은 핫리로드와 동일한 기능을 합니다.
'프로젝트 > Fullstack' 카테고리의 다른 글
[Svelte] 효율적인 데이터 생성/제거 테스트 방법 (1) | 2024.12.25 |
---|---|
[Svelte] 효율적인 메모리 관리방법 (0) | 2024.11.29 |
[Svelte] 효율적인 컴포넌트 관리법 (0) | 2024.11.28 |
[Svelte] 전역에서 사용 가능한 모달 모듈 구현 (0) | 2024.11.27 |
[Svelte] 구독 기능을 이용한 토스트 메시지 구현 (0) | 2024.11.26 |