Lazytest
Runs only failing tests
Install / Use
/learn @cynkra/LazytestREADME
lazytest
<!-- badges: start --> <!-- badges: end --> <pre class='chroma'> <span><span class='kr'><a href='https://rdrr.io/r/base/library.html'>library</a></span><span class='o'>(</span><span class='nv'><a href='https://github.com/cynkra/lazytest'>lazytest</a></span><span class='o'>)</span></span></pre>The goal of lazytest is to save development time by helping you rerun only the tests that have failed during the last run. It integrates tightly with the testthat package and provides the lazytest_local() function, a drop-in replacement for testthat::test_local(), that
- memoizes which tests have failed;
- runs only those tests in subsequent runs.
If all active tests have succeeded, the entire test suite is run in a second pass.
Usage
Call lazytest_local() instead of testthat::test_local() or devtools::test():
The package also provides RStudio add-ins that run the tests in a new terminal. Unfortunately, the “Test package” command is hard-wired to devtools::test(), and there seems to be no way to customize it or hook into it.
Example
Let’s create a package with two boilerplate tests.
<pre class='chroma'> <span><span class='nf'>withr</span><span class='nf'>::</span><span class='nf'><a href='https://withr.r-lib.org/reference/with_options.html'>local_options</a></span><span class='o'>(</span>usethis.quiet <span class='o'>=</span> <span class='kc'>TRUE</span><span class='o'>)</span></span> <span></span> <span><span class='nv'>pkg_parent_dir</span> <span class='o'><-</span> <span class='nf'>withr</span><span class='nf'>::</span><span class='nf'><a href='https://withr.r-lib.org/reference/with_tempfile.html'>local_tempdir</a></span><span class='o'>(</span><span class='o'>)</span></span> <span><span class='nv'>pkg_dir</span> <span class='o'><-</span> <span class='nf'><a href='https://rdrr.io/r/base/file.path.html'>file.path</a></span><span class='o'>(</span><span class='nv'>pkg_parent_dir</span>, <span class='s'>"tea"</span><span class='o'>)</span></span> <span><span class='nf'>usethis</span><span class='nf'>::</span><span class='nf'><a href='https://usethis.r-lib.org/reference/create_package.html'>create_package</a></span><span class='o'>(</span><span class='nv'>pkg_dir</span><span class='o'>)</span></span> <span><span class='nf'>usethis</span><span class='nf'>::</span><span class='nf'><a href='https://usethis.r-lib.org/reference/proj_utils.html'>with_project</a></span><span class='o'>(</span>path <span class='o'>=</span> <span class='nv'>pkg_dir</span>, <span class='o'>{</span></span> <span> <span class='nf'>usethis</span><span class='nf'>::</span><span class='nf'><a href='https://usethis.r-lib.org/reference/use_testthat.html'>use_testthat</a></span><span class='o'>(</span><span class='o'>)</span></span> <span> <span class='nf'>usethis</span><span class='nf'>::</span><span class='nf'><a href='https://usethis.r-lib.org/reference/use_r.html'>use_test</a></span><span class='o'>(</span><span class='s'>"blop"</span><span class='o'>)</span></span> <span> <span class='nf'>usethis</span><span class='nf'>::</span><span class='nf'><a href='https://usethis.r-lib.org/reference/use_r.html'>use_test</a></span><span class='o'>(</span><span class='s'>"blip"</span><span class='o'>)</span></span> <span><span class='o'>}</span><span class='o'>)</span></span></pre>If we run the tests, they all pass.
<pre class='chroma'> <span><span class='nf'>withr</span><span class='nf'>::</span><span class='nf'><a href='https://withr.r-lib.org/reference/with_dir.html'>with_dir</a></span><span class='o'>(</span></span> <span> <span class='nv'>pkg_dir</span>,</span> <span> <span class='nf'>lazytest</span><span class='nf'>::</span><span class='nf'><a href='https://lazytest.cynkra.com/reference/lazytest_local.html'>lazytest_local</a></span><span class='o'>(</span><span class='o'>)</span></span> <span><span class='o'>)</span></span> <span><span class='c'>#> <span style='color: #00BBBB;'>ℹ</span> Testing all tests.</span></span> <span><span class='c'>#> <span style='color: #00BB00;'>✔</span> | <span style='color: #BBBB00;'>F</span> <span style='color: #BB00BB;'>W</span> <span style='color: #0000BB;'>S</span> <span style='color: #00BB00;'> OK</span> | Context</span></span> <span><span class='c'>#> ⠏ | 0 | blip <span style='color: #00BB00;'>✔</span> | 1 | blip</span></span> <span><span class='c'>#> ⠏ | 0 | blop <span style='color: #00BB00;'>✔</span> | 1 | blop</span></span> <span><span class='c'>#> </span></span> <span><span class='c'>#> ══ <span style='font-weight: bold;'>Results</span> ═════════════════════════════════════════════════════════════════════</span></span> <span><span class='c'>#> [ FAIL 0 | WARN 0 | SKIP 0 | <span style='color: #00BB00;'>PASS</span> 2 ]</span></span> <span><span class='c'>#> → Testing all tests next time.</span></span></pre>Now if we replace one of the tests with a failing test,
<pre class='chroma'> <span><span class='nf'>brio</span><span class='nf'>::</span><span class='nf'><a href='https://brio.r-lib.org/reference/write_lines.html'>write_lines</a></span><span class='o'>(</span></span> <span> text <span class='o'>=</span> <span class='nf'><a href='https://rdrr.io/r/base/c.html'>c</a></span><span class='o'>(</span></span> <span> <span class='s'>'test_that("blop() works", {'</span>,</span> <span> <span class='s'>'expect_equal(2 * 2, 42)'</span>,</span> <span> <span class='s'>'})'</span></span> <span> <span class='o'>)</span>,</span> <span> path <span class='o'>=</span> <span class='nf'><a href='https://rdrr.io/r/base/file.path.html'>file.path</a></span><span class='o'>(</span><span class='nv'>pkg_dir</span>, <span class='s'>"tests"</span>, <span class='s'>"testthat"</span>, <span class='s'>"test-blop.R"</span><span class='o'>)</span></span> <span><span class='o'>)</span></span></pre>and then run the tests,
<pre class='chroma'> <span><span class='nf'>withr</span><span class='nf'>::</span><span class='nf'><a href='https://withr.r-lib.org/reference/with_dir.html'>with_dir</a></span><span class='o'>(</span></span> <span> <span class='nv'>pkg_dir</span>,</span> <span> <span class='nf'>lazytest</span><span class='nf'>::</span><span class='nf'><a href='https://lazytest.cynkra.com/reference/lazytest_local.html'>lazytest_local</a></span><span class='o'>(</span><span class='o'>)</span></span> <span><span class='o'>)</span></span> <span><span class='c'>#> <span style='color: #00BBBB;'>ℹ</span> Testing all tests.</span></span> <span><span class='c'>#> <span style='color: #00BB00;'>✔</span> | <span style='color: #BBBB00;'>F</span> <span style='color: #BB00BB;'>W</span> <span style='color: #0000BB;'>S</span> <span style='color: #00BB00;'> OK</span> | Context</span></span> <span><span class='c'>#> ⠏ | 0 | blip <span style='color: #00BB00;'>✔</span> | 1 | blip</span></span> <span><span class='c'>#> ⠏ | 0 | blop ⠋ | 1 0 | blop <span style='color: #BB0000;'>✖</span> | <span style='color: #BBBB00;'>1</span> 0 | blop<span style='color: #555555;'> [0.2s]</span></span></span> <span><span class='c'>#> ────────────────────────────────────────────────────────────────────────────────</span></span> <span><span class='c'>#> <span style='color: #BBBB00; font-weight: bold;'>Failure</span><span style='font-weight: bold;'> (</span><span style='color: #0000BB; font-weight: bold;'>test-blop.R:2:1</span><span style='font-weight: bold;'>): blop() works</span></span></span> <span><span class='c'>#> 2 * 2 (`actual`) not equal to 42 (`expected`).</span></span> <span><span class='c'>#> </span></span> <span><span class='c'>#> `actual`: <span style='color: #00BB00;'>4</span></span></span> <span><span class='c'>#> `expected`: <span style='color: #00BB00;'>42</span></span></span> <span><span class='c'>#> ────────────────────────────────────────────────────────────────────────────────</span></span> <span><span class='c'>#> </span></span> <span><span class='c'>#> ══ <span style='font-weight: bold;'>Results</span> ═════════════════════════════════════════════════════════════════════</span></span> <span><span class='c'>#> <span style='color: #00BBBB;'>Duration: 0.3 s</span></span></span> <span><span class='c'>#> </span></span> <span><span class='c'>#> [ <span style='color: #BBBB00;'>FAIL</span> 1 | WARN 0 | SKIP 0 | PASS 1 ]</span></span> <span><span class='c'>#> → Testing the following tests next time:</span></span> <span><span class='c'>#> <span style='color: #00BBBB;'>•</span> blop</span></s