이응준, 테스트 커버리지 100%
- 테스트 커버리지는 얼마만큼 이 적당할까? 70%?
- 클린 코더를 읽다가 테스트 커버리지 100%를 요구
- -> 말도 안 되는 것 같음, 테스트 어려운 코드도 존재하기 때문에
새로운 프로젝트에 테스트 커버리지 100% 도전
- 의외로 가능 (인스트럭션 기준으로 커버리지 100% 기록)
- 테스트 커버리지가 떨어지면 빌드가 안되게 설정
- 프로덕션 코드는 4천 라인, 테스트 코드 2천 라인(50%)
- 테스트 코드 6천 라인까지 도달 (100%, 23% 커밋이 테스트 코드)
계속 유지할 수 있을까?
- 다행히 유지가 가능했다.
장점들
- 자신 있게 배포를 할 수 있게 되었다.
- 테스트 커버리지가 100% 된 이후 거침없이 리팩토링이 가능, 마스터 브랜치에 걱정 없이 머지
- 불필요한 프로덕션 코드가 사라진다
- 프로덕션 코드에 대한 이해도 상승
- 점점 쉬워지는 테스트 작성(기존 테스트 코드 참고)
테스트 커버리지를 높이기 위해 필요한 것들
- 믿음, 시간이 많이 소요
필요하지 않은 것들
- 의지 : 편한 길을 택하려는 유혹,
- 도구를 이용 Gradle의 Jacoco의 빌드 실패 이용
2가지 어려움
1. 느려지는 테스트 : 400개 테스트 시 1분 초과(생산성 저하)
느려지는 원인 : 스프링 애플리케이션 컨텍스트 로딩
해결
- 스프링 애플리케이션 컨텍스트 로딩 제거, 모킹 라이브러리 이용
- 1-1 다시 느려지는 테스트 : 1600개 테스트 시 1분 초과
- intelliJ이 프로파일러인 async-profiler 이용하여 성능 프로파일링 그 결과 아래 원인들 도출
- 느려지는 원인 : SLFJ4 초기화, Jackson ObjectMapper() 생성, Handlebars 컴파일, Byte Buddy 초기화, 코틀린 리플렉션 모듈 초기화, MockK, 테스트의 순차적 실행(CPU를 충분히 활용하지 못함)
해결
- 불필요한 로깅 설정 제거
- Jackson을 Gson으로 교체
- handlebars 캐시 적용
- ByteBuddy테스트에서 사용 중단
- 코틀린 리플렉션 모듈 초기화의 isSubclassOf 함수 호출 제거
- MockK 필수적이지 않으면 모두 제거
- 테스트를 클래스 단위로 병렬 실행
- 다시 40초 미만으로 실행됨, 노트북 교체 후 6초대
2. 진짜 어려운 테스트
- 어려울 거라 생각했던 테스트
- DB테스트
- 네트워크 테스트
- 프레임워크 테스트
- 랜덤 테스트
- 시간에 의존적인 테스트
- -> mocking으로 어떻게든 테스트 가능
진짜 어려운 테스트는?
- 코틀린이 생성해낸 바이트 코드 테스트하기
100% 규칙
- 새로 추가한 코드가 조금이라도 커버되지 않으면 언제나 실패
- 커버리지 리포트를 보고 빠뜨린 곳을 알 수 있다.
99% 규칙
- 운 좋게 넘어갈 수도, 억울하게 실패할 수도 있다
100%를 넘어서
- 그래도 버그는 있다.
- 1. 테스트를 잘못 작성하는 경우
- 테스트 케이스가 부족할 때 -> Mutation Testing / pitest.org (굉장히 느리므로, 중요한 로직에만 적용하는 것이 좋다.)
- 2. 요구 사항에 오해가 생긴 경우
- 테스트로 스펙 문서 만들기 : Cucumber의 스펙 문서 생성 -> 만족스럽지 못함 -> Junit5의 TestExecutionListener를 이용하여 스펙문서 생성 프로그램 개발
- 3. 컴포넌트 간 협업이 실패할 경우
- 다른 서버와 협업하는 경우, Consumer Driven Contracts기법을 이용
- Spring Cloud Contract와 Pact 중 Pact를 이용하기로 결정
결론
- 테스트 커버리지는 얼마든지 높일 수 있다.
- 테스트 커버리지가 낮으면 빌드 실패하게 하자.
- 테스트는 빨라야 한다.
- 커버리지가 100%라도 버그는 있다.
이항령, 토스 서비스를 구성하는 서버 기술
1. 토스 서비스를 구성하는 서버 기술들
- 2개의 데이터 센터를 active-active, AWS 등등....
- 최근 개발 소스는 코틀린 이용
2. 데이터 센터 트래픽 조절
- 서비스 카나리 배포를 데이터 센터에 적용
3. K8S + Istio
- DC/OS에서 K8S로 마이그레이션
- 높은 Observability
- application concern을 infrastructure concern으로 변경하기 에는 힘든 부분도 존재
- 1% Canary 가능
- Failure Injection Test / Squeeze Test
- Failure Injection Test : 특정 조건에 맞는 요청의 경우 실패, 응답을 늦게 하도록 만들어 서비스에서 실패에 대한 처리가 제대로 되어 있는지 테스트
- Squeeze Test : 하나의 인스턴스에 요청의 비율을 높여 부하를 주는 테스트, 어느 정도 요청부터 서비스 부하를 느끼는지 확인
4. api-gateway / webflux
- spring cloud gateway선택
5. monitoring
- 오픈소스 이용
- 로그 : 컨테이너 ID, 서비스 ID, 배포 ID, Request ID, Pinpoint ID
- apm : Pinpoint
- metric : thanos + ceph + grafana
- 알림 : sentry + toss ES alert + grafana
6. kafka
7. redis
참가 목걸이
'세미나' 카테고리의 다른 글
YOUTHCON'21 요약 (0) | 2021.12.19 |
---|---|
[OKKY 7월 세미나] 개발자에게 좋은 이직/퇴사를 위한 꿀팁 (0) | 2021.07.25 |
[2월 우아한테크세미나] 우아한 스프링 부트 (0) | 2021.04.04 |
[OKKYCON: 2018] 정진욱 - 테스트하기 쉬운 코드로 개발하기 (0) | 2021.03.27 |
[자바 라이브 스터디] 종료 기념 리뷰 (0) | 2021.03.21 |