더북(TheBook)

expect 함수들

유닛 테스팅은 작성한 코드에 어떤 입력을 주었을 때 예상되는 출력이 실제로 반환되는지 확인하는 것을 기본으로 한다. 기댓값과 실제 반환 값을 비교하기 위해 사용하는 함수의 일부를 다음 표에 정리했다.

표 5-17 유닛 테스팅을 위한 expect 함수들

함수

의미

expect_true(x)

x가 참인가

expect_false(x)

x가 거짓인가

expect_equal(object, expected)

object가 기대되는 값 expected와 동일한가. 값의 비교에는 all.equal( )이 사용되며 all.equal( )은 두 객체가 (거의) 같은지를 비교한다. 따라서 부동소수의 경우 epsilon(매우 작은 값) 이하로 차이나는 두 값은 같은 값으로 취급한다.

expect_equivalent(x, y)

x가 y와 동등한가. expect_equal( )과 달리 속성(예를 들면, rownames)을 제거한 뒤 값만 비교한다.

expect_equal( )과 expect_equivalent( )는 비슷하면서도 다른 점이 있어 다음에 예를 보였다. expect_equal( )은 완전히 같은 값의 경우에만 테스트가 통과하고 expect_equivalent( )는 객체의 속성을 제외한 값만 비교한다.

> a <- 1:3
> b <- 1:3
> expect_equal(a, b)
> expect_equivalent(a, b)
> names(a) <- c('a', 'b', 'c')
> expect_equal(a, b)       # 벡터에 부여한 이름이 다르므로 테스트가 실패
Error: a not equal to b
names for current but not for target
> expect_equivalent(a, b)  # 벡터에 부여한 이름을 무시하므로 테스트 성공
<Note>
expect에는 이외에도 다양한 함수가 있다. 전체 함수의 목록은 참고자료 [14]와 help(expect_that), help(expect_equal)을 살펴보기 바란다.

expect_equal( )을 사용한 테스트 방법을 피보나치 수열을 구하는 함수를 예로 들어 살펴보자. 피보나치 수열은 1, 1, 2, 3, 5, … 값을 반환해야 하지만 다음 코드에는 일부러 버그를 만들어두었다. fib(0)=1, fib(1)=1이어야 하지만 fib(1)=1 부분이 빠져 있다.

> fib <- function(n) {
+   if (n == 0) {
+     return(1)
+   }
+   if (n > 0) {
+     return(fib(n-1) + fib(n-2))
+   }
+ }

expect_equal( )을 사용해 fibo(0)의 값이 1인지 확인해보자.

> expect_equal(1, fib(0))

피보나치 수열의 첫 번째 값인 fib(0)을 구하면 정답인 1을 제대로 반환한다. 따라서 expect_equal( )에 인자로 준 기댓값 1과 fib(0)의 값이 같다. 따라서 아무런 경고 메시지도 출력되지 않는다.

그러나 수열의 두 번째 값인 fib(1)을 확인해보면 버그 조건에 해당해 fibo(1)의 값이 1과 같지 않다는 에러 메시지가 출력된다.

> expect_equal(1, fib(1))
Error: 1 not equal to fib(1)
Numeric: lengths (0, 1) differ

이처럼 잘못된 값이 반환된 것을 찾았다면 이에 따라 fibo( ) 함수를 올바르게 수정해나가면 된다.

신간 소식 구독하기
뉴스레터에 가입하시고 이메일로 신간 소식을 받아 보세요.