Appendix F — Comparisons

Published

2024-02-16

Please open an issue on GitHub

Comparisons are the backbone of testing. Exploring the mechanics of how tests perform these comparisons (i.e., the underlying package(s)) can save you from surprising results.

For example, expect_equal() compares whatever is passed to the observed and expected arguments with the waldo package, with some help from diffobj.

library(waldo)
library(diffobj)
library(tibble)

F.0.1 waldo::compare()

If you’d like a preview of a comparison before writing a formal test, you can pass the your observed and expected objects to compare()1

For example, suppose we have two objects:

old
## # A tibble: 3 × 3
##   chr     num fct  
##   <chr> <dbl> <ord>
## 1 B         1 L    
## 2 C         2 M    
## 3 D         3 H
new
## # A tibble: 3 × 3
##   CHR     num fct  
##   <chr> <int> <fct>
## 1 B         1 low  
## 2 C         2 med  
## 3 D         3 high

The outputs below are example outputs from waldo::compare():

compare(
  x = old,
  y = old)
## ✔ No differences
1
Comparing identical objects
compare(
  x = old,
  y = new)
## `class(old)`: "tbl_df" "tbl" "data.frame"
## `class(new)`:                "data.frame"
## 
## `names(old)`: "chr" "num" "fct"
## `names(new)`: "CHR" "num" "fct"
## 
## `old$chr` is a character vector ('B', 'C', 'D')
## `new$chr` is absent
## 
## `old$num` is a double vector (1, 2, 3)
## `new$num` is an integer vector (1, 2, 3)
## 
## `class(old$fct)`: "ordered" "factor"
## `class(new$fct)`:           "factor"
## 
## `levels(old$fct)`: "L"   "M"   "H"   
## `levels(new$fct)`: "low" "med" "high"
## 
## `old$CHR` is absent
## `new$CHR` is a character vector ('B', 'C', 'D')
1
Comparing different objects

compare() displays the differences in classes, names, and any individual value differences.

F.0.2 diffobj::diffObj()

If you’re using Posit Workbench, the diffobj package has a colorful display for making comparisons in the IDE.

The differences can be displayed vertically with diffobj::diffObj():

diffObj(
  old, 
  new)
Figure F.1: Viewer ouput from diffobj::diffObj()

If you want to view the structure (str()) differences, you can use diffobj::diffStr():

diffStr(
  old, 
  new)
Figure F.2: Viewer ouput from diffobj::diffStr()

After viewing the old vs new comparisons with waldo and diffobj, you should notice similarities and differences in the results from testthat2

[ FAIL 1 | WARN 0 | SKIP 0 | PASS 0 ]

── Failure (test-old_vs_new.R:17:3): old vs. new ───────────────────────────────
`new` (`actual`) not equal to `old` (`expected`).

`class(actual)`:   "data.frame"                   
`class(expected)`: "tbl_df"     "tbl" "data.frame"

`names(actual)`:   "CHR" "num" "fct"
`names(expected)`: "chr" "num" "fct"

`actual$CHR` is a character vector ('B', 'C', 'D')
`expected$CHR` is absent

`class(actual$fct)`:   "factor"          
`class(expected$fct)`: "ordered" "factor"

`levels(actual$fct)`:   "low" "med" "high"
`levels(expected$fct)`: "L"   "M"   "H"   

`actual$chr` is absent
`expected$chr` is a character vector ('B', 'C', 'D')
[ FAIL 1 | WARN 0 | SKIP 0 | PASS 0 ]

  1. Be mindful of the difference in arguments between expectation functions (i.e., expect_equal()) and compare()↩︎

  2. The results from testthat don’t include the differences between old$num and new$num. This is due to the tolerance argument, which can be adjusted in both functions.↩︎