본문 바로가기

기록

[LOG]테스트 커버리지 - 토스 컨퍼런스 이응준

Mock 대신 ㅡmock 오브젝트 생성 

 

클린 코드 - 테스트 코드의 커버리지 100% 요구한다. 
50% 에서 100% 까지 2개월
커버리지 측정 시작 
커버리지 낮으면 배포 되지 않게 설정 
2개월 동안 6천라인
테스트 되지않은 코드는 한줄도 없다는 확신이 생겼다.
모든 코드가 커버리지 된 후 리팩토링이 가능해 졌다. 
불필요한 프로덕션 코드가 사라진다. 남아있다면 그것 또한 테스트 해야한다.  

높은 커버리지로 인한 문제, 테스트 케이스 400개 실행시간 1분 초과 
테스트가 느려지면 생산성이 떨어진다. 
느려지는 원인 
스프링 애플리케이션 컨텍스트 로딩을 모두 제거 
보통 서버의 http api 테스트 할때 컨텍스트 로딩을 하는 경우가 많은데 많은 스프링 웹 애플리케이션이 
컨텍스트 로딩없이 테스트 가능하게 해주는 standalone 기능을 제공하고 있고(WebTestClient) 

static Mocking 
다만 main 함수가 실행될때 스프링 애플리케이션이 기동 되는지를 테스트 할때는 애플리케이션 컨텍스트 로딩만 제거하는것은 상당히 어렵기 때문에 
모킹 라이브러리의 스태틱 모킹 기능을 이용해서 스프링을 모킹해서 실제로 스프링 애플리케이션은 기동 되지 않고 
스프링 애플리케이션 run 이 호출되는 지만 확인하는 방법으로 해결했습니다. 


그다음은 1600 개가 되었다. 다시 1분 초과
느려지는 원인을 찾기 위해 프로파일링이 필요했다. 그래서 제가 사용하는 ide 인 intellij 에 내장된 프로파일러인

다시 느려진 원인 
SLF4J
Jsckson ObjectMapper() 생성 
Handlebars 컴파일
Byte Buddy 초기화 
코틀린 리플랙션 모듈 초기화 
MockK 
테스트의 순차적 실행 (cpu 활용 제대로 못하니까)

2. 테스트 하기 어려운 테스트 
db테스트 , 네트워크 테스트 , 프레임 워크 테스트 , 랜덤 테스트, 시간에 의존 적인 테스트 -> 대체로 모킹을 이용하면 그럭 저럭 해결 가능했다. 

진짜 어려운 코드는 코틀린이 생성해낸 바이트 코드를 테스트 하는 것이었습니다. 
커버리지 기준이 라인 커버리지가 아닌 인스트럭션 커버리지 이기 때문에 모든 바이트 인스트럭션이 커버 되어야 했다. 


0 + 1 의 테스트 케이스 버그 
누군가 실수로 sum 함수의 + 연산자를 - 로 바꿨을때도 ;; (테스트가 충분하지 않은데도 커버리지가 100프로가 된다.) 

뮤테이션 테스팅  : 무작위 조작 pitest.org 도구 jvm 기반 도구에 대해 뮤테이션 실행해준다. 
충분히 느리므로 중요한 로직에만 부분적으로 적용하는 것이 좋다. 

Cucumber : 정돈되지 않은 문서 , 어려운 커스터 마이징 

jUnit5의 TextExecutionListener
: 테스트 실행시마다 테스트의 이름 수집 가능 
수집한 테스트의 DisplayName 으로 스펙 문서 생성 도구 개발 

Consumer Driven Contract 
계약을 관리해 주는 Pactflow 라는 도구가 존재 api 를 사용하는 컨슈머 쪽이 요구사항을 machine-readable 하게 기술하면, 
API를 제공하는 쪽, 즉 프로바이더가 그 요구사항을 만족하는지 테스트 하는 것입니다. 


결론 - 테스트 커버리지는 얼마든지 높일수 있다. 
테스트 커버리지가 낮으면 빌드 실패하게 하자 
테스트는 빨라야 한다. 
커버리지가 100% 라도 버그는 있다. 





https://blog.npcode.com/page/6/

 

eungjun

테스트 커버리지를 100%까지 끌어올리면서 테스트로 커버하기가 굉장히 어려운 코드를 종종 만나곤 했다. 다음과 같은 코틀린 코드가 그렇다. fun isYes(answer: String): Boolean { return when(answer) { "yes" ->

blog.npcode.com

https://blog.npcode.com/page/5/

 

eungjun

테스트 커버리지를 100%까지 끌어올리면서 테스트로 커버하기가 굉장히 어려운 코드를 종종 만나곤 했다. 다음과 같은 코틀린 코드가 그렇다. fun isYes(answer: String): Boolean { return when(answer) { "yes" ->

blog.npcode.com

 

 

https://github.com/msbaek/atdd-example/commit/40b39e49722ff5e56ec282e2892747f326e1ebf6

반응형