diff --git a/R-package/tests/testthat/test_basic.R b/R-package/tests/testthat/test_basic.R index 4420c9105..e052499dd 100644 --- a/R-package/tests/testthat/test_basic.R +++ b/R-package/tests/testthat/test_basic.R @@ -1,6 +1,3 @@ -require(xgboost) -library(Matrix) - context("basic functions") data(agaricus.train, package = 'xgboost') diff --git a/R-package/tests/testthat/test_callbacks.R b/R-package/tests/testthat/test_callbacks.R index 69894bd05..6540ef0b3 100644 --- a/R-package/tests/testthat/test_callbacks.R +++ b/R-package/tests/testthat/test_callbacks.R @@ -1,9 +1,4 @@ # More specific testing of callbacks - -require(xgboost) -require(data.table) -require(titanic) - context("callbacks") data(agaricus.train, package = 'xgboost') @@ -84,7 +79,7 @@ test_that("cb.evaluation.log works as expected", { list(c(iter = 1, bst_evaluation), c(iter = 2, bst_evaluation))) expect_silent(f(finalize = TRUE)) expect_equal(evaluation_log, - data.table(iter = 1:2, train_auc = c(0.9, 0.9), test_auc = c(0.8, 0.8))) + data.table::data.table(iter = 1:2, train_auc = c(0.9, 0.9), test_auc = c(0.8, 0.8))) bst_evaluation_err <- c('train-auc' = 0.1, 'test-auc' = 0.2) evaluation_log <- list() @@ -101,7 +96,7 @@ test_that("cb.evaluation.log works as expected", { c(iter = 2, c(bst_evaluation, bst_evaluation_err)))) expect_silent(f(finalize = TRUE)) expect_equal(evaluation_log, - data.table(iter = 1:2, + data.table::data.table(iter = 1:2, train_auc_mean = c(0.9, 0.9), train_auc_std = c(0.1, 0.1), test_auc_mean = c(0.8, 0.8), test_auc_std = c(0.2, 0.2))) }) @@ -256,6 +251,9 @@ test_that("early stopping using a specific metric works", { }) test_that("early stopping works with titanic", { + if (!requireNamespace("titanic")) { + testthat::skip("Optional testing dependency 'titanic' not found.") + } # This test was inspired by https://github.com/dmlc/xgboost/issues/5935 # It catches possible issues on noLD R titanic <- titanic::titanic_train diff --git a/R-package/tests/testthat/test_custom_objective.R b/R-package/tests/testthat/test_custom_objective.R index d98e7045a..95be4140f 100644 --- a/R-package/tests/testthat/test_custom_objective.R +++ b/R-package/tests/testthat/test_custom_objective.R @@ -1,7 +1,5 @@ context('Test models with custom objective') -require(xgboost) - set.seed(1994) data(agaricus.train, package = 'xgboost') diff --git a/R-package/tests/testthat/test_dmatrix.R b/R-package/tests/testthat/test_dmatrix.R index 74d172f69..3c922e9a0 100644 --- a/R-package/tests/testthat/test_dmatrix.R +++ b/R-package/tests/testthat/test_dmatrix.R @@ -1,6 +1,3 @@ -require(xgboost) -require(Matrix) - context("testing xgb.DMatrix functionality") data(agaricus.test, package = 'xgboost') @@ -123,7 +120,7 @@ test_that("xgb.DMatrix: colnames", { test_that("xgb.DMatrix: nrow is correct for a very sparse matrix", { set.seed(123) nr <- 1000 - x <- rsparsematrix(nr, 100, density = 0.0005) + x <- Matrix::rsparsematrix(nr, 100, density = 0.0005) # we want it very sparse, so that last rows are empty expect_lt(max(x@i), nr) dtest <- xgb.DMatrix(x) diff --git a/R-package/tests/testthat/test_feature_weights.R b/R-package/tests/testthat/test_feature_weights.R index 580f58456..bb3802979 100644 --- a/R-package/tests/testthat/test_feature_weights.R +++ b/R-package/tests/testthat/test_feature_weights.R @@ -1,5 +1,3 @@ -library(xgboost) - context("feature weights") test_that("training with feature weights works", { diff --git a/R-package/tests/testthat/test_gc_safety.R b/R-package/tests/testthat/test_gc_safety.R index fb80757c5..f77af1eab 100644 --- a/R-package/tests/testthat/test_gc_safety.R +++ b/R-package/tests/testthat/test_gc_safety.R @@ -1,5 +1,3 @@ -require(xgboost) - context("Garbage Collection Safety Check") test_that("train and prediction when gctorture is on", { diff --git a/R-package/tests/testthat/test_glm.R b/R-package/tests/testthat/test_glm.R index 270267a0f..2d050945a 100644 --- a/R-package/tests/testthat/test_glm.R +++ b/R-package/tests/testthat/test_glm.R @@ -1,7 +1,5 @@ context('Test generalized linear models') -require(xgboost) - test_that("gblinear works", { data(agaricus.train, package = 'xgboost') data(agaricus.test, package = 'xgboost') diff --git a/R-package/tests/testthat/test_helpers.R b/R-package/tests/testthat/test_helpers.R index 2eab5624f..01436f48a 100644 --- a/R-package/tests/testthat/test_helpers.R +++ b/R-package/tests/testthat/test_helpers.R @@ -1,10 +1,11 @@ -library(testthat) context('Test helper functions') -require(xgboost) -require(data.table) -require(Matrix) -require(vcd, quietly = TRUE) +VCD_AVAILABLE <- requireNamespace("vcd", quietly = TRUE) +.skip_if_vcd_not_available <- function() { + if (!VCD_AVAILABLE) { + testthat::skip("Optional testing dependency 'vcd' not found.") + } +} float_tolerance <- 5e-6 @@ -12,25 +13,28 @@ float_tolerance <- 5e-6 flag_32bit <- .Machine$sizeof.pointer != 8 set.seed(1982) -data(Arthritis) -df <- data.table(Arthritis, keep.rownames = FALSE) -df[, AgeDiscret := as.factor(round(Age / 10, 0))] -df[, AgeCat := as.factor(ifelse(Age > 30, "Old", "Young"))] -df[, ID := NULL] -sparse_matrix <- sparse.model.matrix(Improved~.-1, data = df) # nolint -label <- df[, ifelse(Improved == "Marked", 1, 0)] -# binary nrounds <- 12 -bst.Tree <- xgboost(data = sparse_matrix, label = label, max_depth = 9, - eta = 1, nthread = 2, nrounds = nrounds, verbose = 0, - objective = "binary:logistic", booster = "gbtree") +if (isTRUE(VCD_AVAILABLE)) { + data(Arthritis, package = "vcd") + df <- data.table::data.table(Arthritis, keep.rownames = FALSE) + df[, AgeDiscret := as.factor(round(Age / 10, 0))] + df[, AgeCat := as.factor(ifelse(Age > 30, "Old", "Young"))] + df[, ID := NULL] + sparse_matrix <- Matrix::sparse.model.matrix(Improved~.-1, data = df) # nolint + label <- df[, ifelse(Improved == "Marked", 1, 0)] -bst.GLM <- xgboost(data = sparse_matrix, label = label, - eta = 1, nthread = 1, nrounds = nrounds, verbose = 0, - objective = "binary:logistic", booster = "gblinear") + # binary + bst.Tree <- xgboost(data = sparse_matrix, label = label, max_depth = 9, + eta = 1, nthread = 2, nrounds = nrounds, verbose = 0, + objective = "binary:logistic", booster = "gbtree") -feature.names <- colnames(sparse_matrix) + bst.GLM <- xgboost(data = sparse_matrix, label = label, + eta = 1, nthread = 1, nrounds = nrounds, verbose = 0, + objective = "binary:logistic", booster = "gblinear") + + feature.names <- colnames(sparse_matrix) +} # multiclass mlabel <- as.numeric(iris$Species) - 1 @@ -45,6 +49,7 @@ mbst.GLM <- xgboost(data = as.matrix(iris[, -5]), label = mlabel, verbose = 0, test_that("xgb.dump works", { + .skip_if_vcd_not_available() if (!flag_32bit) expect_length(xgb.dump(bst.Tree), 200) dump_file <- file.path(tempdir(), 'xgb.model.dump') @@ -60,6 +65,7 @@ test_that("xgb.dump works", { }) test_that("xgb.dump works for gblinear", { + .skip_if_vcd_not_available() expect_length(xgb.dump(bst.GLM), 14) # also make sure that it works properly for a sparse model where some coefficients # are 0 from setting large L1 regularization: @@ -76,6 +82,7 @@ test_that("xgb.dump works for gblinear", { }) test_that("predict leafs works", { + .skip_if_vcd_not_available() # no error for gbtree expect_error(pred_leaf <- predict(bst.Tree, sparse_matrix, predleaf = TRUE), regexp = NA) expect_equal(dim(pred_leaf), c(nrow(sparse_matrix), nrounds)) @@ -84,6 +91,7 @@ test_that("predict leafs works", { }) test_that("predict feature contributions works", { + .skip_if_vcd_not_available() # gbtree binary classifier expect_error(pred_contr <- predict(bst.Tree, sparse_matrix, predcontrib = TRUE), regexp = NA) expect_equal(dim(pred_contr), c(nrow(sparse_matrix), ncol(sparse_matrix) + 1)) @@ -187,6 +195,7 @@ test_that("SHAPs sum to predictions, with or without DART", { }) test_that("xgb-attribute functionality", { + .skip_if_vcd_not_available() val <- "my attribute value" list.val <- list(my_attr = val, a = 123, b = 'ok') list.ch <- list.val[order(names(list.val))] @@ -224,6 +233,7 @@ if (grepl('Windows', Sys.info()[['sysname']]) || grepl('Linux', Sys.info()[['sysname']]) || grepl('Darwin', Sys.info()[['sysname']])) { test_that("xgb-attribute numeric precision", { + .skip_if_vcd_not_available() # check that lossless conversion works with 17 digits # numeric -> character -> numeric X <- 10^runif(100, -20, 20) @@ -242,6 +252,7 @@ if (grepl('Windows', Sys.info()[['sysname']]) || } test_that("xgb.Booster serializing as R object works", { + .skip_if_vcd_not_available() saveRDS(bst.Tree, 'xgb.model.rds') bst <- readRDS('xgb.model.rds') dtrain <- xgb.DMatrix(sparse_matrix, label = label) @@ -260,6 +271,7 @@ test_that("xgb.Booster serializing as R object works", { }) test_that("xgb.model.dt.tree works with and without feature names", { + .skip_if_vcd_not_available() names.dt.trees <- c("Tree", "Node", "ID", "Feature", "Split", "Yes", "No", "Missing", "Quality", "Cover") dt.tree <- xgb.model.dt.tree(feature_names = feature.names, model = bst.Tree) expect_equal(names.dt.trees, names(dt.tree)) @@ -279,16 +291,18 @@ test_that("xgb.model.dt.tree works with and without feature names", { # using integer node ID instead of character dt.tree.int <- xgb.model.dt.tree(model = bst.Tree, use_int_id = TRUE) - expect_equal(as.integer(tstrsplit(dt.tree$Yes, '-')[[2]]), dt.tree.int$Yes) - expect_equal(as.integer(tstrsplit(dt.tree$No, '-')[[2]]), dt.tree.int$No) - expect_equal(as.integer(tstrsplit(dt.tree$Missing, '-')[[2]]), dt.tree.int$Missing) + expect_equal(as.integer(data.table::tstrsplit(dt.tree$Yes, '-')[[2]]), dt.tree.int$Yes) + expect_equal(as.integer(data.table::tstrsplit(dt.tree$No, '-')[[2]]), dt.tree.int$No) + expect_equal(as.integer(data.table::tstrsplit(dt.tree$Missing, '-')[[2]]), dt.tree.int$Missing) }) test_that("xgb.model.dt.tree throws error for gblinear", { + .skip_if_vcd_not_available() expect_error(xgb.model.dt.tree(model = bst.GLM)) }) test_that("xgb.importance works with and without feature names", { + .skip_if_vcd_not_available() importance.Tree <- xgb.importance(feature_names = feature.names, model = bst.Tree) if (!flag_32bit) expect_equal(dim(importance.Tree), c(7, 4)) @@ -354,6 +368,7 @@ test_that("xgb.importance works with and without feature names", { }) test_that("xgb.importance works with GLM model", { + .skip_if_vcd_not_available() importance.GLM <- xgb.importance(feature_names = feature.names, model = bst.GLM) expect_equal(dim(importance.GLM), c(10, 2)) expect_equal(colnames(importance.GLM), c("Feature", "Weight")) @@ -369,6 +384,7 @@ test_that("xgb.importance works with GLM model", { }) test_that("xgb.model.dt.tree and xgb.importance work with a single split model", { + .skip_if_vcd_not_available() bst1 <- xgboost(data = sparse_matrix, label = label, max_depth = 1, eta = 1, nthread = 2, nrounds = 1, verbose = 0, objective = "binary:logistic") @@ -380,16 +396,19 @@ test_that("xgb.model.dt.tree and xgb.importance work with a single split model", }) test_that("xgb.plot.tree works with and without feature names", { + .skip_if_vcd_not_available() expect_silent(xgb.plot.tree(feature_names = feature.names, model = bst.Tree)) expect_silent(xgb.plot.tree(model = bst.Tree)) }) test_that("xgb.plot.multi.trees works with and without feature names", { + .skip_if_vcd_not_available() xgb.plot.multi.trees(model = bst.Tree, feature_names = feature.names, features_keep = 3) xgb.plot.multi.trees(model = bst.Tree, features_keep = 3) }) test_that("xgb.plot.deepness works", { + .skip_if_vcd_not_available() d2p <- xgb.plot.deepness(model = bst.Tree) expect_equal(colnames(d2p), c("ID", "Tree", "Depth", "Cover", "Weight")) xgb.plot.deepness(model = bst.Tree, which = "med.depth") @@ -397,6 +416,7 @@ test_that("xgb.plot.deepness works", { }) test_that("xgb.shap.data works when top_n is provided", { + .skip_if_vcd_not_available() data_list <- xgb.shap.data(data = sparse_matrix, model = bst.Tree, top_n = 2) expect_equal(names(data_list), c("data", "shap_contrib")) expect_equal(NCOL(data_list$data), 2) @@ -414,12 +434,14 @@ test_that("xgb.shap.data works when top_n is provided", { }) test_that("xgb.shap.data works with subsampling", { + .skip_if_vcd_not_available() data_list <- xgb.shap.data(data = sparse_matrix, model = bst.Tree, top_n = 2, subsample = 0.8) expect_equal(NROW(data_list$data), as.integer(0.8 * nrow(sparse_matrix))) expect_equal(NROW(data_list$data), NROW(data_list$shap_contrib)) }) test_that("prepare.ggplot.shap.data works", { + .skip_if_vcd_not_available() data_list <- xgb.shap.data(data = sparse_matrix, model = bst.Tree, top_n = 2) plot_data <- prepare.ggplot.shap.data(data_list, normalize = TRUE) expect_s3_class(plot_data, "data.frame") @@ -430,11 +452,13 @@ test_that("prepare.ggplot.shap.data works", { }) test_that("xgb.plot.shap works", { + .skip_if_vcd_not_available() sh <- xgb.plot.shap(data = sparse_matrix, model = bst.Tree, top_n = 2, col = 4) expect_equal(names(sh), c("data", "shap_contrib")) }) test_that("xgb.plot.shap.summary works", { + .skip_if_vcd_not_available() expect_silent(xgb.plot.shap.summary(data = sparse_matrix, model = bst.Tree, top_n = 2)) expect_silent(xgb.ggplot.shap.summary(data = sparse_matrix, model = bst.Tree, top_n = 2)) }) diff --git a/R-package/tests/testthat/test_interactions.R b/R-package/tests/testthat/test_interactions.R index e90467cdc..a658fc81f 100644 --- a/R-package/tests/testthat/test_interactions.R +++ b/R-package/tests/testthat/test_interactions.R @@ -1,7 +1,5 @@ context('Test prediction of feature interactions') -require(xgboost) - set.seed(123) test_that("predict feature interactions works", { diff --git a/R-package/tests/testthat/test_io.R b/R-package/tests/testthat/test_io.R index 5b2bc4265..c2cb1a1a8 100644 --- a/R-package/tests/testthat/test_io.R +++ b/R-package/tests/testthat/test_io.R @@ -1,7 +1,4 @@ context("Test model IO.") -## some other tests are in test_basic.R -require(xgboost) -require(testthat) data(agaricus.train, package = "xgboost") data(agaricus.test, package = "xgboost") diff --git a/R-package/tests/testthat/test_model_compatibility.R b/R-package/tests/testthat/test_model_compatibility.R index 6a35ca4b3..cb8c432fa 100644 --- a/R-package/tests/testthat/test_model_compatibility.R +++ b/R-package/tests/testthat/test_model_compatibility.R @@ -1,6 +1,3 @@ -require(xgboost) -require(jsonlite) - context("Models from previous versions of XGBoost can be loaded") metadata <- list( diff --git a/R-package/tests/testthat/test_monotone.R b/R-package/tests/testthat/test_monotone.R index 756863061..cb5827698 100644 --- a/R-package/tests/testthat/test_monotone.R +++ b/R-package/tests/testthat/test_monotone.R @@ -1,5 +1,3 @@ -require(xgboost) - context("monotone constraints") set.seed(1024) diff --git a/R-package/tests/testthat/test_parameter_exposure.R b/R-package/tests/testthat/test_parameter_exposure.R index 86413174b..47524fbfc 100644 --- a/R-package/tests/testthat/test_parameter_exposure.R +++ b/R-package/tests/testthat/test_parameter_exposure.R @@ -1,7 +1,5 @@ context('Test model params and call are exposed to R') -require(xgboost) - data(agaricus.train, package = 'xgboost') data(agaricus.test, package = 'xgboost') diff --git a/R-package/tests/testthat/test_poisson_regression.R b/R-package/tests/testthat/test_poisson_regression.R index 4f3527cdb..b17c6c072 100644 --- a/R-package/tests/testthat/test_poisson_regression.R +++ b/R-package/tests/testthat/test_poisson_regression.R @@ -1,6 +1,5 @@ context('Test Poisson regression model') -require(xgboost) set.seed(1994) test_that("Poisson regression works", { diff --git a/R-package/tests/testthat/test_ranking.R b/R-package/tests/testthat/test_ranking.R index 7a352bea2..9e8d0156e 100644 --- a/R-package/tests/testthat/test_ranking.R +++ b/R-package/tests/testthat/test_ranking.R @@ -1,12 +1,12 @@ -require(xgboost) -require(Matrix) - context('Learning to rank') test_that('Test ranking with unweighted data', { - X <- sparseMatrix(i = c(2, 3, 7, 9, 12, 15, 17, 18), - j = c(1, 1, 2, 2, 3, 3, 4, 4), - x = rep(1.0, 8), dims = c(20, 4)) + X <- Matrix::sparseMatrix( + i = c(2, 3, 7, 9, 12, 15, 17, 18) + , j = c(1, 1, 2, 2, 3, 3, 4, 4) + , x = rep(1.0, 8) + , dims = c(20, 4) + ) y <- c(0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0) group <- c(5, 5, 5, 5) dtrain <- xgb.DMatrix(X, label = y, group = group) @@ -20,9 +20,12 @@ test_that('Test ranking with unweighted data', { }) test_that('Test ranking with weighted data', { - X <- sparseMatrix(i = c(2, 3, 7, 9, 12, 15, 17, 18), - j = c(1, 1, 2, 2, 3, 3, 4, 4), - x = rep(1.0, 8), dims = c(20, 4)) + X <- Matrix::sparseMatrix( + i = c(2, 3, 7, 9, 12, 15, 17, 18) + , j = c(1, 1, 2, 2, 3, 3, 4, 4) + , x = rep(1.0, 8) + , dims = c(20, 4) + ) y <- c(0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0) group <- c(5, 5, 5, 5) weight <- c(1.0, 2.0, 3.0, 4.0) diff --git a/R-package/tests/testthat/test_update.R b/R-package/tests/testthat/test_update.R index 541fdf68e..887ffeb06 100644 --- a/R-package/tests/testthat/test_update.R +++ b/R-package/tests/testthat/test_update.R @@ -1,5 +1,3 @@ -require(xgboost) - context("update trees in an existing model") data(agaricus.train, package = 'xgboost')