callthat
is meant for plumber
API developers who plan to distribute their APIs inside an R package. This package enables the testing of the API’s endpoints within the testthat
framework. This allows the R Checks to also confirm that the endpoints still behave as expected.
The ultimate goal of callthat
is to ensure that the package’s automated testing catches issues with the API even if the developer did not perform unit testing.
The development version from GitHub with:
# install.packages("devtools")
devtools::install_github("edgararuiz/callthat")
plumber
API in your packagePlace your API in the inst/plumber
folder of your package. That way plumber::available_apis("MyPakcageName")
can locate the APIs, after your package is installed.
In MyPakcageName/inst/plumber/sample-api
:
library(plumber)
#* Runs a prediction of the Weight
#* @get /predict
function(weight) {
wtg <- as.numeric(weight)
model <- stats::lm(mpg ~ wt, data = datasets::mtcars)
stats::predict(model, newdata = data.frame(wt = wtg))
}
testthat
folderCreate the test using the same name as the name of the API. Add the prefix test-plumber
.
In MyPakcageName/tests/testthat/test-plumber-sample-api.R
:
test_that("Show how to use test", {
expect_silent({
# ------------- Start plumber API -------------------
local_api <- call_that_plumber_start(
system.file("plumber/sample-api", package = "MyPackageName")
)
# ------------- Start test session ------------------
api_session <- call_that_session_start(local_api)
})
expect_s3_class(
# ---------------- Make API call --------------------
get_predict <- call_that_api_get(
api_session,
endpoint = "predict",
query = list(weight = 1)
),
"response"
)
# ---------- Run tests against response ---------------
## Test to confirm that the response was a success
expect_equal(
get_predict$status_code,
200
)
## Test to confirm the output of the API is correct
expect_equal(
round(content(get_predict)[[1]]),
32
)
# ----- Close the session, and the plumber API --------
expect_null(
call_that_session_stop(api_session)
)
})
callthat
matches the API to the test by name. The call_that_available_tests()
returns a table with the available APIs in your package, and it displays if there is a matching test.
#> # A tibble: 1 x 4
#> api api_path test_exists test_path
#> <chr> <fs::path> <lgl> <fs::path>
#> 1 sample-api inst/plumber/sample-… TRUE inst/tests/test-plumber-sample-a…
callthat
makes it possible to run the exact same tests used for unit testing, for integration testing.
Open a connection with the published API. If that API is running in RStudio Connect, then use call_that_rsc_connection()
, otherwise use the generic call_that_connection()
.
published_api <- call_that_rsc_connection(
url = "https://colorado.rstudio.com/rsc/callthat/testapi",
key = Sys.getenv("RSC_TOKEN") # Optional, only if access to your API is restricted
)
published_api
#> RStudio Connect API: https://colorado.rstudio.com/rsc/callthat/testapi
#> API Key: XXXXXXXXXXXXXX
The call_that_test_remote()
functions runs the tests for the API, but it is possible to also pass the published API’s connection so that the tests run remotely.
call_that_test_remote("sample-api", published_api)
#> ✓ | OK F W S | Context
#> ✓ | 5 | plumber-sample-api
#>
#> ══ Results ═════════════════════════════════════════════════════════════════════
#> [ FAIL 0 | WARN 0 | SKIP 0 | PASS 5 ]