소개
코드 조커
◦ 기초부터 완성까지, 프런트엔드(개발부터 테스트까지, 이론과 예제로 배우는 프런트엔드) 저자
◦ 11년차 프런트엔드 개발자
◦ (현) 글로벌 컨텐츠 회사 FE 개발 부문 팀장
◦ (전) NHN TOAST Cloud FE 개발 팀장
◦ (전) 삼성 SDS FE 개발자
오프
◦ 기초부터 완성까지, 프런트엔드(개발부터 테스트까지, 이론과 예제로 배우는 프런트엔드) 저자
◦ 7년차 프런트엔드 개발자
◦ (현) 글로벌 메신저 회사 FE 개발자
◦ (전) NHN TOAST UI 오픈소스 개발자
강의
수강평
- 실무에 바로 적용하는 프런트엔드 테스트 - 2부. 테스트 심화: 시각적 회귀・E2E 테스트
- 실무에 바로 적용하는 프런트엔드 테스트 - 1부. 테스트 기초: 단위・통합 테스트
- 실무에 바로 적용하는 프런트엔드 테스트 - 1부. 테스트 기초: 단위・통합 테스트
- 실무에 바로 적용하는 프런트엔드 테스트 - 1부. 테스트 기초: 단위・통합 테스트
- 실무에 바로 적용하는 프런트엔드 테스트 - 1부. 테스트 기초: 단위・통합 테스트
게시글
질문&답변
에러 해결 방법
안녕하세요~AI 인턴 친구가 남겨주신 것처럼 아마 노드 버전의 문제이지 않을까 싶습니다.사용하시는 노드 버전이 22버전이라고 되어있는데, 강의는 19버전을 사용하고 있어서요.가능하다면 nvm use 를 통해 버전을 맞춰 강의를 진행해주시거나 현재 버전으로 진행하고 싶으시다면 assert 대신 with로 구문을 변경해서 사용해주시면 될 것 같습니다. 관련 이슈도 올려드릴게요!감사합니다~https://stackoverflow.com/questions/78876691/syntaxerror-unexpected-identifier-assert-on-json-import-in-node-v22
- 0
- 2
- 22
질문&답변
Retry-ability와 커스텀 커맨드, 커스텀 쿼리 질문
안녕하세요 메가님! 답이 조금 늦었네요 ㅠㅠ 죄송합니다.1. 커스텀 쿼리도 Retry-ability 지원되고 커스텀 쿼리 안에 커맨드도 Retry-ability가 지원되면 n의 m제곱 번의 재시도가 발생하는 것일까요?이 부분은 실제 구현을 참고해봐야 할 것 같은데요. 제가 구현을 했다고 가정을 하고 감히 추측을 해보면, n의 m승으로 재시도가 발생하는 경우 그렇게 재시도 시기의 검증 효용이 없다고 판단하고(적다 보니 아닌 경우도 있을 수 있을 것 같네요) 최적화를 했을 것 같은데 cypress측에 문의를 해봐야 할 것 같네요 ㅎㅎhttps://github.com/cypress-io/cypress/issues요기에 문의를 진행해보시면 어떨까 싶습니다!2. 커스텀 커맨드와 커스텀 쿼리 중에 뭘 사용할 것인지는 Retry-ability 지원 유무와 체이닝을 기준으로 선택하면 될까요?예시코드를 봤을 때 getCardButton와getProductCardByIndex 둘 다 DOM 요소를 조회해서 subject를 리턴하여 체이닝을 통해 후속 작업을 하는 것처럼 보이는데 왜 getProductCardByIndex는 커스텀 커맨드로 작성하는지 잘 모르겠습니다.. 말씀해주신대로 Query가 붙은 API와 안붙은 API의 가장 큰 차이는 retry-ability지원 여부입니다.Query가 붙은 API는 동기 방식으로 동작하며 이전까지 체이닝으로 사용한 커맨드의 subject 결과를 받아 사용합니다. 그리고 체이닝으로 연결된 코드를 일정 시간동안 재시도합니다.(https://docs.cypress.io/api/cypress-api/custom-queries)반대로 Query가 붙지 않은 커스텀 커맨드는 비동기로 동작할 수 있으며, 특별한 설정을 하지 않으면 이전의 subject를 이어 받아 사용하지도 않습니다.또한 내부적으로 재시도를 실행하지 않고 단 한번만 실행합니다.예시의 경우 아마 강의 특성상 여러 방법이 있다고 소개를 드리려고 하다보니 직접적이게 와닿는 예시가 아닐 수 있는데요. 이 부분은 죄송합니다. 목적에 맞게 선택해 구현한 뒤 사용하면 됩니다.
- 0
- 1
- 28
질문&답변
직접 구현한 atom 컴포넌트 테스트 범위 질문
안녕하세요. 메가님!직접 작성한 atom 컴포넌트의 경우 다양한 범위에서 사용될 수 있고 영향도가 높은 컴포넌트이며 프로퍼티의 구조에 따라 다른 모습을 나타낼 가능성이 높기 때문에 각각에 대해 명확한 기능적 테스트와 시각적 테스트가 있으면 좋을 것 같습니다.
- 0
- 1
- 47
질문&답변
setup, teardown 동작 순서
안녕하세요!질문주신 내용 답변드립니다.beforeAll 내에 console이 첫번째로 찍히다가 afterAll과 함께 사용할 경우에는 afterAll 바로 직전(마지막 바로 앞)에 찍히고 있습니다. (afterAll을 지울 경우에는 첫번째로 찍히고 있습니다.)vitest의 경우 포매팅을 위해 기본 console 클래스의 동작을 가로채어 로그를 찍도록 구현되어 있는대요. 이 구현 과정에서 로깅의 타이밍이 보장되지 않는 걸로 보입니다. 실제로 setup, teardown의 코드 실행 자체는 beforeAll -> beforeEach -> afterEach -> afterAll 로 이뤄지나 log 자체의 동작때문에 다르게 찍히는 걸로 보입니다. vite.config.js에 disableConsoleIntercept옵션을 true설정하면 예상한 순서대로 로그가 찍히는 것을 확인할 수 있습니다..!beforeEach는 it을 실행하는 횟수만큼 실행되는거 같은데요. describe내에 선언한 beforeEach는 describe내에 호출한 it의 횟수만큼 실행되는게 맞는거 같은데 root의 beforeEach, afterEach도 it의 횟수만큼 실행되는게 맞을까요?넵 맞습니다. 다만, root의 beforeEach, afterEach 모든 it의 개수와 비례하여 실행됩니다~!
- 0
- 1
- 56
질문&답변
debounce 함수 테스트 정확도 관련 질문입니다.
안녕하세요 일상님!debouncedFn이 300ms이 지난 후 실행되어야 함을 테스트할 때, 기존에 작성해주신 것 처럼 테스트할 시에는 함수가 300ms 후가 아닌 즉시 실행이 되거나 그보다 작은 시간이 지나고 실행이 되어도 테스트가 통과하게 됩니다.이 말씀에 대해 조금 더 여쭤보고 싶은데요! 혹시 이런 경우에 작은 시간이 지나도 테스트가 성공한다는 의미는 어떤건지 알 수 있을까요? 제가 추측해보면it('특정 시간이 지난 후 함수가 호출된다.', () => { const spy = vi.fn(); const debouncedFn = debounce(spy, 300); debouncedFn(); expect(spy).toHaveBeenCalled(); // 추가 vi.advanceTimersByTime(300); expect(spy).toHaveBeenCalled(); });이렇게 했을 때 통과되는 것 아니냐 라는 의미로 이해했는데 괜찮을까요? 제가 테스트를 했을 때는 해당 시나리오에 대해서는 통과하지 않아서 조금 더 설명해주시면 저희가 작성한 코드가 잘못된 부분이 있는지 확인을 해보도록 하겠습니다. 추가로 말씀해주신대로 좀 더 구체적으로 호출이 되지 않았음을 확인한 뒤 이후에 호출이 되었음을 확인하고 싶다면, 작성해주신 코드에서 조금만 수정해서 it('특정 시간이 지난 후 함수가 호출된다.', () => { const spy = vi.fn(); const debouncedFn = debounce(spy, 300); debouncedFn(); expect(spy).not.toHaveBeenCalled(); // 즉시 호출되지 않았는지 확인 vi.advanceTimersByTime(300); expect(spy).toHaveBeenCalledTimes(1); // 300ms 후에 정확히 한 번 호출되었는지 확인 });정도로만 검증을 해도 충분하지 않을까 싶습니다! 만약 경계에 대한 명확한 트리거 시점에 대해 검증을 하고 싶으시다면 작성해주신대로 (마지막 toHaveBeenCalled만 제거하고) 작성해주셔도 충분히 좋은 검증 방식이신 것 같습니다.추가로 궁금한 점 있으시면 편하게 질문주세요~ 감사합니다!
- 0
- 2
- 37
질문&답변
브랜치 git clone 질문
한나릴님 안녕하세요!main 브랜치에 내용이 없고, 과정을 진행하시면서 브랜치를 바꿔가면서 진행하실거라 내용이 존재할겁니다! 확인 부탁드릴게요~
- 0
- 1
- 26
질문&답변
ProductFilter test 어떤 방식이 더 선호되는 방식일까요?
안녕하세요!크게 검증하는 내용은 달라지지 않을 것 같습니다. 연속적으로 입력을 하더라도 실제 구현적인 관점에서 달라지는 부분은 없으니까요. 만약 순서를 변경하는것으로 개선을 도모하셨다면 두 테스트를 나눠서 작성하는 것도 좋을 것 같습니다 ㅎㅎ 말씀해주신 패턴대로 적용도 가능하고 각 검증 범위를 나눠 테스트 케이스를 작성했기 때문에 실패했을 때 어느 부분에서 문제가 발생했는지 훨씬 더 쉽게 알 수 있을 것 같아요!it('최소 가격을 수정하면 setMinPrice가 호출된다.',it('최대 가격을 수정하면 setMaxPrice가 호출된다.',
- 0
- 2
- 80
질문&답변
통합 테스트 작성 방식에 대해 궁금한 점이 있습니다
안녕하세요! 답변이 조금 늦었네요 ㅠㅠ 넵 맞습니다. 내부 구현에 대한 의존적인 테스트라고도 볼 수 있을 것 같습니다. 당시 코드를 작성했을 때 기억을 되살려보면.. ProductFilter에 대한 통합테스트이고 값이 변경되었을 때 실제 화면에서 적절하게 변경되었다라는 것을 인지할 수 있는 부분은 각 아이템들에 대한 값이 제대로 노출되는지 여부 정보만 검증할 수 있다고 생각했던것 같습니다. 추가로 필터로 지정된 값으로 더 외부에서 노출되는 아이템이 달라지기 때문에 영향을 미칠 수 있는 store set 함수를 테스트하지 않았나 라고 생각이 듭니다. 현재 테스트 구조상 E2E 테스트에서 실제 필터값의 결과를 테스트하고 있기 때문에 올바른 동작을 검증하고 있습니다. 그래서 Home에 대한 페이지의 통합테스트는 따로 작성되지 않았는데요. 만약 E2E테스트를 사용하지 않고 좀 더 통합테스트에서 해당 동작을 검증하고 싶다면 Home에 대한 통합테스트를 작성해서 실제 결과를 검증해보면 말씀해주신 사용자 관점의 테스트가 될 것 같습니다.! 만약 훅 자체를 반환한다면 훅을 사용하는 컴포넌트 내에서 훅에 대한 검증이 사라지게 되는데요. API 응답만을 모킹하게 되면 해당 훅에 대한 동작은 함께 검증할 수 있기 때문에 두 테스트의 검증 범위가 달라지게 됩니다. 따라서, 테스트 목적에 맞게 판단해서 진행하면 될 것 같습니다.
- 0
- 2
- 99
질문&답변
unit-test-example 브랜치에서 'Test result not found.' 가 뜹니다...
안녕하세요! 문제 해결에 정보가 조금 부족한 것 같은데요.의존을 어떻게 설치하고 실행하셨는지 정보를 조금 더 주실 수 있을까요?
- 0
- 1
- 68
질문&답변
vitest Extension 알려주세요.
안녕하세요~여기 확인해주세요!https://vitest.dev/guide/ide실험실 문양이 아니라 익스텐션 설치에 가셔서 vitest 살펴보시면 될 것 같습니다~
- 0
- 1
- 106