0Pricing
R Academy · 강의

testthat으로 단위 테스트하기

test_that() 블록을 작성하고 예상 조건을 사용하며 devtools::test()로 테스트를 실행합니다.

testthat으로 단위 테스트하기은(는) CoddyKit의 무료 R Academy 강의입니다. 이것은 4개 중 3번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 R Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. R Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

단위 테스트를 하는 이유

단위 tests는 개별 함수가 올바르게 작동하는지 자동으로 검증합니다. 코드를 변경했을 때 회귀를 찾아내고, 실행 가능한 문서 역할을 하며, 안전하게 리팩터링할 수 있다는 확신을 줍니다. testthat 패키지는 R 패키지의 표준 테스트 프레임워크입니다.

testthat 설정하기

usethis::use_testthat()는 DESCRIPTION의 Suggests에 testthat을 추가하고, tests/testthat/을 만들며, 실행기 스크립트 tests/testthat.R을 생성합니다. 새 패키지를 초기화할 때 한 번 실행하십시오.

# usethis::use_testthat()
#
# Creates:
# tests/
#   testthat.R                  <- runner (do not edit)
#   testthat/
#     (empty — write test files here)
#
# Updates DESCRIPTION:
# Suggests: testthat (>= 3.0.0)
# Config/testthat/edition: 3

테스트 file 만들기

usethis::use_test('add')는 tests/testthat/test-add.R을 만듭니다. 관례상 test file의 이름은 test-{function_name}.R로 지정합니다. 각 file에는 하나의 함수 또는 기능에 대한 tests를 모읍니다.

# usethis::use_test('add')  # creates tests/testthat/test-add.R
#
# Content of test-add.R:
# test_that('add() returns correct sum', {
#   expect_equal(add(1, 2), 3)
#   expect_equal(add(-1, 1), 0)
#   expect_equal(add(0.1, 0.2), 0.3, tolerance = 1e-7)
# })

test_that() 구조

test_that('description', { ... })는 서로 관련된 검증을 하나로 묶습니다. 설명 문자열은 'test that ...'이라는 문장을 완성해야 하며, 실패 메시지에서 유용하도록 충분히 구체적이어야 합니다.

# Good test_that descriptions:
# test_that('add() handles negative numbers', { ... })
# test_that('add() recycles length-1 vectors', { ... })
# test_that('add() returns NA when input contains NA', { ... })
#
# Bad (too vague):
# test_that('it works', { ... })
# test_that('test1', { ... })

expect_equal() 및 expect_identical()

expect_equal(actual, expected)은 부동소수점 값을 수치 허용 오차를 적용하여 테스트합니다. expect_identical(actual, expected)는 type을 포함한 완전히 동일한 값을 요구합니다. 대부분의 경우 expect_equal()이 더 적합합니다.

# test_that('add() adds correctly', {
#   expect_equal(add(1, 2), 3)            # numeric equality
#   expect_equal(add(0.1, 0.2), 0.3)     # tolerance handles floating point
#   expect_identical(add(1L, 2L), 3L)    # exact type match: integer
#   expect_identical(add(1.0, 2.0), 3.0) # exact type match: double
# })

expect_error() 및 expect_warning()

함수가 올바른 error와 warning을 발생시키는지 테스트하십시오. error 메시지와 일치하도록 정규식 패턴을 전달하면 아무 error가 아니라 올바른 error가 발생했는지 확인할 수 있습니다.

# test_that('add() validates input types', {
#   expect_error(
#     add('a', 2),
#     regexp = 'numeric'   # message must contain 'numeric'
#   )
#   expect_error(
#     add(NULL, 1),
#     regexp = 'numeric'
#   )
# })
#
# test_that('sqrt() warns on negative input', {
#   expect_warning(sqrt(-1))
# })

expect_true() 및 expect_false()

expect_true(expr)와 expect_false(expr)는 논리 조건을 테스트합니다. 하나의 논리 값으로 반환되는 predicate나 조건을 테스트할 때 사용하십시오.

# test_that('is_positive() returns correct logical', {
#   expect_true(is_positive(5))
#   expect_true(is_positive(0.001))
#   expect_false(is_positive(0))
#   expect_false(is_positive(-3))
# })
#
# # Also useful for vector tests:
# test_that('add() result has correct length', {
#   result <- add(c(1,2,3), c(4,5,6))
#   expect_true(length(result) == 3)
# })

그 밖의 검증 함수

