In the previous section we discussed debugging code and fixing errors. This is essential, but we would encourage you to move beyond this approach to writing formal unit tests. Unit tests are small, automated tests that check a small part of your code.
Why is writing unit tests a good idea? This guide provides a detailed answer. Some of the key reasons are:
When you test using an ad hoc approach, you likely test the most common flow with your function, and fix bugs you find. However, users will inevitably use your functions in ways you hadn't envisaged. By writing tests for all plausible flows/scenarios, you will find new bugs which you can fix.
The simpler and more refactored your code is, the easier it is to write tests. If you find yourself struggling to write tests for a long section of code, this is a good sign that you need to refactor into separate functions.
When you know that the major functionality of your package is covered by tests, you'll be less likely to break things by implementing a new 'great idea'. Without test coverage, it is very hard to know if your 'great idea' improves your package, breaks something, or both.
We suggest using the testthat
package to manage your tests, as it is well-integrated with other R package utilities such as devtools
, and provides good testing functionality.
Let's set up a first test for our server-side package. Ensure that you are in the working directory for that package, and run:
usethis::use_test("funLevelsDS.R")
✔ Setting active project to '/Users/timcadman/Library/Mobile Documents/com~apple~CloudDocs/work/dsExample'
✔ Adding 'testthat' to Suggests field in DESCRIPTION
✔ Adding '3' to Config/testthat/edition
✔ Creating 'tests/testthat/'
✔ Writing 'tests/testthat.R'
✔ Writing 'tests/testthat/test-funLevelsDS.R'
• Modify 'tests/testthat/test-funLevelsDS.R'
This has performed a number of steps:
tests/
testthat.R
test-funLevelsDS.R
testthat
to the DESCRIPTION file of the package.testthat
Now repeat the same step from the working directory of your client-side package referencing the client-side function by running:
usethis::use_test("ds.funLevels.R")
In the next sections we will write tests for the client- and server-side packages.