리액트 컴포넌트 + 스냅샷 테스트
2022-05-30
안녕하세요 지금까지 jest 문법은 어느정도 공부했으니 이번 시간에는
실제로 리액트 컴포넌트를 만들어서 테스트해보고 스냅샷 이라는 것도 한번 0:09 알아보겠습니다
# create react app
일단 create react app으로 프로젝트를 하나를 띄웠습니다
그리고 간단한 컴퍼넌트를 만들겠습니다
Hello.js 라고 만들겠습니다
App.js
import Hello from "./component/Hello";
function App() {
return (
<div className="App">
<Hello />
</div>
);
}
export default App;
필요 없는 건 좀 지울게요
이렇게 사용하겠습니다
화면에 헬로우 보입니다.
App.js
import Hello from "./component/Hello";
const user = {
name: "Mike",
age: 30,
};
function App() {
return (
<div className="App">
<Hello user={user}/>
</div>
);
}
export default App;
이제 유저를 만들구요
이 유저를 전달해 주겠습니다
Hello.js
export default function Hello({ user }) {
return user.name ? <h1>Hello! {user.name}</h1> : <button>Login</button>;
}
유저를 받아서
유저의 이름이 있으면 헬로우 뒤에
유저의 이름을 보여주고
없으면 로그인 버튼을 보여주겠습니다
지금은 “Mike”가 보이구요.
name을 지우면 로그인 버튼이 보입니다
간단한 ui이지만 테스트를 한번 작성해 보겠습니다
create react app 테스트는 jest를 사용합니다 그러니까 별도 설치
없이 바로 테스트 코드를 작성하시면 됩니다
package.json 파일을 열어보면 테스트 명령어가 이미 입력되어 있죠
한번 실행해 볼게요
test
Test Suites: 1 failed, ...
실패 합니다 어 기존의 작성돼 있었던 테스트 한번 살펴보면
app.test.js
import { render, screen } from '@testing-libaray/react';
import App from './App';
test('renders learn react link', () => {
render(<App />);
const linkElement = screen.getByText(/learn react/i);
expect(linkElement).toBeInTheDocument();
});
여기에 app.test.js 파일이 있는데 @testing-libaray/react 에서 render 와
screen을 import 했습니다
테스트에 대한 설명은 ‘renders learn react link’가 렌더링 되는지 보고 있는데 아까
우리가 지워버려죠.
그러니까 실패하는 게 맞습니다 지우구요. 이제 헬로 컴퍼넌트를
테스트 해보겠습니다
Hello.test.js
import { render, screen } from '@testing-libaray/react';
import Hello from './Hello';
const user = {
name: "Mike",
age: 30,
};
test('Hello 라는 글자가 포함되는가?', () => {
render(<Hello user={user} />);
const helloEl = screen.getByText(/Hello/i);
expect(helloEl).toBeInTheDocument();
});
동일한 이름의 테스트를 붙여서 파일을 만들고
네 이렇게 작성했습니다 @testing-libaray/react
라이브러리에 있는 render와 screen을
이용했습니다 render를 통해서 헬로 component를 불러오고
유저를 props로 전달 해줬습니다 그 다음에 스크린에서 이 텍스트가 있는지
확인해봅니다 Hello
라는 텍스트가 있는지 확인하고, 이 부분에서 테스트가
실행이 되겠죠
도큐먼트 안에 방금 지정한 이 텍스트 가 있는지 확인해보는 겁니다
아 테스트 해보면
Hello
로 라는 글자가 포함됐고 잘 통과 됐죠
스냅샷
이번엔 제스트 스냅샷을 활용해 보겠습니다 스냅샷을 성공하는 개수를
찍어두고 비교하면서 테스트 하는 방식입니다 렌더링된 화면과 찍어둔 화면이
다르면 실패하는 거죠
네임이 있는 경우와 없는 경우로 만들어서 테스트를 해보겠습니다
Hello.test.js
import { render, screen } from '@testing-libaray/react';
import Hello from './Hello';
const user = {
name: "Mike",
age: 30,
};
const user2 = {
age: 20,
};
test("snapshot : name 있음", () => {
const el = render(<Hello user={user} />);
expect(el).toMatchSnapshot();
});
test("snapshot : name 없음", () => {
const el = render(<Hello user={user2} />)
expect(el).toMatchSnapshot();
});
test('Hello 라는 글자가 포함되는가?', () => {
render(<Hello user={user} />);
const helloEl = screen.getByText(/Hello/i);
expect(helloEl).toBeInTheDocument();
});
toMatchSnapshot()
으로 스냅샷을 확인해봅니다
이렇게 두가지 경우로 만들었구요
이름이 있는 경우와 없는 경우 두가지로 만들었습니다
테스트를 해 보면
test
v snapshot : name 있음
v snapshot : name 없음
v Hello 라는 글자가 포함되는가?
> 2 snapshots written.
Snapshot Summary
> 2 snapshots written from 1 test suite.
두 개의 스냅샷이
작성되었다 라는 메시지가 뜨고, __snapshots__
라는 못보던 폴더가
생겼습니다
열어보면 Hello.test.js.snap
이 라고 되어 있죠
클릭을 해보면 이름이 없을 때
로그인 버튼이 있고
이름이 있을 때 Hello! Mike
라고 찍혀 있습니다
이렇게 만들어 졌죠 이제 여기서 조금만 달라져도 테스트는 실패하게 됩니다
예를 들어서 여기 있는 이름을 Tom
으로 바꿔 볼게요
Hello.test.js
import { render, screen } from '@testing-libaray/react';
import Hello from './Hello';
const user = {
name: "Tom",
age: 30,
};
const user2 = {
age: 20,
};
test("snapshot : name 있음", () => {
const el = render(<Hello user={user} />);
expect(el).toMatchSnapshot();
});
test("snapshot : name 없음", () => {
const el = render(<Hello user={user2} />)
expect(el).toMatchSnapshot();
});
test('Hello 라는 글자가 포함되는가?', () => {
render(<Hello user={user} />);
const helloEl = screen.getByText(/Hello/i);
expect(helloEl).toBeInTheDocument();
});
test
- Snapshot - 2
+ Received + 2
- Mike
+ Atomics
> 1 snapshots failed.
Test Suites: 1 failed, 1 total
Tests: 1 failed, 2 passed, 3 total
Snapshots: 1 failed, 1 totalpassed, 2 total
Watch Usage
> Press a to run all tests.
> Press f to run only failed tests.
> Press u to update failing snapshots.
> ...
실패 하죠
당연합니다 아깐 마이크로 작성되어 있었기 때문이죠 이 부분에서 확인할 수
있습니다. 스냅샷에는 마이크로 되어 있고 지금 전달한 이름은 톰
이기 때문이에요
이렇게 실패했을 때 선택할 수 있습니다 첫번째는 스냅샷을 업데이트 해주는
4:53
겁니다
4:55
이 코드의 아무 문제가 없다 단지 이제 테스트는 마이크 말고 톰으로
5:00
진행할 거다 그런 판단이 들면 스냅샷을 업데이트에서 갱신 해주면
5:05
그만입니다 한번 해 볼게요 여기 지금 여러가지 메뉴가 나오는데 여기 있죠
5:11
실패한 스냅샷을 업데이트한다
5:14
u 를 누르면
5:16
하나의 스냅샷이 업데이트가 됐고 모두 성공하게 됩니다
5:22
파일을 열어서 확인해 보면 아까는 마이크 였는데 지금 톰 으로
5:26
바뀌어 있죠.
5:27
간단하게 업데이트가 되죠 그래서 더 조심해야 됩니다
5:31
만약 버그가 있어서 실패한 건데 꼼꼼히 살펴보지 않고 귀찮다고 업데이트 해
5:35
버리면 이후부터는 버그가 있는 상태에서 테스트가 통화 되는 겁니다
5:39
그러니까 신중하게 결정하셔야 됩니다
5:42
자 테스트가 실패했을 때 할 수 있는 두 번째 방법은 당연하겠지만 버그를
5:47
수정하는 겁니다
5:49
자 여기서 유저를 전달 하지 않겠습니다
5:53
그러면 로그인 버튼이 나와야 되니까 통과하는 되겠죠
5:57
아까 찍었던 스냅샷을 로그인 버튼이 호출하는 화면이 있으니까요
6:00
npm test
를 해보면
6:03
실패하게 됩니다 우리 살펴보면
6:07
내용을 찾을 수가 없다 헬로 컴퍼넌트 에서 에러가 같죠
6:11
코드를 보면 지금 유저 없기 때문에 1조 어쩜 내 힘도 찾을 수 없는거고
6:17
그래서 에러가 난 거고 이건 명백한 버 그저 님이 업된 1절 사제가 업된
6:22
모두 로그인 버튼을 보여주는게 만든 겁니다 그러니까 이 유저의 여부도
6:27
체크가 되어야 되겠죠
6:29
구들을 수정하겠습니다 어떻게 수정하면 될까요
6:32
유저가 있고
6:34
유저의 이름도 있고 이렇게 적어 주면 되겠죠
6:38
5
6:41
4 동아 있습니다 좀 더 간단하게
6:48
이렇게 접을 수도 있겠죠 이부분 옵션을 채닝 이라는 건데
6:53
1 적 없어도 에러를 내지 않고 언제 파일들을 알아 주기 때문에 믿고
6:57
사용할 수 있습니다 4
6:59
어제 가지로 통과가 됐죠
7:02
부분적인 시간에 따라 변하는 컴퍼넌트를 만들어 볼게요
7:05
타이머 라는 컴포넌트를 만들고 현재 시간에 초를 표시해주고 있습니다
7:19
4 어 지금 현재의 초를 보여주는 타임 하라는 컴포넌트 동안 들었구요
7:24
그래서 인 끝에서 사용하고 있습니다 네 이렇게 초과 표시되고
7:29
진입 시장의 초로 보여주기 때문에 새로운 지 말 때마다 초가 바뀝니다
7:37
디스 코드를 한번 작성해 볼게요
7:41
타이머를 번 더 해 주고요
7:45
네 이렇게 만들어 주고 테스트를 해 보면 아
7:53
테스트 지금 처음이니까 스냅샷 8g 만들어졌죠
7:58
열어보면
8:01
2심 34 겨 라고 표시되어 있습니다
8:04
다시 실행을 해보면
8:07
4 실패하게 되죠 56초 라고 나오고
8:11
1조 라고 나오고
8:13
이렇게 대부분의 확률로 실패하게 됩니다 이럴 때는 어떻게 할까요
8:17
매번 업데이트를 해 주면 될까요 그래서 w 를 누르고
8:22
나오는 메뉴에서 아까 u 를 누르면 업데이트 해 주십시오
8:26
업데이트를 해도 다음에 또 실패했기 뻔합니다 이때는
8:30
이전 시간에 배운 목 홍 전 을 사용합니다
8:34
2 테스트 코드에서 데이트 점
8:37
나 5를
8:41
짬 이렇게 하면 목 함수를 만들 수가 있죠
8:46
점수를 작사 해줍니다 이런식으로 숫자를 아마 바라야 줍니다
8:51
이제 데이트 점 나오는 1 값으로 고정이 되는 거에요
8:55
이 상태에서 테스트를 돌리고
8:59
타임 실패할 있죠 이 쫓아 일을 좀 실패 했네요
9:02
여기서 u 를 눌러서 업데이트를 한번 해 주겠습니다
9:08
4
9:09
확인을 해보면 30 60% 밖에 없구요
9:18
s 테스트를 들리고 하며
9:21
4 냄새 계속 성공하게 됩니다 테스트 내가 언제 라이 숫자로 수행되기
9:26
때문에 항상 통하게 되어있습니다
9:30
이렇게 시간에 따라서 변할 수 있는 것들은 테스트 션의 목 함수를
9:33
이용해서 고정된 값으로 바꾸어 주시면 됩니다
9:37
자 복잡한 디자인 있을 때 코드를 일일이 되죠 하면서 확인하는 작업은
9:41
상당히 힘들죠
9:43
색깔이나 리스트에 개수나 텍스트들을 비교하는데 한줄한줄 테스트 코드를
9:48
짜는 것은 대단히 비율 적입니다 그때 이렇게 스냅샷 테스트를 진행하는
9:52
것이 좋습니다
9:53
하지만 불필요한 테스트가 너무 많아 질 수도 있어요 그렇게 되면 오히려
9:57
스냅샷 테스트를 할 때보다 못하죠
10:00
그리고 기획에 따라 ui 를 계속 바뀌는 경우에는 추천하지 않습니다
10:04
꽃 크리스마스인데 배경이미지 나 알콘 이벤트 꾸준히 자주 바뀌는 화면
10:09
되려면 테스터 4 계속 실패하게 될 것이고 앨범 업데이트를 해 주는게
10:13
작업에 전부 일 거에요
10:15
이런 점들을 잘 인지 하시고 사용하시면 도움이 될겁니다
10:20
마치겠습니다 감사합니다