testthat는 다양한 상황에 사용할 수 있는 여러 검증 함수를 제공합니다.

  • expect_length(x, n) — 벡터 길이 확인
  • expect_type(x, 'double') — 기본 type 확인
  • expect_s3_class(x, 'data.frame') — S3 class 확인
  • expect_null(x) — NULL인지 확인
  • expect_match(string, regexp) — 문자열 패턴 확인
# test_that('add() output has correct type and length', {
#   result <- add(c(1.0, 2.0), c(3.0, 4.0))
#   expect_type(result, 'double')
#   expect_length(result, 2)
# })
#
# test_that('summary_stats() returns a data frame', {
#   result <- summary_stats(rnorm(100))
#   expect_s3_class(result, 'data.frame')
# })

devtools::test()로 tests 실행하기

devtools::test()(Ctrl+Shift+T)는 모든 test file을 실행하고 통과, 실패, warning의 요약을 표시합니다. 개별 테스트 실패에는 실패한 검증과 실제 값 및 예상 값이 표시됩니다.

# devtools::test()
#
# Example output:
# == Testing mypackage ====================================
# v | OK F W S | Context
# v |  3       | add [0.1s]
# v |  4       | subtract [0.1s]
# x |  2 1     | multiply [0.2s]
# -- Failure (test-multiply.R:5): multiply() handles zero
# multiply(5, 0) not equal to 0.
# Actual:   5
# Expected: 0
# ==========================================================
# [ FAIL 1 | WARN 0 | SKIP 0 | PASS 9 ]

covr로 테스트 커버리지 확인하기

covr::package_coverage()는 tests가 패키지의 몇 퍼센트의 line을 실행하는지 측정합니다. covr::report()는 실행된 line(초록색)과 실행되지 않은 line(빨간색)을 보여 주는 HTML 보고서를 엽니다. 커버리지 80% 이상을 목표로 하십시오.

# library(covr)
# cov <- package_coverage()
# print(cov)
#
# Example output:
# mypackage Coverage: 87.50%
# R/add.R:      100.00%
# R/subtract.R: 100.00%
# R/utils.R:     62.50%  <- needs more tests!
#
# covr::report()  # interactive HTML report
# covr::zero_coverage(cov)  # list uncovered lines

경계 사례 테스트하기

좋은 tests는 정상적인 경로뿐 아니라 경계 사례도 다룹니다.

  • 빈 input: numeric(0), character(0)
  • NA input: 함수가 NA를 전파하는지 아니면 처리하는지 확인합니다
  • 길이가 1인 input과 길이가 n인 input
  • 경계 값: 0, 음수, 매우 큰 값
  • 잘못된 type: 사용자가 numeric 함수에 문자열을 전달하면 어떻게 되는지 확인합니다
# test_that('add() handles edge cases', {
#   expect_equal(add(numeric(0), numeric(0)), numeric(0))  # empty
#   expect_true(is.na(add(NA, 1)))                        # NA propagation
#   expect_equal(add(1, c(1,2,3)), c(2,3,4))              # recycling
#   expect_equal(add(.Machine$integer.max, 0L),           # boundary
#               .Machine$integer.max)
# })

빠른 확인: expect_error()

expect_error(my_fn('bad'), regexp = 'invalid input')을 호출합니다. 이 test는 무엇을 검증합니까?

단위 테스트 복습

testthat으로 R 패키지 테스트하기:

  • usethis::use_testthat() — 테스트 인프라를 한 번 설정합니다
  • usethis::use_test('fn') — tests/testthat/test-fn.R을 생성합니다
  • test_that('description', {...}) — 관련된 기대 조건을 하나로 묶습니다
  • expect_equal(), expect_error(), expect_warning(), expect_true(), expect_false() — 핵심 기대 조건 함수입니다
  • devtools::test() — 모든 테스트를 실행합니다(Ctrl+Shift+T)
  • covr::package_coverage() — 테스트 커버리지를 측정합니다

자주 묻는 질문

“testthat으로 단위 테스트하기” 강의는 무료인가요?

네 — “testthat으로 단위 테스트하기” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 R Academy 강의 전체를 잠금 해제할 수 있습니다. R Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

“testthat으로 단위 테스트하기”에서 뭘 배우나요?

test_that() 블록을 작성하고 예상 조건을 사용하며 devtools::test()로 테스트를 실행합니다. 브라우저에서 직접 실행하는 실습 코드로 R Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

R Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 R Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 3번째 강의입니다.

“testthat으로 단위 테스트하기” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 R Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 R Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. usethis와 devtools로 패키지 구조 만들기
  2. roxygen2로 함수 문서화
  3. testthat으로 단위 테스트하기
  4. CRAN 제출과 패키지 유지 관리
← R Academy(으)로 돌아가기