13.4 Test R code - Video Tutorials & Practice Problems
Video duration:
6m
Play a video:
<v Voiceover>As R matures as a language,</v> there's been increasing emphasis on writing tests for the code in your package. This is a way of making sure when you change things your code doesn't break. There are a few different ways to do that, particularly the R unit package and the testthat package. Testthat was written by Hadley Wickham, so it has seen very quick adoption, as he builds tools that are very easy for people to use. So let's say you want to start using tests in your package. Well that's very simple with the devtools package. We can do library(devtools) and then very easily just type in use_testthat(). You'll see in the description file that it added a line Suggests: testthat. That is because it has created this infrastructure for testing. If we come here and click the Open File dialogue, we will see there's a new folder called Tests. In there, there's a testthat.r file. This simply loads testthat, loads our package, and then runs a check on this package. We also see that inside this one, there's another folder called testthat. Right now it's empty, but this is where we will put files that test our functions. Now that our testing infrastructure is in place, we should go ahead and write some tests for our function simple.ex. We can have this generated automatically by typing in use_test and then in quotes the name of the file where the tests will be written to. First that will be simpleex. You run this, and it tells us that a new test file was created inside tests/testthat/test-simpleex.r. We go to the Open File dialogue. We load the package testthat, that way it's easier to work with interactively here. Let's go check out the file that was created by the use test. Inside the testthat folder is this file test-simpleex.r All the files in this folder need to start with test dash, and then the name of the test you are doing. You can see here that it created a bunch of code here automatically, including the context, some comments to us, and a simple test. We'll delete the stuff we don't need, and we'll edit the context. The context should tell you what test is being conducted. It's good to be verbose because you'll have a lot of tests you're working on. We are gonna make it very simple and just say that ("simpleex works properly"). Not a great context, but it'll do us for now. So we're gonna create a few tests for this one function. The first test is checking that it returns the correct class. So we will say, test_that(. We write what we're testing. And that is that 'simple.ex returns the right class', close the quote comma, then we put curly braces because we could be putting multiple expressions. So there are a number of expectations we can put. You can expect that things are equal. You can expect that there's warnings. We are expecting is, expect_is. This allows us to check the class of something against what we expect it to be. So we are expecting that (simple.ex(3,4), 'numeric'). That's one test we can do. Now to test this in action, we will use the dev tools function load_all to load everything up into memory, and we can work this out. We can now run this line of code and see. It did not return any errors. That means it worked properly. If the expectation failed, you would get a message back. I will now run this entire test, and still no messages, meaning things are still going well. Now let's test out the accuracy of this function. We're gonna test that it returns the correct number. So we say test_that, so we're gonna make a note to ourselves in this test_that function that simple.ex returns the proper number. Say ('simple.ex returns the proper number'. So in here we'll have a few expectations. We will say expect_equal(simple.ex(3, 4), 12). We'll also expect_equal(simple.ex(2, 2), 4). And then we'll do some vector operations. We'll say 1:3, 1:3), and we expect that to return the vector (1, 4, 9). So we can run each of these expectations individually, or we can run the entire test. And since we don't get messages we know it ran correctly. Sometimes, however, you expect your code to give a warning. So we need to test for that. We'll say, test_that('simple.ex gives a warning with mismatched sized vectors'. And here we'll put expect_warning when we do (simple.ex(1:3, 1:2)). And we do indeed get that warning. Testing is an important part of code writing that will be very beneficial when you're rewriting code to know that you didn't break anything. And it's often become your requirement to contributing to other people's open source packages. Hadley Wickham's testthat package makes testing in R a very simple process.