Nothing
#===============================================================================
# Test: quick_anova()
# File: test-quick_anova.R
# Description: Unit tests for the quick_anova() function
#===============================================================================
#------------------------------------------------------------------------------
# Setup: Create test data
#------------------------------------------------------------------------------
# Set seed for reproducibility
set.seed(123)
# Normal distribution, 3 groups (for standard ANOVA)
test_data_normal <- data.frame(
group = rep(c("A", "B", "C"), each = 25),
value = c(rnorm(25, mean = 10, sd = 2),
rnorm(25, mean = 12, sd = 2),
rnorm(25, mean = 14, sd = 2)),
stringsAsFactors = FALSE
)
# Unequal variances, 3 groups (for Welch ANOVA)
test_data_unequal_var <- data.frame(
group = rep(c("X", "Y", "Z"), each = 20),
value = c(rnorm(20, mean = 10, sd = 1),
rnorm(20, mean = 12, sd = 3),
rnorm(20, mean = 15, sd = 5)),
stringsAsFactors = FALSE
)
# Skewed data, 4 groups (for Kruskal-Wallis)
test_data_skewed <- data.frame(
treatment = rep(c("T1", "T2", "T3", "T4"), each = 20),
score = c(rexp(20, 1), rexp(20, 1.5), rexp(20, 2), rexp(20, 2.5)),
stringsAsFactors = FALSE
)
# Small sample data
test_data_small <- data.frame(
group = rep(c("Low", "Medium", "High"), each = 5),
response = c(rnorm(5, 5, 1), rnorm(5, 6, 1), rnorm(5, 7, 1)),
stringsAsFactors = FALSE
)
# Data with NA values
test_data_na <- test_data_normal
test_data_na$value[1:3] <- NA
# Two groups only (should work but suggest using quick_ttest)
test_data_two_groups <- data.frame(
group = rep(c("Control", "Treatment"), each = 20),
value = c(rnorm(20, 10, 2), rnorm(20, 12, 2)),
stringsAsFactors = FALSE
)
#------------------------------------------------------------------------------
# Basic Functionality Tests
#------------------------------------------------------------------------------
test_that("quick_anova() creates a quick_anova_result object", {
result <- quick_anova(test_data_normal,
group = group,
value = value,
verbose = FALSE)
expect_s3_class(result, "quick_anova_result")
})
test_that("quick_anova() performs standard one-way ANOVA", {
result <- quick_anova(test_data_normal,
group = group,
value = value,
method = "anova",
verbose = FALSE)
expect_equal(result$method_used, "anova")
expect_true(!is.null(result$omnibus_result))
expect_true("p_value" %in% names(result$omnibus_result))
})
test_that("quick_anova() performs Welch ANOVA", {
result <- quick_anova(test_data_unequal_var,
group = group,
value = value,
method = "welch",
verbose = FALSE)
expect_equal(result$method_used, "welch")
expect_true(!is.null(result$omnibus_result))
expect_true("p_value" %in% names(result$omnibus_result))
})
test_that("quick_anova() performs Kruskal-Wallis test", {
result <- quick_anova(test_data_skewed,
group = treatment,
value = score,
method = "kruskal",
verbose = FALSE)
expect_equal(result$method_used, "kruskal")
expect_true(!is.null(result$omnibus_result))
expect_true("p_value" %in% names(result$omnibus_result))
})
test_that("quick_anova() auto-selects appropriate method", {
# Normal data with equal variances should select ANOVA
result_normal <- quick_anova(test_data_normal,
group = group,
value = value,
method = "auto",
verbose = FALSE)
expect_true(result_normal$method_used %in% c("anova", "welch"))
})
test_that("quick_anova() creates ggplot object", {
result <- quick_anova(test_data_normal,
group = group,
value = value,
verbose = FALSE)
expect_s3_class(result$plot, "ggplot")
})
#------------------------------------------------------------------------------
# Parameter Validation Tests
#------------------------------------------------------------------------------
test_that("quick_anova() validates data parameter", {
expect_error(quick_anova(NULL, group = group, value = value),
"`data` must be a data frame")
expect_error(quick_anova(list(a = 1), group = group, value = value),
"`data` must be a data frame")
})
test_that("quick_anova() validates conf.level parameter", {
expect_error(quick_anova(test_data_normal, group = group, value = value,
conf.level = 1.5),
"`conf.level` must be between 0 and 1")
expect_error(quick_anova(test_data_normal, group = group, value = value,
conf.level = -0.5),
"`conf.level` must be between 0 and 1")
})
test_that("quick_anova() validates add_jitter parameter", {
expect_error(quick_anova(test_data_normal, group = group, value = value,
add_jitter = "yes"),
"`add_jitter` must be TRUE or FALSE")
})
test_that("quick_anova() validates show_p_value parameter", {
expect_error(quick_anova(test_data_normal, group = group, value = value,
show_p_value = "yes"),
"`show_p_value` must be TRUE or FALSE")
})
test_that("quick_anova() validates verbose parameter", {
expect_error(quick_anova(test_data_normal, group = group, value = value,
verbose = "yes"),
"`verbose` must be TRUE or FALSE")
})
test_that("quick_anova() validates column names", {
expect_error(quick_anova(test_data_normal,
group = nonexistent,
value = value,
verbose = FALSE),
"not found")
expect_error(quick_anova(test_data_normal,
group = group,
value = nonexistent,
verbose = FALSE),
"not found")
})
test_that("quick_anova() validates value is numeric", {
bad_data <- test_data_normal
bad_data$value <- as.character(bad_data$value)
expect_error(quick_anova(bad_data, group = group, value = value,
verbose = FALSE),
"must be numeric")
})
test_that("quick_anova() requires at least 2 groups", {
single_group_data <- data.frame(
group = rep("A", 20),
value = rnorm(20)
)
expect_error(quick_anova(single_group_data, group = group, value = value,
verbose = FALSE),
"requires at least 2 groups")
})
test_that("quick_anova() works with exactly 2 groups", {
result <- quick_anova(test_data_two_groups,
group = group,
value = value,
verbose = FALSE)
expect_s3_class(result, "quick_anova_result")
})
#------------------------------------------------------------------------------
# Post-hoc Tests Validation
#------------------------------------------------------------------------------
test_that("quick_anova() performs Tukey HSD post-hoc after ANOVA", {
result <- quick_anova(test_data_normal,
group = group,
value = value,
method = "anova",
post_hoc = "tukey",
verbose = FALSE)
expect_true(!is.null(result$post_hoc))
expect_equal(result$post_hoc$method, "tukey")
})
test_that("quick_anova() performs Welch post-hoc after Welch ANOVA", {
result <- quick_anova(test_data_unequal_var,
group = group,
value = value,
method = "welch",
post_hoc = "welch",
verbose = FALSE)
expect_true(!is.null(result$post_hoc))
expect_equal(result$post_hoc$method, "welch")
})
test_that("quick_anova() performs Wilcoxon post-hoc after Kruskal-Wallis", {
result <- quick_anova(test_data_skewed,
group = treatment,
value = score,
method = "kruskal",
post_hoc = "wilcox",
verbose = FALSE)
expect_true(!is.null(result$post_hoc))
expect_equal(result$post_hoc$method, "wilcox")
})
test_that("quick_anova() auto-selects appropriate post-hoc test", {
result <- quick_anova(test_data_normal,
group = group,
value = value,
method = "anova",
post_hoc = "auto",
verbose = FALSE)
expect_true(!is.null(result$post_hoc))
})
test_that("quick_anova() skips post-hoc when post_hoc = 'none'", {
result <- quick_anova(test_data_normal,
group = group,
value = value,
method = "anova",
post_hoc = "none",
verbose = FALSE)
expect_true(is.null(result$post_hoc))
})
#------------------------------------------------------------------------------
# Statistical Tests Validation
#------------------------------------------------------------------------------
test_that("quick_anova() performs normality checks", {
result <- quick_anova(test_data_normal,
group = group,
value = value,
method = "auto",
verbose = FALSE)
expect_true(!is.null(result$assumption_checks$normality))
expect_true("recommendation" %in% names(result$assumption_checks$normality))
})
test_that("quick_anova() checks variance equality for ANOVA", {
result <- quick_anova(test_data_normal,
group = group,
value = value,
method = "anova",
verbose = FALSE)
# Should have variance test if method is ANOVA and auto decision was made
expect_true(is.null(result$assumption_checks$variance) ||
!is.null(result$assumption_checks$variance))
})
test_that("quick_anova() handles method = 'auto' correctly", {
# For normal data, should choose parametric method
result <- quick_anova(test_data_normal,
group = group,
value = value,
method = "auto",
verbose = FALSE)
expect_true(result$method_used %in% c("anova", "welch"))
# For skewed data, should choose Kruskal-Wallis
result_skewed <- quick_anova(test_data_skewed,
group = treatment,
value = score,
method = "auto",
verbose = FALSE)
expect_true(result_skewed$method_used %in% c("anova", "welch", "kruskal"))
})
#------------------------------------------------------------------------------
# Plot Customization Tests
#------------------------------------------------------------------------------
test_that("quick_anova() supports different plot types", {
result_box <- quick_anova(test_data_normal, group = group, value = value,
plot_type = "boxplot", verbose = FALSE)
expect_s3_class(result_box$plot, "ggplot")
result_violin <- quick_anova(test_data_normal, group = group, value = value,
plot_type = "violin", verbose = FALSE)
expect_s3_class(result_violin$plot, "ggplot")
result_both <- quick_anova(test_data_normal, group = group, value = value,
plot_type = "both", verbose = FALSE)
expect_s3_class(result_both$plot, "ggplot")
})
test_that("quick_anova() supports jitter customization", {
result_no_jitter <- quick_anova(test_data_normal, group = group, value = value,
add_jitter = FALSE, verbose = FALSE)
expect_s3_class(result_no_jitter$plot, "ggplot")
result_custom <- quick_anova(test_data_normal, group = group, value = value,
add_jitter = TRUE, point_size = 3,
point_alpha = 0.8, verbose = FALSE)
expect_s3_class(result_custom$plot, "ggplot")
})
test_that("quick_anova() supports p-value label formats", {
result_stars <- quick_anova(test_data_normal, group = group, value = value,
p_label = "p.signif", verbose = FALSE)
expect_s3_class(result_stars$plot, "ggplot")
result_numeric <- quick_anova(test_data_normal, group = group, value = value,
p_label = "p.format", verbose = FALSE)
expect_s3_class(result_numeric$plot, "ggplot")
})
test_that("quick_anova() supports hiding p-value", {
result <- quick_anova(test_data_normal, group = group, value = value,
show_p_value = FALSE, verbose = FALSE)
expect_s3_class(result$plot, "ggplot")
})
test_that("quick_anova() accepts palette parameter", {
result <- quick_anova(test_data_normal, group = group, value = value,
palette = "qual_bold", verbose = FALSE)
expect_s3_class(result$plot, "ggplot")
})
test_that("quick_anova() accepts NULL palette", {
result <- quick_anova(test_data_normal, group = group, value = value,
palette = NULL, verbose = FALSE)
expect_s3_class(result$plot, "ggplot")
})
#------------------------------------------------------------------------------
# Return Object Structure Tests
#------------------------------------------------------------------------------
test_that("quick_anova() returns object with required components", {
result <- quick_anova(test_data_normal, group = group, value = value,
verbose = FALSE)
expect_true("plot" %in% names(result))
expect_true("omnibus_result" %in% names(result))
expect_true("post_hoc" %in% names(result))
expect_true("method_used" %in% names(result))
expect_true("descriptive_stats" %in% names(result))
expect_true("assumption_checks" %in% names(result))
expect_true("auto_decision" %in% names(result))
expect_true("timestamp" %in% names(result))
expect_true("parameters" %in% names(result))
})
test_that("quick_anova() result contains descriptive statistics", {
result <- quick_anova(test_data_normal, group = group, value = value,
verbose = FALSE)
expect_s3_class(result$descriptive_stats, "data.frame")
expect_true("n" %in% names(result$descriptive_stats))
expect_true("mean" %in% names(result$descriptive_stats))
expect_true("sd" %in% names(result$descriptive_stats))
expect_true("median" %in% names(result$descriptive_stats))
})
test_that("quick_anova() stores parameters correctly", {
result <- quick_anova(test_data_normal,
group = group,
value = value,
method = "anova",
post_hoc = "tukey",
conf.level = 0.95,
plot_type = "boxplot",
verbose = FALSE)
expect_equal(result$parameters$method, "anova")
expect_equal(result$parameters$post_hoc, "tukey")
expect_equal(result$parameters$conf.level, 0.95)
expect_equal(result$parameters$plot_type, "boxplot")
})
#------------------------------------------------------------------------------
# Edge Cases and Special Scenarios
#------------------------------------------------------------------------------
test_that("quick_anova() handles small samples", {
result <- quick_anova(test_data_small, group = group, value = response,
verbose = FALSE)
expect_s3_class(result, "quick_anova_result")
})
test_that("quick_anova() handles data with NA values", {
result <- quick_anova(test_data_na, group = group, value = value,
verbose = FALSE)
expect_s3_class(result, "quick_anova_result")
# Check that rows with NA were removed
expect_true(nrow(result$descriptive_stats) == 3)
})
test_that("quick_anova() handles different confidence levels", {
result_90 <- quick_anova(test_data_normal,
group = group,
value = value,
conf.level = 0.90,
verbose = FALSE)
expect_equal(result_90$parameters$conf.level, 0.90)
result_99 <- quick_anova(test_data_normal,
group = group,
value = value,
conf.level = 0.99,
verbose = FALSE)
expect_equal(result_99$parameters$conf.level, 0.99)
})
test_that("quick_anova() handles unbalanced sample sizes", {
unbalanced_data <- data.frame(
group = c(rep("A", 10), rep("B", 20), rep("C", 30)),
value = rnorm(60)
)
result <- quick_anova(unbalanced_data, group = group, value = value,
verbose = FALSE)
expect_s3_class(result, "quick_anova_result")
# Check descriptive stats show different sample sizes
expect_true(length(unique(result$descriptive_stats$n)) > 1)
})
test_that("quick_anova() handles 4+ groups", {
many_groups_data <- data.frame(
group = rep(c("A", "B", "C", "D", "E"), each = 15),
value = c(rnorm(15, 10, 2), rnorm(15, 11, 2), rnorm(15, 12, 2),
rnorm(15, 13, 2), rnorm(15, 14, 2))
)
result <- quick_anova(many_groups_data, group = group, value = value,
verbose = FALSE)
expect_s3_class(result, "quick_anova_result")
expect_equal(nrow(result$descriptive_stats), 5)
})
test_that("quick_anova() p-value is within valid range", {
result <- quick_anova(test_data_normal, group = group, value = value,
verbose = FALSE)
expect_true(result$omnibus_result$p_value >= 0)
expect_true(result$omnibus_result$p_value <= 1)
})
#------------------------------------------------------------------------------
# S3 Methods Tests
#------------------------------------------------------------------------------
test_that("print.quick_anova_result works", {
result <- quick_anova(test_data_normal, group = group, value = value,
verbose = FALSE)
# print method displays plot and descriptive stats
expect_output(print(result), "Method:|group|value")
})
test_that("summary.quick_anova_result works", {
result <- quick_anova(test_data_normal, group = group, value = value,
verbose = FALSE)
# summary should produce output - just check it runs without error
expect_output(summary(result))
})
test_that("quick_anova_result contains plot", {
result <- quick_anova(test_data_normal, group = group, value = value,
verbose = FALSE)
# Result should contain a ggplot object
expect_s3_class(result$plot, "ggplot")
})
#------------------------------------------------------------------------------
# Verbose Mode Tests
#------------------------------------------------------------------------------
test_that("quick_anova() prints messages when verbose = TRUE", {
# Function should produce diagnostic messages when verbose = TRUE
result <- quick_anova(test_data_normal, group = group, value = value,
verbose = TRUE)
# Just verify the result is created - verbose messages are visible in test output
expect_s3_class(result, "quick_anova_result")
})
test_that("quick_anova() minimizes output when verbose = FALSE", {
# verbose = FALSE should minimize output
result <- quick_anova(test_data_normal, group = group, value = value,
verbose = FALSE)
# Just check the result is created successfully
expect_s3_class(result, "quick_anova_result")
})
#------------------------------------------------------------------------------
# Integration Tests
#------------------------------------------------------------------------------
test_that("quick_anova() end-to-end workflow for ANOVA", {
result <- quick_anova(
data = test_data_normal,
group = group,
value = value,
method = "anova",
post_hoc = "tukey",
plot_type = "boxplot",
add_jitter = TRUE,
show_p_value = TRUE,
p_label = "p.signif",
palette = "qual_vivid",
verbose = FALSE
)
expect_s3_class(result, "quick_anova_result")
expect_s3_class(result$plot, "ggplot")
expect_equal(result$method_used, "anova")
expect_true(!is.null(result$post_hoc))
expect_true(result$omnibus_result$p_value >= 0 && result$omnibus_result$p_value <= 1)
})
test_that("quick_anova() end-to-end workflow for Welch ANOVA", {
result <- quick_anova(
data = test_data_unequal_var,
group = group,
value = value,
method = "welch",
post_hoc = "welch",
plot_type = "violin",
show_p_value = TRUE,
p_label = "p.format",
verbose = FALSE
)
expect_s3_class(result, "quick_anova_result")
expect_s3_class(result$plot, "ggplot")
expect_equal(result$method_used, "welch")
expect_true(!is.null(result$post_hoc))
expect_true(result$omnibus_result$p_value >= 0 && result$omnibus_result$p_value <= 1)
})
test_that("quick_anova() end-to-end workflow for Kruskal-Wallis", {
result <- quick_anova(
data = test_data_skewed,
group = treatment,
value = score,
method = "kruskal",
post_hoc = "wilcox",
plot_type = "both",
show_p_value = TRUE,
verbose = FALSE
)
expect_s3_class(result, "quick_anova_result")
expect_s3_class(result$plot, "ggplot")
expect_equal(result$method_used, "kruskal")
expect_true(!is.null(result$post_hoc))
expect_true(result$omnibus_result$p_value >= 0 && result$omnibus_result$p_value <= 1)
})
#===============================================================================
# End: test-quick_anova.R
#===============================================================================
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.