Golang에서 캐시 없이 테스트하기

Golang에서 캐시 없이 테스트하기

2025년 2월 14일

image

Golang에서 테스트 할 때에는 2회차부터는 테스트 속도가 매우 빨라진다.

1회차

ok      github.com/my/package/test    126.752s

2회차

ok      github.com/my/package/test    (cached)

1회차엔 2분이 넘게 걸렸지만, 2회차엔 시간을 잴 세도 없이 빠르게 테스트가 끝나버렸다

사실 성능적으로 달라진 것은 아니고, 코드가 변경되지 않은 경우 테스트 결과를 캐시를 통해 다시 사용하기 때문이다.

통합 테스트

먼저 통합 테스트란 여러 컴포넌트를 하나로 묶어서 테스트하는 것을 말한다.

Mocking을 주로 하는 유닛 테스트와는 다르게 실제 컴포넌트를 주로 다루기 때문에, 테스트 속도가 느린 것이 특징이다.

다만 API 서버에서는 이런 통합 테스트가 실제 사용자의 행위를 가장 실물에 가깝게 테스트가 가능하기에 종종 사용된다.

통합 테스트에서는 이런 캐시 관련된 부분을 제외해야 할 때가 종종 있다.

통합 테스트에서 캐시 없이 테스트 하는 이유

모든 통합테스트에서 그렇진 않다. 사실 멱등성을 보장하는 테스트라면, 캐시를 사용해도 무방하다.

만약 외부 서비스 같은걸 사용하지 않고, 테스트에도 이런 것들이 제외되어 있다면, 캐시를 사용해도 무방하다. (오히려 이런 경우에는 테스트 시간을 조금이라도 줄이기 위해 사용해야 한다)

다만 외부 서비스 사용이 많고, 테스트가 멱등성을 보장하지 않는다면(매번 결과가 달라진다거나 하는 등), 그리고 외부 서비스의 변경으로 인해 수정해야 하는 소요가 많다면, 캐시된 결과를 그대로 믿는 것보단, 그 때 그 때 마다 테스트를 실행하는 것이 좋을 것이다.

캐시 없이 테스트하기

각설하고 이유가 길었는데 캐시를 사용하지 않는 방법은 매우 간단하다. go test 의 플래그로 -count 1을 사용하면 된다.

go test -count 1 -v ./...

이런 방식이면 캐시를 사용하지 않고, 매번 테스트를 실행할 수 있다.

-count 1 인가?

-count 1은 사실 캐시를 하라, 하지 말아라 하는 명령어는 아니다. 단순히 테스트를 몇번 실행할 것인가를 지정하는 것이다.

또한 공식 문서에 따르면 디폴트 값도 1이기에 원래는 생략하더라도 동일한 동작을 해야하는 옵션이다.

-count n
    Run each test, benchmark, and fuzz seed n times (default 1).
    If -cpu is set, run n times for each GOMAXPROCS value.
    Examples are always run once. -count does not apply to
    fuzz tests matched by -fuzz.

단 이 옵션은 그 동작이 같지 않다.

의도인지 아닌지는 모르겠으나 공식 문서에서도 다음과 같이 캐시를 비활성화 하는 관용적인 방법으로 -count 1을 사용하라고 지시하고 있다.

“The idiomatic way to disable test caching explicitly is to use -count=1.”

마치며

사실 방법론으로 -count 1과 같은 옵션으로 캐시 유무를 결정하는 건 내 생각엔 설계 미스인 것 같다.

일반적으로 디폴트 옵션과 동일한 값을 사람들은 넣을 필요가 없다고 생각하기 때문이다.

오히려 버그라고 봐도 무방할 정도인데, 왜 Go에서는 이런 방식을 유지하고 있는지 모르겠다. 차라리 -no-cache 같은 플래그를 두어서 좀 더 명확하게 하면 좋지 않았을까…?