0Pricing
R Academy · Pelajaran

Pengujian Unit dengan testthat

Tulis blok test_that(), gunakan ekspektasi, dan jalankan pengujian dengan devtools::test().

Pengujian Unit dengan testthat adalah pelajaran R Academy gratis di CoddyKit. Ini adalah pelajaran 3 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar R Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus R Academy mencakup 4 pelajaran total.

Mengapa Melakukan Pengujian Unit?

Pengujian unit secara otomatis memverifikasi bahwa setiap fungsi berperilaku dengan benar. Pengujian ini menangkap regresi saat Anda mengubah kode, berfungsi sebagai dokumentasi yang dapat dijalankan, dan memberi Anda keyakinan untuk melakukan refaktor dengan aman. Paket testthat adalah kerangka pengujian standar untuk paket R.

Menyiapkan testthat

usethis::use_testthat() menambahkan testthat ke Suggests dalam DESCRIPTION, membuat tests/testthat/, dan membuat skrip pelaksana tests/testthat.R. Jalankan sekali saat menginisialisasi paket baru.

# 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

Membuat File Pengujian

usethis::use_test('add') membuat tests/testthat/test-add.R. Berdasarkan konvensi, file pengujian diberi nama test-{function_name}.R. Setiap file mengelompokkan pengujian untuk satu fungsi atau fitur.

# 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)
# })

Struktur test_that()

test_that('description', { ... }) mengelompokkan ekspektasi yang saling terkait. String deskripsi sebaiknya melengkapi kalimat 'test that ...' dan cukup spesifik agar berguna dalam pesan kegagalan.

# 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() dan expect_identical()

expect_equal(actual, expected) melakukan pengujian dengan toleransi numerik untuk bilangan titik mengambang. expect_identical(actual, expected) memerlukan kesamaan persis, termasuk tipe. Untuk sebagian besar kasus, expect_equal() lebih disarankan.

# 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() dan expect_warning()

Uji apakah fungsi menghasilkan error dan peringatan yang benar. Berikan pola regex untuk mencocokkan pesan error — ini memastikan error yang tepat dihasilkan, bukan sembarang 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() dan expect_false()

expect_true(expr) dan expect_false(expr) menguji kondisi logika. Gunakan keduanya saat menguji predikat atau kondisi yang menghasilkan satu nilai logika.

# 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)
# })

Fungsi Ekspektasi Lainnya

testthat menyediakan banyak fungsi ekspektasi untuk berbagai skenario:

  • expect_length(x, n) — memeriksa panjang vektor
  • expect_type(x, 'double') — memeriksa tipe dasar
  • expect_s3_class(x, 'data.frame') — memeriksa kelas S3
  • expect_null(x) — memeriksa apakah nilainya NULL
  • expect_match(string, regexp) — memeriksa pola string
# 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')
# })

Menjalankan Pengujian dengan devtools::test()

devtools::test() (Ctrl+Shift+T) menjalankan semua file pengujian dan menampilkan ringkasan pengujian yang berhasil, gagal, serta peringatan. Kegagalan pengujian individual menampilkan ekspektasi yang gagal serta nilai aktual dibandingkan nilai yang diharapkan.

# 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 ]

Cakupan Pengujian dengan covr

covr::package_coverage() mengukur persentase baris dalam paket Anda yang dijalankan oleh pengujian. covr::report() membuka laporan HTML yang menampilkan baris yang tercakup (hijau) dan tidak tercakup (merah). Usahakan cakupan setidaknya 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

Menguji Kasus Batas

Pengujian yang baik tidak hanya mencakup jalur normal, tetapi juga kasus batas:

  • Input kosong: numeric(0), character(0)
  • Input NA: apakah fungsi meneruskan atau menangani NA?
  • Input dengan panjang 1 dibandingkan input dengan panjang n
  • Nilai batas: 0, bilangan negatif, nilai yang sangat besar
  • Tipe yang salah: apa yang terjadi ketika pengguna memberikan string kepada fungsi numerik?
# 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)
# })

Pemeriksaan Singkat: expect_error()

Anda memanggil expect_error(my_fn('bad'), regexp = 'invalid input'). Apa yang diverifikasi oleh pengujian ini?

Rangkuman Pengujian Unit

Menguji paket R dengan testthat:

  • usethis::use_testthat() — menyiapkan infrastruktur pengujian sekali saja
  • usethis::use_test('fn') — membuat tests/testthat/test-fn.R
  • test_that('description', {...}) — mengelompokkan ekspektasi yang berkaitan
  • expect_equal(), expect_error(), expect_warning(), expect_true(), expect_false() — fungsi inti untuk ekspektasi
  • devtools::test() — menjalankan semua pengujian (Ctrl+Shift+T)
  • covr::package_coverage() — mengukur cakupan pengujian

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Pengujian Unit dengan testthat” gratis?

Ya — teks lengkap “Pengujian Unit dengan testthat” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus R Academy, upgrade ke CoddyKit PRO. Kursus R Academy mencakup 4 pelajaran total.

Apa yang akan aku pelajari di “Pengujian Unit dengan testthat”?

Tulis blok test_that(), gunakan ekspektasi, dan jalankan pengujian dengan devtools::test(). Kamu berlatih R Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai R Academy?

Tidak diperlukan pengalaman sebelumnya. R Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 3 dari 4.

Berapa lama pelajaran “Pengujian Unit dengan testthat” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran R Academy ini?

Ya. Setiap pelajaran R Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. Struktur Paket dengan usethis dan devtools
  2. Mendokumentasikan Fungsi dengan roxygen2
  3. Pengujian Unit dengan testthat
  4. Pengiriman ke CRAN dan Pemeliharaan Paket
← Kembali ke R Academy