unit testing in r with testthat - hrug

Post on 08-Jan-2017

156 Views

Category:

Data & Analytics

1 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Unit Testing in R(R Workflow Series Part 5)

Houston R Users Group Ed Goodwin

R Workflow Series• Intro to RStudio - January

• Using knitr for literate programming and documentation - February

• Intro to GitHub - March

• Production code in R - March

• Unit Testing in R - You are here

Tying it all together

• RStudio has lots of debugging capabilities

• Production code can get messy really quickly

• The bigger a code base grows the easier it is to make dumb mistakes that ripple through the code

• How do we help manage all this?

The Answer is Unit Testing*

* Unit Testing is not a “silver bullet”. It will not turn you into a programming genius. However, it will help you fake it really well until you become one.

What is Unit Testing?

• Unit Tests are low level tests of your code functionality.

• Written by the developers themselves

• The first line of defense against bugs in the code

Test Driven Development (TDD)• Unit testing gained popularity with Test Driven

Development in the late 1990s. The idea was that you write the test first and then write the code that it tested

• Test Driven Development philosophy helped make eXtreme Programming (XP) popular

• eXtreme Programming was rolled into Agile Methodologies that are now dominant today

• see http://martinfowler.com/bliki/TestDrivenDevelopment.html “Test Driven Development: By Example” by Martin Fowler for more information

Benefits of Unit Testing

• Fewer bugs

• Better code structure

• Easier restarts…gives you confidence to make changes

• Robust code

Test Driven Development Steps

1. Write a test for the next bit of functionality that you want to test

2. Write the functional code until the test passes

3. Refactor the new and old code to make it well structured

Tools for unit testing• Some functionality you want to code

• A unit test model that will allow you to create tests easily

• A unit test scaffolding to run the tests quickly in the order you want

• A unit test reporter that will tell you the results of the test

Workflow

testthat package• Designed by Hadley Wickham

“I wrote testthat because I discovered I was spending too much time recreating bugs that I had previously fixed.”

• Provides functions that catch errors, warnings and messages

• Allows for simple testing via command line, RStudio, or other dev tools

• Integrates into R package system, for building code intended for external consumption via CRAN

testthat• Hierarchical structure

• Expectations - describes what the result of a computation should be

• Tests - group together expectations

• Contexts - group together tests by related functionality

• set up your package to use testthat with devtools::use_testthat()

Expectations• equals()

• all.equal()

• is_identical_to()

• is_equivalent_to()

• is_a()

• matches()

• prints_text()

• shows_message()

• gives_warning()

• throws_error()

• is_true()

Expectations (contd.)

R Journal, January 2011 “testthat: Get Started with Testing” by Hadley Wickham

Tests

testthat.R used to run all your tests… as long as their names start with test (e.g. testMath.r)

use devtools::test(“/path/to/tests/“) to run

Example Test

Simple test that will pass

Expectations

Contexts

• called using the context(“string”) function

• allows you to group multiple tests together to help identify failure points

• simply an output mechanism

Skipping tests

skip() function allows you to skip tests.

output shows an ’S’ instead of a ‘.’ for skipped output.

Set up, Tear down, and cleanup

testthat does not handle tear down and clean up. You must do this explicitly yourself.

Continuous IntegrationContinuous integration is the process of setting up your project to do continuous builds and test.

If you have a GitHub project you can set this up with Travis CI (https://travis-ci.org/)…it’s free if your project is open source.

Simply run the command devtools::add_travis() to create a travis.yml file to your project.

Best practices of unit testing

A great unit test will do the following:

• Fail only when a bug has been introduced

• Fail Fast, for instant feedback

• Easy to understand what scenario is being tested and needs fixing

Best practices (contd.)• tests should run under a minute

• serialize and hardcode your data outside of the test...create mockups (Test Doubles...like Stunt Doubles in the movies)

• offload connections and integration points

• avoid system variables (especially for CRAN)

• treat test code as production code...it's a feedback mechanism for you

• eliminate unreliable tests

• test at the appropriate level...for your project.

Unit Test Design PatternsArrange, Act, Assert Pattern

Given, When, Then

Resources• RJournal intro to testthat https://journal.r-project.org/archive/2011-1/

RJournal_2011-1_Wickham.pdf

• testthat Github https://github.com/hadley/testthat

• Martin Fowler’s Unit Test bliki http://martinfowler.com/bliki/UnitTest.html

• http://kbroman.org/pkg_primer/pages/tests.html

• xUnit test design patterns http://xunitpatterns.com/Book%20Outline.html

• http://www.typemock.com/unit-test-patterns-for-net

Sample Code for Talk

https://github.com/egoodwintx/hrugtestexample

top related