테스트 파일 구조
이 절에서는 코드와 테스트를 어떤 파일에 어떻게 기술해야 하는지를 살펴본다. 가장 일반적인 파일 구성은 비즈니스 로직이 되는 fibo( )를 한 소스 파일에 넣고, 테스트 코드는 별도의 소스 파일에 넣는 것이다. 한 가지 파일 구성의 예는 다음과 같다.
• fibo.R : 비즈니스 로직인 fibo( ) 함수를 작성해 저장
• run_tests.R : 테스트들을 실행하기 위한 명령을 저장한 파일
• tests/test_fibo.R : tests 디렉터리에 fibo 함수에 대한 테스트 코드를 작성해 test_fibo.R로 저장
fibo.R 함수에는 다음과 같이 fibo( ) 함수 코드만 작성해 넣으면 된다.
fibo <- function(n) { if (n == 0 || n == 1) { return(1) } return(fibo(n - 1) + fibo(n - 2)) }
run_tests.R은 다음과 같이 작성한다. 먼저 fibo.R을 source( )하여 해당 파일에 있는 명령을 실행한다. 그러면 그 결과로 fibo( ) 함수가 정의될 것이다. 테스트 수행은 test_dir( ) 함수를 사용하는데, 아래 예에서는 tests 디렉터리에 있는 모든 테스트 파일을 실행하고 그 결과의 요약을 얻게 했다.
require(testthat) source("fibo.R") test_dir("tests", reporter="summary")
tests 디렉터리의 test_fibo.R의 첫 행에는 해당 파일 내 테스트들이 무엇에 대한 테스트인지를 명시하기 위해 context(“fibonacci series”)를 적는다. 이 예에서는 테스트 파일이 하나뿐이지만 여러 테스트 파일을 작성하게 된다면 context( )에 기록한 정보가 유용하게 사용된다. 그 뒤 test_that( )들을 기술하는데, test_that( )은 앞서 설명한 대로 base test와 recursion test 두 가지 경우로 나눈다.
context("fibonacci series") test_that("base test", { expect_equal(1, fibo(0)) expect_equal(1, fibo(1)) }) test_that("recursion test", { expect_equal(2, fibo(2)) expect_equal(3, fibo(3)) expect_equal(5, fibo(4)) })
테스트를 위한 준비가 모두 끝났다. run_tests.R 파일이 있는 디렉터리에서 R을 실행하고 source(“run_tests.R”)을 수행하면 테스트가 실행되는 화면을 볼 수 있다. 테스트 실행 시에는 context( )로 지정한 “fibonacci series”라는 문자열이 출력되므로 어떤 테스트들이 수행 중인지 좀 더 쉽게 알 수 있다.
> source("run_tests.R")
fibonacci series : .....
에러가 발생하는 경우의 출력을 살펴보기 위해 일부러 expect_equal(0, fibo(5))를 recursion test에 추가해 다시 run_tests.R을 실행해보자.
> source("run_tests.R")
fibonacci series : .....1
1. Failure: recursion test -----------------------------------------------------
0 not equal to fibo(5)
Mean relative difference: 1
위 실행 결과를 보면 fibonacci series 테스트 수행 중 recursion test에서 에러가 발생했고, fibo(5)의 반환 값이 0이 아님을 알 수 있다.