You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R语言使用testthat编写get_data_from_multiqc_star函数测试用例

R 环境使用 testthat 编写数据处理函数测试用例

测试覆盖核心目标

  • 验证输出字段完全符合预期,无多余字段、无缺失字段
  • 验证直接提取的字段(Sample、total_reads、uniquely_mapped、multimapped)数值和输入完全一致
  • 验证衍生计算字段(total_mapped、total_reads_post_trimming、frac_uniquely_mapped)的计算精度和结果正确性
  • 验证边界输入、异常输入下函数的表现符合预期

前置准备

先把依赖包和待测试函数加载到当前R环境:

library(dplyr)
library(testthat)

# 待测试的MultiQC STAR结果处理函数
get_data_from_multiqc_star <- function(df_multiqc_star){
  df <- df_multiqc_star %>%
    mutate(total_mapped = sum(uniquely_mapped, multimapped),
           total_reads_post_trimming  = total_reads,
           frac_uniquely_mapped = round((uniquely_mapped/total_mapped), 4)) %>%
    select(Sample,
           total_reads_post_trimming,
           uniquely_mapped,
           frac_uniquely_mapped,
           multimapped,
           total_mapped)
  return(df)
}

基础功能测试用例

首先构造数值完全已知的测试输入,手动计算好预期结果,再和函数输出做比对,避免逻辑偏差:

# 构造标准测试输入,额外加1个无关字段验证select逻辑是否生效
test_input <- tibble(
  Sample = c("sample1", "sample2", "sample3"),
  total_reads = c(1000000, 2000000, 1500000),
  uniquely_mapped = c(800000, 1700000, 1200000),
  multimapped = c(100000, 200000, 200000),
  extra_col = c(1,2,3)
)

# 按照当前函数逻辑手动计算预期输出
# 注意:当前函数sum()是对两列所有值全局求和,不是按行相加
global_total_mapped <- sum(test_input$uniquely_mapped, test_input$multimapped)
expected_res <- tibble(
  Sample = test_input$Sample,
  total_reads_post_trimming = test_input$total_reads,
  uniquely_mapped = test_input$uniquely_mapped,
  frac_uniquely_mapped = round(test_input$uniquely_mapped / global_total_mapped, 4),
  multimapped = test_input$multimapped,
  total_mapped = rep(global_total_mapped, nrow(test_input))
)

运行测试校验核心逻辑:

test_that("核心字段提取和计算逻辑正确", {
  output <- get_data_from_multiqc_star(test_input)
  
  # 校验输出格式为数据框
  expect_s3_class(output, "data.frame")
  # 校验输出字段名和顺序完全匹配要求
  expect_equal(
    colnames(output),
    c("Sample", "total_reads_post_trimming", "uniquely_mapped",
      "frac_uniquely_mapped", "multimapped", "total_mapped")
  )
  # 校验直接提取的字段数值完全一致
  expect_equal(output$Sample, expected_res$Sample)
  expect_equal(output$total_reads_post_trimming, expected_res$total_reads_post_trimming)
  expect_equal(output$uniquely_mapped, expected_res$uniquely_mapped)
  expect_equal(output$multimapped, expected_res$multimapped)
  # 校验衍生计算字段结果准确
  expect_equal(output$total_mapped, expected_res$total_mapped)
  expect_equal(output$frac_uniquely_mapped, expected_res$frac_uniquely_mapped)
})

补充测试场景

边界值测试

覆盖mapped reads为0的极端场景,确认函数不会意外崩溃:

test_that("0值边界输入运行正常", {
  edge_input <- tibble(
    Sample = "zero_mapped",
    total_reads = 500000,
    uniquely_mapped = 0,
    multimapped = 0
  )
  # 确认函数运行不报错
  expect_no_error(get_data_from_multiqc_star(edge_input))
  edge_output <- get_data_from_multiqc_star(edge_input)
  # 0除以0会返回NaN,若业务要求该场景返回0可后续调整函数逻辑
  expect_true(is.nan(edge_output$frac_uniquely_mapped))
})

异常输入测试

确认输入缺失必填字段时,函数会抛出错误而非返回无意义结果:

test_that("缺失必填字段时正常报错", {
  # 输入缺少uniquely_mapped字段
  bad_input <- tibble(
    Sample = "bad_sample",
    total_reads = 1000000,
    multimapped = 50000
  )
  expect_error(get_data_from_multiqc_star(bad_input))
})

提示:当前函数中total_mapped = sum(uniquely_mapped, multimapped)的写法是对全表两列数值做全局求和,如果实际需求是统计每个样本各自的总比对reads数,需要将该行修改为total_mapped = uniquely_mapped + multimapped,修改后同步调整测试用例里的预期计算逻辑即可。

内容的提问来源于stack exchange,提问作者Navidrn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 05:24:15