Introduction
발표자 소개
이번 섹션의 발표자는 신원규 님이다.
주니어 클라우드 개발자로, 현재 B2B 서비스를 제공하는 회사에서 client 앱 개발을 담당하고 있다.
서비스의 특징으로, 비전공자 신입 2명이 맡아 진행한 프로젝트이며 서비스 운영 기간은 약 2년이 조금 안된다. 이번 발표의 주제와 관련된 TDD 를 도입함으로써 적어도 결재와 관련한 장애는 0건이 으로 보고도었다.
Frontend 에서의 TDD 도입에 대해,
FE 는 코드의 생명 주기가 BE 에 비해 매우 짧은 시간을 가져가므로 빠른 배포 주기를 가져가는 데에 방해가 되기 때문에 TDD 도입이 오히려 방해가 된다는 의견도 있다.
때문에 반드시 도입을 해야 한다는 것은 아니며, 프로젝트의 상황, 인력 풀, 자원 등을 상황에 따른 가치 판단을 잘 하여 TDD 도입에 대해 현명하게 판단할 수 있어야 한다.
TDD 를 적용하면서 다양한 범위에 대한 Test Case 를 세워 대비를 한다고 생
개발자들이 하는 테스트는 결코 Sanity-Test 에 지나지 않는다. (sanity: 이성, 제정신 분별 등)
즉, 본격적인 QA 과정을 진행하기에 앞서 너무나도 당연한 로직을 정상적으로 수행하는 지에 대한 테스트를 뜻한다.
테스트 코드가 중요한 건 알겠는데..
어디서부터 어디까지 테스트를 해야 하지?
어떻게 시작을 해야 하지?
바로 작업을 진행하기 전에 상태 전이도(STD: State Transition Diagram) 를 그려보는 것이 좋다.
만약, 우리 코드가 MVVM 패턴을 따르고 있다면 ViewModel 의 상태에 따라 View 가 화면을 그릴 것이라 기대할 수 있다. 이러한 구조라면 ViewModel 을 하나의 상태를 가지는 FSM 이라 부를 수 있을 것이다.
왜 상태 전이도를 그려야 할까?
⇒ 상태 전이도 자체가 테스트 케이스이기 때문이다. 즉. STD 의 화살표 하나 하나가 개별 테스트 케이스가 된다.
번외+) 문서 작성에 대해 (상태 전이도 포함)
문서를 작성하는 이유는 시스템 구조를 잘 파악하려는 의도도 있지만, 이후 유지보수 과정에서 후임자의 이해를 도와주기 위함도 있다.
때문에 문서와 실제코드의 싱크가 맞지 않으면 오히려 방해가 될 수 있으므로 최초 작성 시에 수정이 용이한 방식으로 문서를 작성하는 것이 좋다.
작성된 테스트 케이스가 어떤 환경에서 실행되어야 할까?

