Testing your Shiny applications shouldn't be an afterthought.
Many developers write tests after building features, missing the core benefit of test-first development: tests as design tools. I'll walk you through how I built a small content submission form using Behavior-Driven Development (BDD), starting from absolutely nothing.
Whether you're building a new app or adding a feature, the steps are the same.
Follow along and see how tests drive design decisions, keep business value visible, and make refactoring safe.
Level-up your testing game! Grab your copy of the R testing roadmap.
The app's purpose we're about to build is to submit data that another app will display.
BDD starts with a high-level specification describing the behavior we want to see. The first specification is the most important. It describes the core behavior that delivers value to users.
We have 2 choices for writing specifications:
testthat. We have a full freedom to design our own domain-specific language (DSL) for expressing specifications.cucumber. We are constraLearn how to write When steps that describe user actions without leaking implementation details. Build a clean DSL that survives UI refactors and keeps specifications readable.
Learn how to set up test preconditions in Shiny BDD using Given steps. Master dependency injection, test doubles, and composable setup patterns for reliable R testing.
Topics
Learn to recognize problems in R test code that cause your test suite to pass while hiding real bugs. Detect those issues and start writing more trustworthy tests.
Learn how to write Then steps that assert outcomes without coupling to implementation. Build custom testthat expectations and keep your BDD assertions at the right level.
Learn how to write When steps that describe user actions without leaking implementation details. Build a clean DSL that survives UI refactors and keeps specifications readable.
Expanded mutator library, improved reporting, and parallel execution for mutation testing in R.
Learn how to set up test preconditions in Shiny BDD using Given steps. Master dependency injection, test doubles, and composable setup patterns for reliable R testing.
When shinytest2's `set_inputs()` won't work, leverage widget APIs directly. Learn to write cleaner, faster and more robust tests using JavaScript APIs.
Follow each step as I develop a form with Shiny and Behavior-Driven Development. Learn practical techniques for better software design through automated tests.
Code organization and deployment strategy for multiple Shiny apps sharing common logic within a single R package. Structuring your project in a monorepo format.
Learn how to effectively implement Behavior-Driven Development (BDD) practices in your projects. Focus on delivering the most valuable scenarios first and avoid the pitfalls of over-specification.
Learn how to write reliable R tests by wrapping external dependencies and using `testthat::local_mocked_bindings`. Make your tests fast, clean, and predictable.
A Practical Guide to Faking External Dependencies and Business Logic with R6 Classes for Reliable Tests.
A step-by-step guide to stronger R Shiny testing with stable selectors and reusable actions.
A Practical Guide to Faking External Dependencies in R for Fast, Reliable Tests.
Adding Cucumber specifications to an existing application? Learn how to write Gherkin scenarios that focus on user behavior, not implementation details. Use AI to iterate faster.
Given a set of existing Cucumber and Playwright acceptance tests, I asked Copilot to refactor them according to best practices for step organization and anti-patterns.
Get them out of your way to start testing your code effectively.
Learn how to effectively test your Plumber APIs in R using a two-layer testing strategy that separates business logic from API contracts.
Adding acceptance tests first makes refactoring safer.
Discover the essential layers of testing for robust R packages: unit tests, acceptance tests, code coverage, and mutation testing.
Learn how to use Behavior-Driven Development (BDD) in R to ensure your software meets user requirements through executable specifications.
Learn how to build scalable and maintainable code by abstraction and information hiding, improving flexibility and ease of future changes.
Learn how to apply Acceptance Test-Driven Development (ATDD) to build robust Shiny applications using {shinytest2} and {selenider}.
Discover the benefits and challenges of AI-assisted testing, and learn how to optimize your testing process for better code quality and maintainability.
Learn how to manage snapshot tests in R using CI and GitHub API to ensure consistency across different environments.
Learn how to generate code coverage reports in R using cobertura-action without sharing your private code with codecov.io.
Discover how to build user-focused software with BDD. Learn from Dave Farley's comprehensive YouTube series.
Compare {shinytest2} and Cypress for acceptance testing Shiny apps. Learn their pros, cons, and which might suit your project better.
Learn the differences between unit tests and acceptance tests and how they contribute to software quality.
Learn how good automated tests can save time, reduce costs, and improve software quality.
Learn how poor test writing can halt your development process and discover strategies to avoid this pitfall.
Learn how to speed up your unit tests by optimizing the structure of your test files using testthat in R.
Discover how tests can reveal code modularity, coupling, and separation of concerns to improve your code quality.
Discover the top three lessons learned from three years of testing as an R developer. Improve your testing practices with these insights.
Learn how to write descriptive unit test titles that enhance code readability and maintainability.
Learn methods to capture and test code output in R, including snapshot testing, dput, and constructive package.
Learn how to speed up Shiny app tests using shinytest2 by reusing application instances and refreshing the browser.
Learn how to test Shiny components for correct markup and server communication using shinytest2.
Learn how to manage state in Shiny modules using a React-inspired approach with event handlers for better control and flexibility.
Learn how to create resilient E2E test selectors in Shiny apps using data-* attributes and best practices.
Learn how to export data to Excel in Shiny apps and use snapshot tests to validate and inspect the exported workbooks.
Learn how to use tests to develop Shiny modules efficiently, ensuring faster development cycles and better modularization.
Learn how to set up Cucumber with Cypress in Rhino projects for clear and maintainable end-to-end tests.
Learn how to write BDD style tests for Shiny module servers using R6 and testServer to improve readability and maintainability.
Learn how to implement real-time input validation in Shiny apps using Bootstrap Form Validation API for immediate feedback.
Learn how to apply acceptance test-driven development (ATDD) to build robust Shiny modules with R6 and shinytest2.
Learn about Agile Testing Quadrants and how they help in planning and executing different types of tests in software development.
Learn how to effectively test Shiny modules using shiny::testServer with examples and best practices.
Discover how to use TDD and approval testing to rapidly develop and test plots in R.
Learn how TDD helps you prototype faster by allowing you to experiment with your code and find better solutions quickly.
Learn how to extend Shiny modules in legacy code using the Sprout Technique and Test Driven Development.
Learn how to use AI tools to use new libraries quickly without spending hours on documentation.
Learn how to test R functions with external dependencies using stubs and the testthat package.
Learn the 3 essential steps of Test-Driven Development (TDD) to improve code quality and development speed.
Learn how Test Driven Development (TDD) ensures you build the right thing on the first try with no rewrites.
Learn how to manage legacy code efficiently using the Sprout Technique to reduce frustration and improve productivity.
Learn how to write cleaner and more effective unit tests using the Arrange, Act, Assert method. Step-by-step guide with examples.
Learn how we built an app prototype with 96% code coverage in just 2 weeks using TDD and effective testing strategies.
Learn about Direct Response, State Change, and Interaction Tests to improve your unit testing strategy.