less than 1 minute read

defp eventually(func) do
  if func.() do
    true
  else
    Process.sleep(10)
    eventually(func)
  end
end

Programming Phoenix 1.4 책에서 본 소스 코드다. 함수 이름이 eventually라니. 난 이렇게 함수 이름을 못 짓는다. 함수 목적도 명확하다. 결국은 인자로 넘어온 함수가 참이 되는 걸 확인하는 함수니깐.

assert eventually(fn -> Cache.fetch(name, :key1) == :error end)

테스트 코드에서 사용한다. 5초 캐시한 후에 삭제, 혹은 랜덤이 가미된 일정 시간 후 삭제. Process.sleep/1 함수를 떠올리기 쉬운데, 테스트가 느려질뿐더러 깨지기 쉬운 테스트가 된다. 약간 더 늦게 실행되면 테스트가 깨진다. 다시 실행하면 또 된다. 깨지지 않게 하려고 sleep 시간을 늘린다. 테스트가 느려진다. 이런 악순환이 계속된다.

성공할 때까지 시도하는 함수다. 테스트 간격도 10초로 고정되어 있다. 시도 횟수와 테스트 간격을 인자로 추가해 더 쓸모있는 eventually 함수를 만들 수 있다. 테스트에 필요한 함수라서 그런지 well-ironed/liveness 패키지도 있다.