テストコードを書くことは品質の高いソフトウェアを作る上で必須のスキルです。バグの早期発見・リファクタリングの安心感・チーム開発での信頼性向上につながります。
テストの種類
| 種類 | 内容 | 粒度 |
|---|---|---|
| ユニットテスト | 関数・クラス単体のテスト | 小(最も細かい) |
| 統合テスト | 複数モジュールの連携テスト | 中 |
| E2Eテスト | ユーザー操作を模したブラウザテスト | 大(最も広い) |
Jestのセットアップ(Node.js)
# インストール
npm install --save-dev jest
# package.json
{
"scripts": {
"test": "jest",
"test:watch": "jest --watch"
}
}
Jestの基本的な書き方
// math.js
export function add(a, b) {
return a + b;
}
export function divide(a, b) {
if (b === 0) throw new Error('0で割ることはできません');
return a / b;
}
// math.test.js
import { add, divide } from './math';
describe('add関数', () => {
test('2つの数値を足す', () => {
expect(add(1, 2)).toBe(3);
expect(add(-1, 1)).toBe(0);
});
test('小数も計算できる', () => {
expect(add(0.1, 0.2)).toBeCloseTo(0.3);
});
});
describe('divide関数', () => {
test('割り算を計算する', () => {
expect(divide(10, 2)).toBe(5);
});
test('0で割るとエラーを投げる', () => {
expect(() => divide(10, 0)).toThrow('0で割ることはできません');
});
});
よく使うmatcher
expect(value).toBe(5); // 厳密な等値
expect(value).toEqual({a: 1}); // オブジェクトの深い比較
expect(value).toBeTruthy(); // truthy値
expect(value).toBeFalsy(); // falsy値
expect(value).toBeNull(); // null
expect(value).toBeUndefined(); // undefined
expect(arr).toHaveLength(3); // 配列の長さ
expect(str).toContain('hello'); // 文字列・配列に含まれるか
expect(fn).toThrow('error'); // エラーを投げるか
非同期テスト
// async/awaitを使った非同期テスト
test('非同期でユーザーを取得', async () => {
const user = await fetchUser(1);
expect(user.name).toBe('太郎');
});
// モック(外部APIの代替)
jest.mock('./api');
import { fetchUser } from './api';
test('モックを使ったテスト', async () => {
fetchUser.mockResolvedValue({ id: 1, name: '太郎' });
const user = await fetchUser(1);
expect(user.name).toBe('太郎');
expect(fetchUser).toHaveBeenCalledWith(1);
});
Vitest(Viteプロジェクト向け)
Viteを使うプロジェクトではVitestがJestより高速で推奨されます。APIはJestとほぼ同じなので移行も簡単です。
npm install --save-dev vitest
// vitest.config.ts
export default {
test: { globals: true }
}
まとめ
テストコードはdescribe→test→expectの構造で書きます。ユニットテストから始め、重要な関数・コンポーネントのテストを習慣化することで、リファクタリングの安心感が大幅に上がります。
📚 プログラミング初心者におすすめの本