Тест бичих (Jest + RNTL)
"Энэ код ажиллаж байна" гэдгийг хэрхэн баталгаажуулах вэ? Гараар туршихад цаг их зарцуулдаг, өөрчлөлт хийх бүрт дахин дахин шалгах хэрэгтэй болдог. Автоматжуулсан тест нь кодыг тань хурдан, найдвартай шалгадаг — нэг удаа бичихэд тань байнга ажиллаж байдаг. Эхлэгчдэд хэцүү санагдаж болох ч үндсэн тестийг бичиж сурахад маш хурдан болно.
Jest тохируулга
Expo апп үүсгэхэд Jest автоматаар суулгагддаг. @testing-library/react-native нэмэн суулгана:
npx expo install jest-expo @testing-library/react-native @testing-library/jest-native
package.json-д Jest тохируулга нэмнэ:
{
"scripts": {
"test": "jest",
"test:watch": "jest --watch"
},
"jest": {
"preset": "jest-expo",
"setupFilesAfterFramework": ["@testing-library/jest-native/extend-expect"],
"transformIgnorePatterns": [
"node_modules/(?!((jest-)?react-native|@react-native(-community)?)|expo(nent)?|@expo(nent)?/.*|@expo-google-fonts/.*|react-navigation|@react-navigation/.*|@unimodules/.*|unimodules|sentry-expo|native-base|react-native-svg)"
]
}
}
Эхний тест — component шалгах
__tests__ хавтас үүсгэж тест файлуудаа тэнд хадгална. Нэрлэх дүрэм: ComponentName.test.tsx:
// __tests__/AppButton.test.tsx
import React from 'react';
import { render, fireEvent, screen } from '@testing-library/react-native';
import { AppButton } from '../components/AppButton';
describe('AppButton', () => {
it('label зөв харуулна', () => {
render(<AppButton label="Нэвтрэх" onPress={() => {}} />);
// Текст дэлгэцэнд байгаа эсэхийг шалгана
expect(screen.getByText('Нэвтрэх')).toBeTruthy();
});
it('дарахад onPress дуудагдана', () => {
// jest.fn() нь функц дуудагдсан эсэхийг хянах "spy"
const mockPress = jest.fn();
render(<AppButton label="Дарах" onPress={mockPress} />);
fireEvent.press(screen.getByText('Дарах'));
expect(mockPress).toHaveBeenCalledTimes(1);
});
it('disabled үед дарахад onPress дуудагдахгүй', () => {
const mockPress = jest.fn();
render(<AppButton label="Идэвхгүй" onPress={mockPress} disabled />);
fireEvent.press(screen.getByText('Идэвхгүй'));
expect(mockPress).not.toHaveBeenCalled();
});
});
Terminal дээр npx jest ажиллуулахад тест гүйж үр дүн гарна:
✓ AppButton › label зөв харуулна (23ms)
✓ AppButton › дарахад onPress дуудагдана (8ms)
✓ AppButton › disabled үед дарахад onPress дуудагдахгүй (5ms)
Tests: 3 passed, 3 total
Hook тестлэх
Custom hook-ийг тестлэхэд renderHook ашиглана:
// __tests__/useCounter.test.ts
import { renderHook, act } from "@testing-library/react-native";
// Тестлэх hook
function useCounter(initial = 0) {
const [count, setCount] = React.useState(initial);
const increment = () => setCount((c) => c + 1);
const decrement = () => setCount((c) => c - 1);
const reset = () => setCount(initial);
return { count, increment, decrement, reset };
}
describe("useCounter", () => {
it("эхний утга зөв байна", () => {
const { result } = renderHook(() => useCounter(5));
expect(result.current.count).toBe(5);
});
it("increment ажиллана", () => {
const { result } = renderHook(() => useCounter());
act(() => {
result.current.increment();
});
expect(result.current.count).toBe(1);
});
it("reset анхны утгад буцна", () => {
const { result } = renderHook(() => useCounter(10));
act(() => {
result.current.increment();
result.current.increment();
result.current.reset();
});
expect(result.current.count).toBe(10);
});
});
Async тест — fetch шалгах
API дуудлагатай код тестлэхэд mock ашиглана. Жинхэнэ сервер рүү хандахгүйгээр тестийг гүйцэтгэнэ:
// __tests__/LessonList.test.tsx
import React from 'react';
import { render, screen, waitFor } from '@testing-library/react-native';
import { LessonList } from '../components/LessonList';
// fetch-г mock болгоно — жинхэнэ сервер хэрэггүй
global.fetch = jest.fn();
const mockLessons = [
{ id: '1', title: 'React Native гэж юу вэ?', order: 1 },
{ id: '2', title: 'Node.js суулгах', order: 2 },
];
beforeEach(() => {
(fetch as jest.Mock).mockResolvedValue({
ok: true,
json: async () => mockLessons,
});
});
afterEach(() => {
jest.clearAllMocks();
});
describe('LessonList', () => {
it('ачаалж байхад loading харуулна', () => {
render(<LessonList courseSlug="react-native" />);
expect(screen.getByText('Ачааллаж байна...')).toBeTruthy();
});
it('хичээлүүдийг зөв харуулна', async () => {
render(<LessonList courseSlug="react-native" />);
// Async дуусахыг хүлээнэ
await waitFor(() => {
expect(screen.getByText('React Native гэж юу вэ?')).toBeTruthy();
expect(screen.getByText('Node.js суулгах')).toBeTruthy();
});
});
it('алдаа гарахад error харуулна', async () => {
(fetch as jest.Mock).mockRejectedValue(new Error('Сүлжээний алдаа'));
render(<LessonList courseSlug="react-native" />);
await waitFor(() => {
expect(screen.getByText('Сүлжээний алдаа')).toBeTruthy();
});
});
});
Тест бичих нь нэмэлт ажил мэт санагдаж болох ч ашиглах тусам "яагаад эрт сураагүй юм бэ" гэж бодох болно. Өчүүхэн тестүүдийг байнга бичих дадал болгоорой — том апп бүтээхдээ маш их тустай.
Дараагийн хичээлд:
EAS Build тохируулга — Expo Application Services ашиглан аппаа жинхэнэ .apk болон .ipa файл болгон build хийх, App Store / Play Store-д нийтлэхэд бэлдэх талаар сурна.