오늘의 개발

TDD 챌린지 2주 차 - 썸네일 생성기 기능 구현 & cypress 테스트 코드 작성

유토냥이 2023. 6. 4. 22:27

 

지난 1주 차 때 핵심 기능과 테스트 명세를 간단히 작성해보았다.

이번 주 차에서는 테스트를 작성하고 핵심 기능이 동작하도록 구현할 예정이다.

최소한의 UI로 기능을 테스트 후 기능을 확장하고자 한다.

 

만들고자 하는 것은 썸네일 생성기이다.

당장은 단순히 랜덤한 단색 배경과 제목, 내용을 입력할 수 있는 정도의 기능을 구현할 것이다.

 

초기 세팅 완료~

 

테스트 코드가 동작하려면 해당 페이지 진입을 시켜주어야한다.


✨ 써보며 익히는 cypress

cy.visit()

인자로 넣은 url을 방문하는 메서드이다.

 

 

cy.get()

인자로 CSS 선택자, DOM 엘리먼트를 넣어주면 해당 요소를 찾는다.

위 코드에서 cy.get('#title')은 #title이라는 id값을 가진 HTML 요소를 찾는다.

 

cy.contains()

get과 함께 체이닝해서 사용할 경우를 예를 들면, 동일한 class를 가진 요소가 여러개 존재할 경우 어떤 요소를 선택할 것인지 선택이 필요할 수 있다.

이때 contains의 인자로 넣은 text를 기준으로 엘리먼트를 찾을 수 있게 된다.


✨참고 사항

Cypress에서 특정 요소를 선택할 때에도 '안티 패턴'이 존재한다.

CSS나 JS가 변경되기 쉬울 수록 권장되지 않는다.

 

다음은 공식문서의 내용을 일부 캡처해보았다.

<button
  id="main"
  class="btn btn-large"
  name="submission"
  role="button"
  data-cy="submit"
>
  Submit
</button>

변경이 되어도 테스트에 영향을 미치지 않는 것이 항상 권장되는 것 같다.

 

이번 TDD 챌린지를 진행 중에 일부 테스트 코드는 안티패턴으로 작성될 수 있겠다는 생각이 들었다..😓

하지만 권장되지 않는 사항이 있다는 것을 알았으니 의식하면서 작성해봐야겠다. 

 

type()

cy.get으로 선택한 엘리먼트에 값을 입력하는 메서드이다.

인풋 상자에 텍스트 '제목입니당'을 입력하기 위해 사용했다.

 

should()

애플리케이션 상태를 어설션하는 메서드이다. (공식문서 피셜.)

인풋 상자에 작성한 텍스트가 미리보기 뷰에도 반영되어야하므로 미리보기 뷰의 타이틀 텍스트 요소를 찾은 후 should메서드를 사용하여 '제목입니당'이라는 텍스트를 가지고 있는지 체크해주었다.

 

간단한 테스트부터 하나씩 추가하여 작성해보았다.

처음에는 기능 구현을 하지 않고 테스트 코드만 먼저 작성하여 실패하는 테스트를 만들고, 이후 기능 로직 코드를 작성해주었다.

 

리팩토링이 필요해요 😨

싸이프러스에서 Mock 작업을 수행할 수 있는 것으로 아는데, 해당 사항은 문서를 조금 더 살펴봐야 할 것 같아서

우선 자바스크립트 코드로 기능 구현은 이렇게 작성해보았다.

 

init 함수 이름이 내부 코드 행위와는 전혀 연관이 없어서 리팩토링도 수행할 생각이다.

 

changeTitleText 함수를 만들어서 타이틀 변경 이벤트를 분리해주었다.

겸사겸사 테스트 코드도 리팩토링 해주자.

 

테스트 코드는 중복되는 부분을 함수로 만들어서 재사용하도록 했다.

다른 것보다 함수 네이밍하는 게 참 어렵다.. ㅠㅠ

 

진행을 하다 보니 css 스타일이 들어가지 않으면

완성할 작업물 특성상 아웃풋 확인이 어려울 것으로 생각되어

css 작업을 간단히 추가하기로 했다.

 

배경 색상 변경 버튼을 누르면 배경 색상이 랜덤한 hexcode 값이 되도록 변경해야한다.

