개발

프론트엔드 vs. 백엔드 테스트

flowertaekk 2021. 5. 22. 09:48

사이드 프로젝트로 Next.js 를 TypeScript로 쓰면서 TDD방식으로 진행하려고 이것저것 찾아보면서 공부하고 있던 중에 '백엔드에서 테스트를 대하는 방식과 프론트에서 테스트를 보는 관점이 좀 다르다' 라고 느껴서 공부를 시작하게 되었고, 정리한 내용을 공유하겠습니다.

 

참고로 프론트엔드쪽의 테스트는 아직 미경험이기 때문에 부족한 점이 많습니다! 지금은 이론적으로 공부한 것들을 정리하지만 나중에 실제로 경험해 본 후기를 공유할 수 있도록 할게요!


우선 테스트 비용적인 측면에서 유명한 Mike Cohn씨의 테스트 피라미드를 봐볼까요?

 

위로 올라갈수록 테스트에 드는 비용(시간 및 테스트 작성 난이도)가 증가

요소들을 살펴보면 아래와 같습니다.

  • UI test : 브라우저에 표시되고 있는 어플리케이션의 구조 및 컨텐츠를 테스트
  • Service test : UI를 제외한 전체적인 비지니스 로직의 테스트
  • Unit test : 단위 테스트! 함수 단위로 테스트

이 피라미드가 표현하고 있는건,  UI 테스트는 시간이 오래걸리고 테스트를 쓰는 것이 어려운 반면, Unit 테스트는 시간도 오래 걸리지 않고 테스트 작성도 쉽게 할 수 있다는 것입니다.

 

Mike Cohn씨의 피라미드는 백엔드(Unit에서 Service까지)에서는 잘 작동하지만, UI 테스트에 대한 비용이 너무 크기 때문에 프론트엔드에 적용하기에는 무리가 있습니다. 특히나 TDD로 진행하기 위해서는 테스트의 안정성 측면에서도 그렇고, 개발 속도면에서도 문제가 있습니다.

 

여담이지만, TDD는 테스트와 함께 개발하기 때문에, 테스트 없이 개발하는 것보다 개발 속도는 느리다고 생각하실 수도 있겠지만, TDD를 활용한 개발방식이 테스트 없이 개발을 진행하는 것보다 훨씬 빠르다는 통계가 있습니다. (켄트 백 님의 '테스트 주도 개발' 강력 추천합니다!)


그러면 프론트엔드의 테스트는 어떤 식으로 구조화해야 효율적인 개발이 가능할까요?

Kent C. Dodds 씨가 자바스크립트 어플리케이션 테스트를 가이드하기 위해 만든 '테스트 트로피'가 있습니다!

자세한 설명은 Kent C. Dodds씨의 트위터 에서 확인하실 수 있습니다.

 

Kent C. Dodds on Twitter

“"The Testing Trophy" 🏆 A general guide for the **return on investment** 🤑 of the different forms of testing with regards to testing JavaScript applications. - End to end w/ @Cypress_io ⚫️ - Integration & Unit w/ @fbjest 🃏 - Static w/ @flowt

twitter.com

요소들을 내용을 살펴보면 다음과 같습니다.

  • End to End : 백엔드부터 프론트엔드까지 전체적인 어플리케이션을 테스트 (Cypress)
  • Integration : 하나의 화면 내에 있는 모든 것들이 제대로 동작한다는 걸 보장할 수 있는 레벨의 테스트. 예를 들면 버튼을 눌렀을 때 어느 컴포넌트의 무엇이 바뀌는지 동작을 테스트한다. (Jest, Enzyme ..)
  • Unit : 유닛 테스트! 하나의 함수를 테스트 (Jest)
  • Static : 자바스크립트의 문법에 문제가 없는지 테스트. 테스트라기 보단 문법을 어기지 않고 코드가 제대로 동작한다는 걸 보장. 코드의 동작을 보장한다는 점에서는 테스트라고 보는 것 같다. (ESLint, Prettier..)

 

 

테스트 트로피를 보면 Integration 이 가장 중요한 많은 비중을 차지하고 있듯이, 프론트엔드의 테스트는 Integration 테스트를 중심으로 프로젝트를 이끌어 가는게 중요하다고 합니다.


그래서 백엔드에서 보는 테스트와 프론트에서 보는 테스트에 대한 관점이 어떻게 다른데?

첫 번째로, Mike Cohn씨의 '테스트 피라미드'와 Kent C. Dodds씨의 '테스트 트로피'에는 Service가 Integration으로 바뀌었다는 차이가 있네요!

 

그럼 Service와 Intergration은 어떻게 다를까요?

위에서 정리한 내용을 다시 가져와서 리마인드 해볼까요?

Service test : UI를 제외한 전체적인 비지니스 로직의 테스트
Integration : 하나의 화면 내에 있는 모든 것들이 제대로 동작한다는 걸 보장할 수 있는 레벨의 테스트. 예를 들면 버튼을 눌렀을 때 어느 컴포넌트의 무엇이 바뀌는지 동작을 테스트한다. (Jest, Enzyme ..)

Service test는 특정 input이 있을 때, 예상하는 output이 나오는지를 테스트합니다. 결국, 여러 Unit 테스트를 조합한 결과를 테스트한다고 볼 수 있겠네요!

 

반면에, Integration test 에서는 input이 있고, 특정 이벤트(onClick) 등이 발생했을 때 화면이 어떻게 바뀌는지(output)에 대한 테스트를 합니다.

 

공통적으로는 역시 input에 대한 output이 제대로 나오는지를 테스트하고 있지만,

데이터의 결과를 테스트를 할지(Service test), 뷰(화면)의 결과를 테스트하는지(Integration test)에 대한 차이가 있다고 느꼈습니다.

 

두 번째로, 백엔드에서는 Unit 테스트를 중심으로 프로젝트를 진행한다고 한다면, 프론트엔드에서는 Integration 테스트를 중심으로 프로젝트를 이끌어나아간다는 차이가 있습니다.

 

백엔드를 TDD로 진행하면서 Unit test가 제대로 구축되어있다면 전체적인 프로그램의 동작도 어느정도 보장 가능하다고 느껴왔는데, 프론트엔드는 확실히 Unit test만으로는 화면의 변화를 테스트할 수는 없기 때문에 Integration test의 비중을 늘려가면서 진행하게 되는 차이가 생기지 않았을까 생각합니다!

 

(물론, Unit test와 Integration test를 중심으로 진행한다고는 했지만, 다른 테스트들 역시 동반되지 않으면 전체적인 프로그램의 동작을 보증하기는 힘들겠죠? 각각의 역할이 있으니까요!)


이번 주제가 TDD를 좋아하는 개발자로서 저에게는 정말 흥미로운 주제였는데, 재밌게 읽어주셨으면 좋겠습니다!

'개발' 카테고리의 다른 글

target="_blank" 다른 탭으로 링크 이동하기  (0) 2021.11.12
Jest 사용법 (Usage)  (0) 2021.05.30
Java 접근 제한자 (Access Modifier)  (0) 2021.05.15
concourse 테스트  (0) 2021.05.05
circle-ci 테스트  (0) 2021.04.30