Test-Driven Development in React Native - Part 3

ရှေ့အပိုင်းမှာ လိုအပ်တာတွေ ပြင်ဆင်ပြီး project မှာ test အတွက် ဘယ်လိုတွေပါလဲ သိပြီဆိုတော့ ကျွန်တော်တို့ ကိုယ်တိုင် test တွေရေးဖို့ စလိုက်ကြရအောင်ပါ။

test တွေမရေးခင် ကျွန်တော်တို့ရဲ့ App.tsx နဲ့ original __ test__ folder ကို src ဆိုတဲ့ folder ထဲကို အရင်ရွှေ့လိုက်ပါမယ်။ အပြင်မှာ အရင်ကအတိုင်း ထားလဲ ရပါတယ်။ ဒါပေမယ့် app နဲ့ ပတ်သက်တဲ့ implementation file တွေ အားလုံးကို src လို folder ထဲ ရွှေ့ထားတာ convention လိုမျိုး ဖြစ်တဲ့အတွက် ကျွန်တော်တို့ ရွှေ့ထားပါမယ်။ လိုအပ်တဲ့အခါ file တွေကို ရှာရလဲ လွယ်သွားပါလိမ့်မယ်။

အရင်ဦးဆုံး test နဲ့ ပတ်သက်တာတွေကို folder structure ဘယ်လိုလုပ်သွားမလဲ ပြောပါမယ်။ ကျွန်တော်တို့ test တွေရေးမယ့် screen တွေ၊ component တွေ၊ service တွေနဲ့ folder အတူတူအောက်မှာ __test__ ဆိုတဲ့ folder ဆောက်ပြီး အဲ့ထဲမှာ ကျွန်တော်တို့ test ရေးမယ့် file name အတိုင်းကိုပဲ .test ဆိုတာကို ထည့်ပြီးရေးပါမယ်။ အပေါ်မှာကြည့်မယ်ဆို App.tsx ကို test လုပ်မှာအတွက် App.test.tsx ဆိုတာကို __test__ folder ထဲမှာ create လုပ်ပါတယ်။

အပိုင်း ၁မှာတုန်းက ပြောခဲ့တဲ့ testing အတွက် ကျွန်တော်တို့ အသုံးပြုမယ့် library ၂ခုဖြစ်တဲ့ jest နဲ့ react native testing library တွေမှာ jest က default project မှာထဲက ပါပြီးသား ဖြစ်နေပါလိမ့်မယ်။ ဒီတော့ ကျွန်တော်တို့ testing library ကို သွင်းဖို့လိုပါလိမ့်မယ်။

Introduction | Testing Library
React Native Testing Library is a testing library for React Native inspired

ဒီ testing library က react native တခုထဲမဟုတ်ဘဲ တခြား framework တွေကိုပါ support ပေးတာဖြစ်တဲ့အတွက် သူနဲ့ သက်ဆိုင်ရာ menu အောက်ထဲမှာ ဝင်ရောက်ကြည့်နိုင်ပါတယ်။ ကျွန်တော်တို့ကတော့ react native အတွက် အသုံးပြုမှာ ဖြစ်တဲ့အတွက် @testing-library/react-native ဆိုတာကို install လုပ်ပါမယ်။

yarn add --dev @testing-library/react-native

ဒါပြီးရင်တော့ ကျွန်တော်တို့တွေ test တွေစပြီး ရေးလို့ရပါပြီ။

Check the initial project

test တွေမရေးခင် ကျွန်တော်တို့ app အလုပ်မလုပ် build လုပ်ပြီး စမ်းကြည့်ပါဦးမယ်။ ios simulator မှာ စမ်းမယ်ဆို yarn ios ဆိုပြီး run လိုက်လို့ရပါတယ်။ android မှာ ဆိုရင်တော့ yarn android ဆိုပြီး run လို့ရပါတယ်။

yarn ios
initial app screen on ios
yarn android
initial app screen on android

Updating App.tsx

App.tsx မှာပါတဲ့ code တွေက အပေါ်မှာ screen မှာ မြင်နေရတဲ့ အတိုင်းကို ရေးထားတာတွေပါ။ ဒါတွေကို ကျွန်တော်တို့ မလိုတဲ့အတွက် screen အတွက် လိုမယ့် basic view နဲ့ အရင် update လုပ်လိုက်ပါမယ်။ test driven သွားမှာဖြစ်တဲ့အတွက် တခြား implementation တွေ မဖြည့်သေးပါဘူး။

import React from 'react';
import {View} from 'react-native';

const App = () => {
  return <View />;
};

export default App;

src/App.tsx

ဒါပြီးရင်တော့ App.test.tsx ကိုလဲ အခုလိုမျိုး ပြင်လိုက်ပါမယ်။

import React from 'react';
import {describe, test} from '@jest/globals';
import {render} from '@testing-library/react-native';
import App from '../App';

describe('App', () => {
  test('should render correctly', () => {
    const screen = render(<App />);
    screen.getByTestId('app');
  });
});

src/__test__/App.test.tsx

အခုလိုပြင်ပြီးတဲ့အချိန် npm run test ဆိုပြီး run ကြည့်လိုက်မယ်ဆို result ကို အောက်မှာပြထားသလို တွေ့ရမှာ ဖြစ်ပါတယ်။