유닛테스트는
쉽고 빠르게 만들수 있으며 유지보수 비용 또한 저렴하다.
통합테스트는
검증 대상과 인접하고 밀접하게 상호작용하는 여러 요소들을 동시에 테스트하는 환경을 의미한다.
UI 테스트(End to End) 란,
시스템 전반의 요소를 최대한 실제 서비스 환경과 비슷하게 테스트하는 환경을 의미한다.
E2E 테스트를 통과했다면 실제 환경에서도 가능하다고 거의 확신할 수 있지만, 작성 비용이 비싸고 유지보수에도 많은 노력이 필요하다.
Q) 모든 테스트 케이스를 E2E 로 작성하게 되면 어떻게 될까?
⇒ 일단 feature 개발 속도가 끔찍하게 늘어날 것이다. 테스트 코드 또한 엄청나게 늘어질 것이며 테스트에 실패하면 어디서부터 어떻게 고쳐야 할 지 오랫동안 살펴봐야 할 것이다.
때문에 가치 판단을 잘 하여 현재 cost 에 적절한 테스트 환경에서 테스트를 하는 것이 가장 적절할 것이다.
TDD 시작하기
TDD 의 첫 시작은 실패를 기대하는 테스트 케이스 작성부터 시작해야 한다.
화면에 진입 하자마자 발생한 이벤트, 페이지 초기 진입 이벤트 등도 class 로 선언한다.
공통 상세와 공통 이벤트 타입을 정의한다.
그리고 아직 동작 할 로직이 없기 때문에 실패를 기대하는 테스트 케이스를 먼저 작성한다.
Q) 실패를 기대하는 테스트 케이스를 작성하는 등, 테스트 케이스가 한 번에 작성되지 않는 이유는?
⇒ 모든 작업은 가능한 한 작은 범위로 쪼개야 하기 때문이다. 그 이유는 리스크 관리 떄문인데, 코드 변경점이 작을 수록 PR 리뷰 과정에서 보다 유의미한 피드백을 나누기 좋고 빠뜨린 부분이 발생할 확률이 적어지기 때문이다.
또한 테스트 케이스는 모델이 만족해야 될 요구사항을 의미하기도 한다. 즉, 이 시점에서 이 모델이 앞으로 만족해야 하는 사양, 방향 등에 대해 토론하고 그 결과에 따라 테ㅅ트 케이스를 재작성하는 과정을 거치게 된다.
Given-When-Then 패턴
흔히 SUT(systen-under-test) 라고 부른다.
절차 지향적이 아닌 유저 시나리오 기반으로 표현하는 방법.
given
테스트에서 구체화 하고자 하는 행동을 시작하기 전에 테스트 상태를 설명하는 부분
관심 있는 이벤트가 일어나기 전에 SUT 가 가져야 할 직전 상태를 설정하는 코드 영역
when
구체화 하고자 하는 그 행동
유저의 행동이 코드로 추상화되어 표현된 부분
then (생략 가능)
어떤 특정 행동 때문에 발생할 것이라 에상되는 변화에 대해 설명하는 부분
유저의 행동에 따라 추가로 변동되는 모델의 변화를 기술하고 이를 기다리는 부분
expect
모든 변화가 종료되었을 때, 어떠한 값을 기대하는 지에 대한 부분
위 각 영역을 나누면서 테스트 코드를 서술한다.
테스트 케이스를 작성하면서..
만약 given 또는 then 이 복잡한 케이스는 작성된 구조에 있어서 뭔가 문제가 있음을 암시하는 것을 뜻한다.
모든 테스트 케이스를 커버할 수 있을까?
⇒ 현실적으로 불가능하다. 하지만 이를 해결하기 위해 2가지 방안 정도를 소개한다.
- realistic 한 데이터를 일부분 가져와서 테스트 코드에서 활용하는 방법
- 테스트 데이터를 랜덤하게 생성하는 방법
랜덤 데이터 테스트 할 때에도 실제 서비스에서 발생할 만한 조합으로 랜덤 제너레이션 코드를 작성해야 한다.
마치며..
엔지니어에게 기술은 매우 중요하다. 그 이유는 기술은 문제 해결의 도구로 사용되어 실생활에 긍정적인 변화를 끼칠 수 있기 때문이다.
여기서 중요한 점은 어떻게 하면 한정된 자원 하에서 문제를 효율적으로 해결할 수 있을 지에 대해 고민하고 전략을 수립한 다음 이를 실천하는 것이다.
공학이 수학과 다른 점은 공학은 trade-off 를 동반하여 문제를 해결해야 한다는 것이기 때문에 당연히 모든 경우에 들어맞는 개발 방법론 또한 존재하지 않는다. TDD 또한 마찬가지다.
TDD 도입으로 인해 얻는 이점도 있겠지만 그에 따른 불이익이 더 클 수도 있기 때문에 각자의 상황에 맞게 trade-off 를 고려해서 도입에 대한 판단을 하길 바란다.
'취미 > 컨퍼런스' 카테고리의 다른 글
| [DroidKnights 2024] 후기 (1) | 2024.06.12 |
|---|---|
| Melos 를 사용한 flutter 모노레포 구축하기 (이정주, GDG Incheon) - Flutter with AI 2024 Seoul (0) | 2024.05.25 |
| Flutter x LangChain (Justin, Flutter Seoul) - Flutter with AI 2024 Seoul (0) | 2024.05.25 |
| 세 가지 기술로 창조하는 혁신적인 앱 개발 워크 플로우 (Aiden) - Flutter with AI 2024 Seoul (0) | 2024.05.25 |
| 프롬프트 엔지니어링 시작해보기 (류지영, Flutter Seoul) - Flutter with AI 2024 Seoul (0) | 2024.05.25 |