Discuss code-local testing
This commit is contained in:
parent
1002703a80
commit
80079f9c5d
@ -1,20 +1,15 @@
|
|||||||
# tocID <- "RPR-Unit_testing.R"
|
# tocID <- "RPR-Unit_testing.R"
|
||||||
#
|
#
|
||||||
# ---------------------------------------------------------------------------- #
|
|
||||||
# PATIENCE ... #
|
|
||||||
# Do not yet work wih this code. Updates in progress. Thank you. #
|
|
||||||
# boris.steipe@utoronto.ca #
|
|
||||||
# ---------------------------------------------------------------------------- #
|
|
||||||
#
|
|
||||||
# Purpose: A Bioinformatics Course:
|
# Purpose: A Bioinformatics Course:
|
||||||
# R code accompanying the RPR-Unit_testing unit.
|
# R code accompanying the RPR-Unit_testing unit.
|
||||||
#
|
#
|
||||||
# Version: 1.1
|
# Version: 1.2
|
||||||
#
|
#
|
||||||
# Date: 2017 10 - 2019 01
|
# Date: 2017 10 - 2019 01
|
||||||
# Author: Boris Steipe (boris.steipe@utoronto.ca)
|
# Author: Boris Steipe (boris.steipe@utoronto.ca)
|
||||||
#
|
#
|
||||||
# Versions:
|
# Versions:
|
||||||
|
# 1.2 2020 Updates. Discuss local tests.
|
||||||
# 1.1 Change from require() to requireNamespace()
|
# 1.1 Change from require() to requireNamespace()
|
||||||
# 1.0 New code
|
# 1.0 New code
|
||||||
#
|
#
|
||||||
@ -35,10 +30,11 @@
|
|||||||
#TOC>
|
#TOC>
|
||||||
#TOC> Section Title Line
|
#TOC> Section Title Line
|
||||||
#TOC> -------------------------------------------------
|
#TOC> -------------------------------------------------
|
||||||
#TOC> 1 Unit Tests with testthat 46
|
#TOC> 1 Unit Tests with testthat 42
|
||||||
#TOC> 2 Organizing your tests 165
|
#TOC> 2 Organizing your tests 165
|
||||||
#TOC> 2.1 Testing scripts 189
|
#TOC> 2.1 Testing scripts 189
|
||||||
#TOC> 3 Task solutions 204
|
#TOC> 2.2 Rethinking testing 202
|
||||||
|
#TOC> 3 Task solutions 220
|
||||||
#TOC>
|
#TOC>
|
||||||
#TOC> ==========================================================================
|
#TOC> ==========================================================================
|
||||||
|
|
||||||
@ -56,7 +52,7 @@ if (! requireNamespace("testthat", quietly = TRUE)) {
|
|||||||
# data(package = "testthat") # available datasets
|
# data(package = "testthat") # available datasets
|
||||||
|
|
||||||
# testthat is one of those packages that we either use A LOT in a script,
|
# testthat is one of those packages that we either use A LOT in a script,
|
||||||
# or not at all. Therfore it's more reasonable to depart from our usual
|
# or not at all. Therefore it's more reasonable to depart from our usual
|
||||||
# <package>::<function>() idiom, and load the entire library. In fact, if
|
# <package>::<function>() idiom, and load the entire library. In fact, if
|
||||||
# we author packages, it is common practice to load testthat in the part
|
# we author packages, it is common practice to load testthat in the part
|
||||||
# of the package that automates testing.
|
# of the package that automates testing.
|
||||||
@ -122,7 +118,8 @@ expect_error(log(v[1,2])) # This appears oK, but ...
|
|||||||
expect_error(log(v[1,2]), "non-numeric") # ... it's actually a different error!
|
expect_error(log(v[1,2]), "non-numeric") # ... it's actually a different error!
|
||||||
|
|
||||||
# Producing unit tests simply means: we define a function, and then we check
|
# Producing unit tests simply means: we define a function, and then we check
|
||||||
# whether all test pass. Consider a function that is loaded on startup:
|
# whether all test pass. Consider a function that is loaded on startup from
|
||||||
|
# the .utilities.R script:
|
||||||
|
|
||||||
biCode
|
biCode
|
||||||
|
|
||||||
@ -144,6 +141,9 @@ expect_error(biCode(), "argument \"s\" is missing, with no default")
|
|||||||
# test_that("<descriptive string>, {<code block>})
|
# test_that("<descriptive string>, {<code block>})
|
||||||
|
|
||||||
test_that("NA values are preserved", {
|
test_that("NA values are preserved", {
|
||||||
|
# bicode() respects vector length: input and output must have the smae length.
|
||||||
|
# Therefore NA's can't be simply skipped, bust must be properly passed
|
||||||
|
# into output:
|
||||||
expect_true(is.na((biCode(NA))))
|
expect_true(is.na((biCode(NA))))
|
||||||
expect_equal(biCode(c("first", NA, "last")),
|
expect_equal(biCode(c("first", NA, "last")),
|
||||||
c("FIRST", NA, "LAST."))
|
c("FIRST", NA, "LAST."))
|
||||||
@ -199,6 +199,22 @@ if (FALSE) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# == 2.2 Rethinking testing ================================================
|
||||||
|
|
||||||
|
# However, it is important to keep in mind that different objectives lead to
|
||||||
|
# different ideas of what works best. There is never a "best" in and of itself,
|
||||||
|
# the question is always: "Best for what?" While automated unit testing is a
|
||||||
|
# great way to assure the integrity of packages and larger software artefacts as
|
||||||
|
# they are being developed, more loosely conceived aggregates of code - like the
|
||||||
|
# scripts for this course for example - have different objectives and in this
|
||||||
|
# case I find the testthat approach to actually be inferior. The reason is its
|
||||||
|
# tendency to physically separate code and tests. Keeping assets, and functions
|
||||||
|
# that operate on those assets separated is always poor design. I have found
|
||||||
|
# over time that a more stable approach is to move individual functions into
|
||||||
|
# their individual scripts, all in one folder, one function (and its helpers)
|
||||||
|
# per file, and examples, demos and tests in an if (FALSE) { ... } block, as
|
||||||
|
# explained above.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# = 3 Task solutions ======================================================
|
# = 3 Task solutions ======================================================
|
||||||
|
Loading…
Reference in New Issue
Block a user