Test-driven development ကို ကျွန်တော်တို့ လေ့လာမှာဖြစ်တဲ့အတွက် TDD ရဲ့ အစဖြစ်တဲ့ test ရေးပြီးတော့ run လိုက်တဲ့အခါ test တွေ fail တာကနေ အစပြုသွားမှာပဲ ဖြစ်ပါတယ်။ ဒီတော့ အပေါ်မှာ မြင်ရတာမျိုးကို ကျွန်တော်တို့တွေ ခဏခဏ မြင်သွားရမှာပါ။ အောက်မှာပြထားတဲ့ flow လေးကို ပြန်မြင်ကြည့်လို့ရပါတယ်။

ကျွန်တော်တို့ App.tsx အတွက် အပေါ်မှာ ရေးထားတဲ့ test က test id သတ်မှတ်ထားဖို့ လိုတာကို စစ်ထားတာပဲ ဖြစ်ပါတယ်။ ဒီ App.tsx ထဲမှာ ကျွန်တော်တို့တွေ navigation နဲ့ပတ်သက်တာတွေကို နောက်ပိုင်းကျ ရေးသွားမှာပဲ ဖြစ်ပါတယ်။ အခုတော့ test id ထည့်လိုက်ခြင်းအားဖြင့် test pass သွားပါလိမ့်မယ်။

import React from 'react';
import {View} from 'react-native';

const App = () => {
  return <View testID="app" />;
};

export default App;

App.tsx

Home Screen

ပြီးရင်တော့ ကျွန်တော်တို့တွေ src folder ထဲမှာ screens ဆိုတဲ့ folder တခုကို တည်ဆောက်ပါမယ်။ ဒါကတော့ app ထဲမှာ ပါမယ့် screen တွေကို တစုတစည်းထဲ ထားဖို့ပဲ ဖြစ်ပါတယ်။ Screen ထဲမှာ component တွေ ပါဝင်မှာ ဖြစ်ပါတယ်။​ အောက်မှာပြထားတာလေးနဲ့ မြင်ကြည့်လို့ရပါတယ်။ screen ထဲမှာပဲ အကုန်ပစ်ထည့်လို့ရပေမယ့် test တွေ ရေးရတာ လွယ်အောင်နဲ့ ပြန်သုံးဖို့ ရှိလာတဲ့အခါ လွယ်ကူအောင် component တွေ ခွဲထုတ်ပြီး ရေးလေ့ရှိကြတာပဲ ဖြစ်ပါတယ်။

screens ဆိုတဲ့ folder ထဲမှာ ကျွန်တော်တို့ HomeScreen.tsx ဆိုတဲ့ file တခု တည်ဆောက်ပါမယ်။ သူနဲ့အတူပဲ __test__ ဆိုတဲ့ folder ကိုပါ တည်ဆောက်ပြီး သူ့ထဲမှာ HomeScreen.test.tsx ဆိုပြီး create လုပ်ပါမယ်။

အပေါ်မှာ create လုပ်ထားတဲ့ file ၂ခုထဲကမှ HomeScreen.tsx ကို အခုလိုပဲ update အရင်လုပ်ပါမယ်။ ကြည့်ကြည့်မယ်ဆို ကျွန်တော်တို့ App.tsx မှာ စရေးတာနဲ့ ဆင်တူပါတယ်။

import React from 'react';
import {View} from 'react-native';

const HomeScreen = () => {
  return <View />;
};

export default HomeScreen;

src/screens/HomeScreen.tsx

ပြီးရင်တော့ သူ့ရဲ့ test file ဖြစ်မယ့် HomeScreen.test.tsx ကို အခုလို update လုပ်ပါမယ်။ ဒီမှာ ကျွန်တော်တို့တွေ component render လုပ်မလုပ်ကို test id ခေါ်ပြီး စစ်ကြည့်ထားတာပဲ ဖြစ်ပါတယ်။

import React from 'react';
import {describe, test} from '@jest/globals';
import {render} from '@testing-library/react-native';
import HomeScreen from '../HomeScreen';

describe('HomeScreen', () => {
  test('should render correctly', () => {
    const screen = render(<HomeScreen />);
    screen.getByTestId('home-screen');
  });
});

အပေါ်မှာ လုပ်ခဲ့သလိုပဲ test ရေးပြီးပြီးချင်း run တဲ့အခါ implementation မရှိသေးတဲ့အတွက် pass မဖြစ်သေးပါဘူး။ ကျွန်တော်တို့ လိုချင်တဲ့ result တွေကို test ထဲမှာ တဆင့်ချင်း ရေးသွားပါမယ်။ အခုတော့ test id ကိုပဲ လိုချင်သေးတာဖြစ်တဲ့အတွက် test id ကိုပဲ​ test ကနေ ခေါ်ထားတာ ဖြစ်ပါတယ်။

ဒီတော့ HomeScreen.tsx ကို test pass ဖြစ်ဖို့ လိုတာတွေ ထည့်ပါမယ်။

import React from 'react';
import {View} from 'react-native';

const HomeScreen = () => {
  return <View testID="home-screen" />;
};

export default HomeScreen;

test ပြန် run ကြည့်တဲ့အခါ test တွေအကုန် pass ဖြစ်နေမှာပဲ ဖြစ်ပါတယ်။

နောက်တစ်ပိုင်းမှာတော့ home screen မှာ component တွေကို ဆက်ပြီး ရေးသွားမှာပဲ ဖြစ်ပါတယ်။