문제는 '랜덤' 값을 테스트 코드로 작성해야하는 부분에서 cypress는 어떻게 랜덤 값을 테스트하는지 알 필요성을 느꼈다.

 

그 전에 궁금증이 든 사항은 다음과 같다.

- 랜덤 값을 테스트 하기 위해서 Mock 함수를 만들어야 하나?

- 아니면 배경 색상이 변경되었는지만 판단해야하는 걸까?

 

 

랜덤 값 테스트를 위해 stub을 사용하여 작성한 함수의 반환 값을 강제로 제어하려고 했는데 계속 랜덤한 색상으로 변경이 되어 나타나는 문제로(아마 stub을 제대로 못 쓴 것 같지만..) 😓 window 객체의 random함수를 스텁하여 강제로 0.5를 반환하도록 하는 방식으로 단순한 테스트 코드를 작성하는 방법을 선택했다.

배경 색상이 변경되었는지 정도만 확인할 수 있다.

 

궁금한 사항이자 해결하지 못한 문제 🤔

'랜덤한 값'을 반환하는 함수를 테스트 코드로 작성하는 올바른 방법은 무엇일까.

 

아쉬운대로 해당 함수의 테스트 코드를 만들어서 16진수 6자리를 생성하는지 테스트 하는 코드를 추가했다.

E2E 테스트에서도 함수를 테스트코드로 작성하는지는 모르겠다.

아무래도 사용자 시나리오를 테스트하는 쪽이라 함수 단위로 테스트하진 않을 것 같단 생각이 들지만

하지 말라는 법은 없을테니 아쉬운대로 작성해봤다.

 

 

정말 기본적인 기능에만 충실한 썸네일 생성기를 완성했다.

배경 커스텀이 된다거나, 제목이나 내용의 폰트 크기, 색상 등 변경할 수 있는 커스텀 기능들을 넣어 확장해볼 수 있겠다.

 

[2주 차] 아직 해결하지 못한 문제 🤔

이미지를 다운로드 받는 부분을 테스트 코드로 어떻게 작성하는걸까.

테스트 코드 작성하고 기능을 구현했어야하는데 이미지 다운로드 시뮬레이션은 어떻게 해야되는지 몰라서 기능부터 구현해버렸다.

이미지 다운로드 테스트 코드 작성은 되는대로 본문에 추가할 예정이다.

 

랜덤한 값을 리턴하는 함수를 사용할 경우 어떻게 해야할까?

강제로 함수의 리턴 값을 고정시키는 방법이 전부인건가.. 앞서 작성했던 고민이지만 해결 방법이 궁금하다. 😵

 

(+06.05 추가)

이미지 다운로드를 이벤트를 가로채서 테스트하고 싶었는데 무지하여 해당 테스트 코드가 제대로 동작하지 않았다.

슬프지만 다운로드된 이미지의 위치만 체크하는 테스트 코드로 작성했다..

 

작성하고 싶었던 테스트 코드는 다음과 같다.

썸네일 생성 버튼 클릭 -> 이미지 다운로드 intercept -> 다운로드 된 이미지 파일 확장자 확인

하는 방식으로 테스트 코드를 짜고 싶었는데 공식문서 뒤적거렸지만 해결하지 못해서 클릭 후 일정 시간 대기 시킨 후 파일이 저장된 위치에 있는지 확인하는 방법으로 테스트 코드를 작성했다. (넘나 아쉽..)

 

비록 해결하지 못했지만 해당 부분을 참고하고자 했던 문서는 여기

 

회고

이번 주는 피로에 시달려서 빠르게 완성하지 못한 게 아쉽다.

바닐라 자바스크립트를 사용했으니 다음엔 리액트로 TDD 하는 것도 도전해보고 싶다는 생각이 들었다.

Cypress랑은 아직 친하지 않은 어색한 사이긴 하지만 친해지려고 노력중이다.

 

썸네일을 이미지화 하는 부분에서 직접 구현을 시도해보고 싶었는데 생각보다 시간이 조금 소요될 것 같아서 아쉬운대로 라이브러리를 사용했다. 확실히 라이브러리가 쉽고 빠르고 간편하긴 한 것 같다. ㅋㅋㅋ

 

리팩토링도 해야되는데 피곤함을 핑계로 다음 주의 나에게 조금 양보해볼까 한다.

 


참고 자료

Cypress 공식문서