A docker container providing:
- a patched R interpreter/installation with builtin code coverage support.
- and also a normal (unpatched) R for easy comparison.
Both R installations share installed packages.
After the build:
- code coverage of the included testthat package:
make run-test
- run the patched interpreter interactive console:
make run
And don't forget to Star the project if you like it!
This project allows to build a docker container containing a patched version of the R interpreter which provides a new feature: code coverage.
N.B: You do no need to install it if you use it directly from the docker hub (recommended). These instructions are only provided for those willing to build the docker container from scratch.
It should work on all platforms supporting docker: cf https://docs.docker.com/installation/. The very first step is to install docker.
A unix-like terminal and GNU make.
git clone https://github.com/quartzbio/r-coverage.git
cd r-coverage
# choose the version to build
cd rxxx
# build the docker container: QUITE LONG
make build
The docker container contains two R versions:
- the normal one (unpatched), available as R and Rscript in the docker container
- the patched one, available, available as Rcov and Rscript_cov in the docker container
All installed packages (present and future) are shared between the two R installations for convenience.
The essential devtools package is preinstalled.
We provide docker containers for several versions of R. If you built the container, just cd in the appropriate rxxx subdirectory (e.g. r312 for R-3.1.2). If you use the docker hub, use the appropriate tags. In the examples below we use the default tag (latest).
docker run -ti quartzbio/r-coverage Rscript_cov test.R
# or: make run-test
This runs the testthat (version 0.7.1) own test suite, and displays in a crude way the corresponding code coverage. Excerpt of the output:
$`/home/docker/testthat/R/utils.r`
[,1] [,2]
[1,] 2 1
[2,] 3 55
[3,] 4 55
It means that the line 2 has been hit 1 time, thes line 3 and 4 55 times.
Typing docker run -ti quartzbio/r-coverage
(or make run
), you end up in the patched R console.
Rcov_start() starts the code coverage tracking, then execute your code, and finally Rcov_stop() stops the
tracking and returns an environment, with the tracked source file names as keys and hit matrices as values.
All the tracked code must have source reference attached. This is normally done by sourc()ing files, or loading packages. To simulate it in an interactive session, we can use the arse(text = , keep.source = TRUE) function.
Example of a session:
### code to define a function
"tested_function <- function(x) { # 1
if (x == 0) return(0)
y <- 1
a <- 3 + y
for (i in 1:10) {
a <- a + y + x # 7
}
if (x == 1) return(1)
a <- y + 3
x + a # 13
}
" -> code
### parse it with source references, and evaluate it.
expr <- parse(text = code, keep.source = TRUE)
eval(expr)
### execute a function call, tracking the code coverage
Rcov_start()
tested_function(1)
res <- as.list(Rcov_stop())
print(res)
Let's look at the coverage of the stringr package:
Launch the R patched console: docker run -ti quartzbio/r-coverage
(or make run
)
library(devtools)
pkg <- download.packages('stringr', '.')
untar(pkg[2], compressed=TRUE)
Rcov_start()
test('stringr')
res <- as.list(Rcov_stop())
print(res)
Let's look at the coverage of the crayon package:
Launch the R patched console: docker run -ti quartzbio/r-coverage
(or make run
)
library(devtools)
# the R-3.0.2 is quite old now, get a compatible version
pkg <- devtools:::github_remote("hadley/stringr", ref = 'stringr-0.6.2')
fname <- devtools:::remote_download(pkg)
repo <- dirname(files[1])
files <- unzip(fname)
repo <- dirname(files[1])
Rcov_start()
test(repo)
res <- as.list(Rcov_stop())
print(res)
We can use the docker volume feature (shared filesystem) to mount a local directory inside the docker container. Suppose that the R source code is in the $DIR directory on the local filesystem. We will mount the directory $DIR as ~/code in the docker:
docker run -ti -v $DIR:/home/docker/code quartzbio/r-coverage
# or: docker run -ti -v $DIR:/home/docker/code rcov-r302
>setwd('code')
...
Orginally this patch is just a very first draft as a proof of concept for the R community. I got absolutely no feedback on its implementation, but it seems to work amazingly well, at least for our purposes. In Quartz Bio we have used it daily for months to test the coverage of our numerous internal R packages without problems.
Of course, as it is, just outputting the covered lines is not very useful. We have developed for our needs some code that output the code coverage percentage by source code file and package. We could package this code and release it if the R community asks for it.
We might also develop/provide a GUI to quickly see the lines that are not covered directly in the source code.
Use the github issues for bugs, questions, requests and general discussions.
- cf the related project: https://github.com/quartzbio/r-coverage-patch.git
- this blog post: http://r2d2.quartzbio.com/posts/top10_coverage.html