게시글
질문&답변
2024.05.31
vitest 실행시 테스트 실행에서 출력을 기록하지 않았습니다
안녕하세요 김건하님! 저는 개인적으로 해당 탭을 사용하고 있지 않아서 이슈를 좀 찾아봤는데요. https://github.com/vitest-dev/vscode/issues/175 아마 이 이슈와 연관되어 있지 않을까 싶습니다. 참고 부탁드려요! 추가로 현재 과정은 npm으로 실행하는 것을 권장하고 있습니다! 이 부분도 같이 챙겨주시면 감사하겠습니다~
- 0
- 1
- 22
질문&답변
2024.05.28
질문 있습니다.
안녕하세요 Raehan Jeong님~! 우선 통합 테스트 강의에서 설명하듯이 통합 테스트의 단위는 비즈니스 로직이 응집되어 있는 컴포넌트가 되어야 하는대요. 이렇게 통합 테스트 대상이 되는 컴포넌트의 경우 UI를 렌더링하기 위한 여러 작은 컴포넌트로 결합되어 있습니다. 그리고 이 컴포넌트를 기준으로 비즈니스 로직에 대한 기능 검증 을 실행합니다. 이와는 조금 다르게 스토리북은 기능 검증 보다는 개발 과정에서 UI가 올바르게 렌더링 되었는지 확인하기 위한 도구입니다. 즉, 스토리북은 비즈니스 로직을 검증한다 보다는 UI를 확인한다 라고 할 수 있는대요. 그렇기 때문에 통합 테스트 단위와 스토리북 단위는 같을 수도 있지만 다른 경우가 더 많을 것 같습니다. 예를 들어 예매한 영화 티켓의 정보를 보여주는 컴포넌트 가 있고 가정해보겠습니다. 이 컴포넌트에서는 API를 통해 티켓의 정보를 보여줘야 하며, 티켓 확인 버튼을 누르면 사용 완료 같은 문구를 보여줘야 할텐데요. 이런 다양한 비즈니스 요구 사항을 통합 테스트로 검증할 수 있습니다. 만약 예매한 영화 티켓의 정보를 보여주는 컴포넌트 를 대상으로 스토리북을 작성한다면 API부터 상태 변경까지 모두 모킹하거나 별도의 조작을 통해 스토리를 작성해야 하는데요. 이렇게 되면 스토리 작성 작업에 대한 비용도 커지며, 원하는 스토리를 만들어 UI를 확인하는데에도 불필요하게 많은 시간이 소요됩니다. 결국 예매한 영화 티켓의 정보를 보여주는 컴포넌트 도 예매 버튼, 티켓 정보를 보여주는 타이틀 등의 여러 컴포넌트들로 구성될텐데요. 이런 컴포넌트들은 UI를 보여주는게 전부이며 별도로 검증할 만한 로직들이 없습니다. prop으로 받은 정보를 렌더링하는 정도의 역할만 하기 때문에 단위 테스트를 작성하는 것이 크게 의미가 없고 오히려 스토리북으로 UI만 빠르게 확인하는 것이 좋습니다. 필요하다면 이런 presentational 컴포넌트들을 조합하여 스토리로 만들어 확인할 수도 있구요. (그렇기 때문에 컴포넌트 설계 시 통합 테스트 단위와 UI 확인 단위를 명확히 나누는 것도 굉장히 중요하다고 강의 후반부에 이야기합니다..!) 결과적으로 스토리북과 통합 테스트는 서로 확인하려는 목적이 다르기 때문에 단위가 다를 수 있습니다. 말씀하신 내용중에 통합 테스트를 스토리북과 같은 도구와 함께 하라는 것이 아니라, 통합 테스트로 상태에 따른 동작을 검증하고, 그 안에 있는 각각의 컴포넌트들은 스토리북 안에서 스타일과 레이아웃이 틀어지지 않는지 확인하라는 것 이 강의의 목적에 좀 더 부합하는 방향으로 보입니다. 혹시나 이해가 안가거나 더 궁금한 사항이 있으시다면 편하게 말씀해주세요~!
- 0
- 1
- 39
질문&답변
2024.05.09
2강 storybook & vitest
안녕하세요 전상원님~! 말씀하신 브랜치 기준으로 세팅을 동일하게 하고 재현해보았는데요. 저 같은 경우에는 스토리북이나 테스트 실행 모두 이상없이 동작하네요. 의존성 버전 호환의 문제일 수 있을 것 같은대요. 혹시 해당 브랜치 기준으로 node_modules 폴더를 삭제하고 npm ci 로 의존성을 다시 설치해도 동일할까요?
- 0
- 2
- 99
질문&답변
2024.05.04
mockServiceWorker.js 파일이 프로젝트내에 포함되어 있어야 하나요?
안녕하세요 bn.kim 님! 1.x 버전에서 세팅을 진행할때는 init cli가 잘 나와있었던 것 같은데, 2.x로 넘어가면서 해당 문서가 잘 보이지 않네요. 해당 파일은 브라우저에서 msw를 수행할 때 파일이 필요한 것으로 알고 있습니다. init cli를 통해 세팅을 진행할 경우 해당 세팅을 모두 해주는 것으로 알고 있는데요! 실제 서비스 배포시에는 해당 파일이 굳이 public에 위치할 필요는 없으니 빌드 후에 제거해주시면 좋을것 같습니다. 아래 참고 하실 수 있는 문서 같이 드립니다! https://mswjs.io/docs/cli/init
- 1
- 2
- 66
질문&답변
2024.04.05
toHaveClass 테스트코드 관련하여 질문 남깁니다!
안녕하세요 디건버님~! 우선 css modules 처럼 동적인 해시값에 의해 className이 변경되는 경우에는 vitest의 css.modules.classNameStrategy 설정을 통해 테스트 환경에서 css에 해시값이 추가되지 않도록 할 수 있습니다. (jest의 경우 https://github.com/keyz/identity-obj-proxy 라이브러리를 사용하면 문제를 해결할 수 있습니다.) // 예제의 vite.config.js export default defineConfig({ plugins: [react(), eslint({ exclude: ['/virtual:/**', 'node_modules/**'] })], test: { // ... setupFiles: './src/utils/test/setupTests.js', // 아래 옵션 추가 css: { modules: { classNameStrategy: 'non-scoped', }, }, }, resolve: { alias: [{ find: '@', replacement: path.resolve(__dirname, 'src') }], }, }); // jest.config.js module.exports = { // ... moduleNameMapper: { "\\.(css)$": "identity-obj-proxy", ... }, }; export default class App extends Component { render() { return ( Hello, world! ); } } // 위의 설정을 적용하면 아래처럼 해시값없이 키값만 기준으로 className이 생성됩니다. exports[`test App renders correctly 1`] = ` Hello, world! `; 테스트에서는 로직의 흐름에 따라 className이 올바르게 변경되는 것인지 검증하는 것이 목적입니다. 따라서 동적인 스타일 해시값까지는 굳이 검증할 필요가 없는대요. 다행히 테스트 도구들의 설정을 통해 해시값 설정을 제거하고 className이 적절하게 변경되는지 명확하게 검증할 수 있습니다. 이외에도 AI가 답변해준 것처럼 toHaveClass 매처에 정규 표현식을 사용하여 검증하는 방법도 있지만 번거로움이 있기 때문에 설정을 통해 컴포넌트의 테스트 코드를 좀 더 깔끔하게 관리하는 것이 좋을 것 같습니다..! 제가 vanila-extract 는 직접 사용해보지는 않았지만 공식 문서에 위에서 이야기한 설정에 대한 가이드 가 있으니 이 부분을 참고하시면 문제없이 동작하지 않을까 합니다. 혹시 추가적인 문의 사항이나 이슈가 있다면 얼마든디 편하게 답글 남겨주세요. 감사합니다! 😃
- 0
- 2
- 146
질문&답변
2024.03.28
4.3 강의 자료가 이상해요
안녕하세요 2scent님! 강의자료 pdf 형태로 다시 업로드 하였으니 확인 부탁드립니다. 이외에도 궁금하거나 이슈가 있다면 언제든지 편하게 말씀해주세요! 🙂
- 0
- 1
- 113
질문&답변
2024.03.26
shopping-mall-integration-test 브랜치에 이상한 점 발견
안녕하세요 제일일님! 해당 부분은 테스트에서 다음과 같이 프로덕트 카드를 선택할 때 사용하는 목적으로 사용하고 있는데요. const productCards = await screen.findAllByTestId('product-card'); 혹시 에러 코드나 어느 부분에 문제가 발생했는지 조금 더 구체적으로 설명해주실수 있을까요?
- 0
- 2
- 179
질문&답변
2024.03.23
show more 버튼이 노출되지 않는 테스트 케이스에서 limit 오동작 문제
안녕하세요 leo.kang 님! 제가 결혼식에 가야하는 일정때문에 조금 서둘러 답변 드리는 점 양해 부탁드립니다 🥲 저녁에 돌아와서 조금 더 궁금하신 점 남겨주시면 내용 보충해서 남겨두겠습니다. 우선 첫 번째로 남겨주신 질문은 useInfiniteQuery 의 동작 문제가 맞는 것 같습니다. 해당 코드를 only를 붙여 돌리거나 순서를 바꿔 가장 먼저 호출하게 하면, 정상적으로 동작하는데요. 구현 부를 조금 살펴보면, OFFSET을 제외한 params를 키로 사용하다보니 캐싱이 되어 이전 요청을 그대로 사용해 해당 문제가 발생하는 것으로 보입니다. params를 options 로 변경하면 코드가 테스트가 동작될 겁니다. 사실 offset이 앱 자체에서 변경될 일이 없다보니..저렇게 했던것 같기도 한데요. 저도 사실 요즘 RQ를 사용할 때 선호하는 구현 방식은 아니라 올바른 방법으로 작성한다면, OFFSET도 포함을 시켜줘야 할 것으로 보입니다. 시간이 된다면 최신 RQ를 적용하면서 키 관리 방식을 수정하고 싶네요 ㅎㅎ.. 해당 부분 코드 수정해서 업로드 해 두도록 하겠습니다. 발견해주셔서 감사합니다. 👍 export const useLoadMore = ({ url, options }) => { const { params, ...others } = options; const context = useInfiniteQuery( [url, params], ({ queryKey, pageParam = 0 }) => defaultFetcher({ queryKey, pageParam: { offset: pageParam * others.limit, limit: others.limit }, }), { getNextPageParam: (lastPage, pages) => { return lastPage.lastPage ? false : pages.length; }, }, ); return context; }; 두번째로 msw 핸들러 부분이 말씀해주신 부분대로 수정이 되어야 하는 것 같습니다. 이 부분은 명백하게 잘못 구현되어 있는 것 같은데요. 이 부분은 제가 최대한 빠르게 예제 코드에 반영해두도록 하겠습니다. 혼란 드려 죄송합니다. 제보 감사하며, 추가로 궁금한 점 있으시면 편하게 댓글 주세요!
- 1
- 1
- 122
질문&답변
2024.03.16
상태 검증과 행위 검증에 대해서 질문이 있어 남기게 되었습니다!
안녕하세요 종민님~! 우선 말씀하신 것처럼 커스텀 훅의 경우 비즈니스 로직 자체에 대한 입력과 결과 특히 상태의 변화에 대해 테스트를 작성하는 것이라 할 수 있습니다. 그리고 컴포넌트 역시 사용자가 이벤트를 발생시켰을 때의 상태 변화를 검증하는 상태 기반 검증이라 할 수 있습니다. 일반 함수나 커스텀 훅과는 다르게 내부적으로 캡슐화되어 사용되는 React의 state가 검증 대상이 아닐 뿐, 이 상태가 DOM에 제대로 반영되는지 DOM의 상태 변화 를 검증합니다. 즉, 컴포넌트 통합 테스트 역시 상태 기반의 검증 이라 할 수 있습니다. 컴포넌트의 상태가 올바르게 DOM에 반영되는지 검증하고 있기 때문이죠. ( 컴포넌트의 상태 검증을 위한 테스트 코드 작성 형태가 이벤트를 통한 행동 기반인 것이지, 테스트 검증 자체는 결국 DOM 상태를 기준으로 하고 있습니다! ) 다만, 강의 예제에서 일부 케이스 테스트는 말씀하신 행위 기반의 테스트로 작성되어 있습니다. 바로 리액트 라우터를 통한 네비게이션 검증이 대표적인 예시인대요. JSDOM 기반의 테스트 구동 환경은 실제 브라우저 환경이 아닙니다. 그렇기 때문에 제대로 url이 변경되는지 검증하기 어려우며, 그렇다고 외부 라이브러리인 리액트 라우터의 내부 구현에 따른 상태를 테스트에서 검증하게 되면 배보다 배꼽이 더 커지는 형태가 됩니다. 이렇게 내부 테스트에서 검증하기 힘든 외부 영역(라이브러리 또는 다른 외부 시스템)이 있을때는 spy나 mock을 사용해 행위 기반으로 검증합니다. 예제의 경우 링크 이동에 필요한 navigate 함수가 호출되었는지 spy를 통해 행위 기반으로 검증하고 있습니다. spy나 mock을 사용한 테스트는 대부분 어떤 행위를 했는지 안했는지 검증하기 때문에 실제 상태가 올바르게 변경되었는지 정확성있게 검증하지는 못합니다. 그렇기 때문에 프런트엔드 테스트에서도 특별한 경우가 아니면 spy나 mock을 많이 사용하지는 않습니다. 강의에서는 msw를 사용한 API 응답 데이터를 갈아끼우는 행위도 모킹이라고 표현해서 헷갈리실 수 있는대요. 사실 이 부분도 응답 데이터를 우리가 원하는 데이터로 고정하여 상태를 검증하는 것이기 때문에 일종의 stub이라고 할 수 있습니다. (테스트더블에 대한 내용은 2부 강의 후반부에 좀 더 자세히 설명하니 참고 부탁드립니다 🙂 ) 내용이 길었는대요. 정리하자면 아래와 같습니다. 컴포넌트의 상태가 올바르게 DOM에 반영되는지 검증하고 있기 때문에 컴포넌트 통합(또는 단위) 테스트 역시 상태 기반의 검증 이다. 대부분의 프런트엔드 테스트에서는 특별한 경우가 아니면 DOM 상태를 확인하는 상태 기반으로 검증한다. 외부 라이브러리 또는 시스템 내에서 제어할 수 없는 영역의 경우 spy나 mock을 사용하여 행위 기반으로 검증한다. msw를 사용한 API 응답 데이터를 갈아끼우는 것도 우리가 원하는 상태를 검증하기 위해 만든 stub이다. 혹시 더 궁금한 사항이 있다면 얼마든지 댓글로 남겨주세요!
- 0
- 1
- 106
질문&답변
2024.03.08
navigate 관련 테스트에서 질문있습니다!
안녕하세요 종민님! 우선 강의 들어주셔서 감사합니다. 결국 말씀해주신 기능에 있어서, 가장 실제 시나리오와 비슷한 검증은 E2E 테스트에서 가능할 것입니다. 클릭을 하면 실제 브라우저에서 경로가 변하기 때문에 url을 검증하면 제대로 이동이 되었는지 확인할 수 있거든요. 다만, 단위 통합 테스트 환경에서 navigate라는 함수를 호출했을때 navigate 함수가 제대로 동작할 것이라는 가정하에 어떤 경로로 호출되었는지를 검증하는 형태로 구현이 되어있을 건데요. 이렇게 확인할 경우 간편하다는 장점도 있지만, 단점 또한 존재합니다. https://www.inflearn.com/questions/1172186/mocking%EA%B3%BC-spy%ED%95%A8%EC%88%98%EA%B0%80-%ED%97%B7%EA%B0%88%EB%A6%BD%EB%8B%88%EB%8B%A4 이 질문에 간단하게 제가 정리를 해뒀는데요! 같이 읽어보시면 좋을 것 같습니다~ 추가로 궁금하시면 질문 남겨주세요!
- 1
- 1
- 128