Test-driven development is hard…and important.


December 28, 2018

I’ve been developing an R package that interacts with the Databrary.org API and with Datavyu annotation files stored locally or on Databrary alongside shared videos. If you’re curious, you can download the databraryr package from this GitHub repository: https://github.com/databrary/databraryr.

Like many people in the software world, I’m entirely self-taught. Ok, I took a class in C programming at the U.S. Department of Agriculture’s Graduate School in the year before I applied to graduate schools in cognitive neuroscience. But my R package development skills are entirely self-taught. I must thank the incredibly generous geniuses who have gone before me and who share their code and their talents so freely and openly. Without the almost instant availability of these resources, my progress would be much, much slower.

Developers are an opinionated bunch, and there are at least as many styles (fads?) in software development as their are developers. One style that I have started to try to emulate is ‘test-driven development’. In TDD, the idea is that you create tests for how each part of your package should respond given this or that input. If your tests are through enough and correct, your package should work…at least within the boundaries of what you tested.

For the latest version of the package (0.1.4), I added a bunch of new tests to evaluate several new functions I’ve added to the package. Let’s just say that getting through my own self-designed test battery was challenging. But as a result, the code is cleaner and less buggy than it would be if I hadn’t gone this route.

In the larger sense, TDD is sort of a “plan for the worst” style. I like it because I know it forces me to be more precise and specific than I might otherwise choose to be. Since I’ve been using the databraryapi more often for keeping tabs on what’s going on in the Databrary world, that’s a very good thing.

In case you’re curious what the package can do, check this out:

Downloading GitHub repo databrary/databraryr@HEAD
askpass    (1.1   -> 1.2.0) [CRAN]
dplyr      (1.1.2 -> 1.1.3) [CRAN]
filelock   (NA    -> 1.0.2) [CRAN]
sodium     (NA    -> 1.2.1) [CRAN]
assertthat (NA    -> 0.2.1) [CRAN]
selectr    (NA    -> 0.4-2) [CRAN]
getPass    (NA    -> 0.2-2) [CRAN]
plyr       (NA    -> 1.8.8) [CRAN]
magick     (NA    -> 2.7.5) [CRAN]
keyring    (NA    -> 1.3.1) [CRAN]
rvest      (NA    -> 1.0.3) [CRAN]
Installing 11 packages: askpass, dplyr, filelock, sodium, assertthat, selectr, getPass, plyr, magick, keyring, rvest

The downloaded binary packages are in
── R CMD build ─────────────────────────────────────────────────────────────────
* checking for file ‘/private/var/folders/hz/j_rrw69j3pz2xfp4m2jgj__h0000gp/T/RtmpwZF2Rx/remotesfadc27c83a99/databrary-databraryr-55eadfe/DESCRIPTION’ ... OK
* preparing ‘databraryr’:
* checking DESCRIPTION meta-information ... OK
* checking for LF line-endings in source and make files and shell scripts
* checking for empty or unneeded directories
Omitted ‘LazyData’ from DESCRIPTION
* building ‘databraryr_0.4.2.tar.gz’

Here is a list of some recently authorized researchers:

# A tibble: 5 × 6
     id sortname prename   affiliation                 url           institution
  <int> <chr>    <chr>     <chr>                       <chr>         <lgl>      
1 11313 Mathers  Sandra    University of Oxford        <NA>          NA         
2 11656 Wilcox   Teresa    Florida Atlantic University https://psy.… NA         
3  7217 Sen      Hilal     University of Akureyri      <NA>          NA         
4 11618 Movinsky Cassandra Saint Francis University    <NA>          NA         
5 10876 Nwogu    Ifeoma    University at Buffalo, SUNY <NA>          NA         

And here is a very simple plot of the growth in authorized researchers and institutions over time:

with(databraryr::read_csv_data_as_df(), plot(Auth_Investigators, Institutions))

I’ve said in other places that I think scientists will eventually interact with their data programmatically – via scripts like this – with the data and materials stored in repositories that others can also access programmatically. Furthermore, I think that the philosophy of test-driven development can help make our software AND the results and findings we derive from it more robust and reproducible.