TDD란 요약하자면 Test Code먼저 작성하는 개발방법이라 할 수 있다.
Testing을 하지 않고 개발을 하면 아래와 같이 코드를 작성한다.
Test Code를 먼저 작성하면 아래와 같이 작성한다.
이 외에도 다양한 장점들이 있긴하다.
하지만, 경우에 따라서 초반에 개발 시간이 더 들어갈 수 있으며
협업하는 환경이라면 모두가 Testing 코드에 익숙해야 한다.
fireEvent와 userEvent는 유저의 인터렉션을 포함한 Testing하기 위한 API이다.
결론적으로, userEvent API 를 활용하는 것이 옳다.
userEvent는 fireEvent를 기반으로 만들어졌는데
userEvent는 Element의 Type에 따라 좀 더 적절한 Event가 호출된다.
fireEvent는 button을 click하여도, focus가 안되는 등 기능에만 집중되어있다.
@testing-library에 포함되어 있으며 아래와 같이 import된다.
import { fireEvent } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
다음과 같이 사용할 수 있다.
어떠한 button이 있다고 하자.
const Counter = () => {
const [counter, setCounter] = useState(0);
return (
<p data-testid="counter">{counter}</p>
<button data-testid="plus-btn"
onClick={() => setCounter(counter + 1)}>
+</button>
)
}
test code에서 두 API는 다음과 같이 사용한다.
test("+ button pressed, counter changed 1", () => {
render(<Counter />);
const btnElement = screen.getByTestId('plus-btn');
const numElement = screen.getByTestId('counter');
// fireEvent.click(btnElement);
userEvent.click(btnElement);
expect(numElement).toHaveTextContent(1);
})
하나의 test함수에 여러개의 expect를 하면 어떻게 될까?
결론적으로는 가능하다.
예를 들어, 어떤 버튼을 누르면 3개의 버튼이 disabled 되는 상황을 test 하면 정상적으로 동작은 한다.
test("diabled button pressed, all buttons disabled", () => {
render(<App />)
const disabledElement = screen.getByTestId('disabled-button');
userEvent.click(disabledElement);
const aBtn = screen.getByTestId('a-btn');
const bBtn = screen.getByTestId('b-tn');
const cBtn = screen.getByTestId('c-btn');
expect(aBtn).toBeDisabled();
expect(bBtn).toBeDisabled();
expect(cBtn).toBeDisabled();
})
상황에 따라 변하지 않으면서 단순한 것들은 묶어서 처리할 수 있다.
하지만, 가급적 나누어서 처리하는 것이 클린한 코드가 아닐까?
협업하는 환경에서는 판단 하는기준이 달라질 수 있기 때문에
1 function 1 test가 convention으로 적합할 것 같다는 생각이다.