Functional testing in 2024
Verify that your application behaves as expected on every code change
Functional testing lets you validate that your software conforms to its expected requirements, behaviors, and utilities. In this guide, we’ll outline the different kinds of functional tests that are most used commonly today, their differing purposes, and how they combine to produce modern testing workflows! Within that, we'll explore how you can capitalize on the latest trends in developer tooling by validating application functionality and appearance using tools like Playwright, Cypress, and Storybook.
Why is functional testing so important?
Functional testing is critical to perform, to ensure that you deliver the application experience and quality that your users expect. Fundamentally, your users are not your QA testers, and you should never rely on them to be the ones catching errors in your code! Instead, functional testing provides you with a tried-and-tested methodology for catching software implementation errors before they reach production.
We've been using functional testing at Chromatic and Storybook for many years, to ensure that the code we use to build our apps performs as expected before it gets to our users.
FAQ: Is functional testing different from manual testing?
No, and this is a common misconception! Manual application testing can take the form of functional testing, where you manually go through your application to validate the correctness and stability of different aspects. However, you can also perform functional tests automatically and with testing tools like Playwright, Cypress, and Storybook. In the next section, we'll highlight the different types of functional tests.
Examples of different types of functional test
There are different kinds of functional tests that you can use to inspect your application at varying depths and angles. Collectively, they bring you a complete overview of your application's behavior and functionality. These testing types include:
⚛️ Unit testing
🚒 Smoke testing
🤨 Sanity testing
⏪ Regression testing
🤝 Integration testing
🙌 User Acceptance Testing
Let's explore each test type, one at a time!
⚛️ Unit testing
A unit test checks a small, composed section of code. For example, if you're testing a UI built with a JavaScript framework like React, you might use a unit test to check the functionality of a button or another isolated component and confirm that error states are handled correctly. Unit tests are convenient methods for asserting the correct output of code functionality and getting feedback fast.
🚒 Smoke testing
Smoke testing takes its name from the world of hardware, where a sign of success is that your product isn't literally on fire. For our purposes, smoke testing a frontend application involves checking the stability of your application's most critical features and plumbing. Think of it like a health check to catch any major issues. Once you've confirmed your application's stability, you can proceed to deeper-level functional tests.
🤨 Sanity testing
Whenever you make a change or bug fix, you need to ensure the new code works correctly without creating any obvious errors. This is where sanity tests come in. Sanity tests are quick checks to ensure the behavior–the ‘sanity’–of your new code after changes.
⏪ Regression testing
New code changes can create bugs in code that worked previously. For example, your team could add a new way to log into your app that accidentally breaks the popular existing method. Regression testing is a process of catching any instances of new changes introducing incompatibilities or defects.
🤝 Integration testing
Integration tests validate that different services and modules work correctly together. These checks are vital due to the ever-increasing complexity of modern app infrastructure, where so many APIs and libraries need to be compatible for your app to perform as intended.
🙌 UAT (User Acceptance Testing)
UAT means bringing in a human to check that your application conforms to their expectations and their intended business usage.
Using a functional testing strategy
One of the most popular strategies for functional testing today is the Testing Trophy, a concept coined by Kent Dodds (author of React Testing Library) in 2018.
The Testing Trophy has four key parts that combine all the testing types we've mentioned so far:
End-to-end testing: In end-to-end (E2E) testing, you use a test runner like Playwright or Cypress to control your browser and click through your application as if it were a human tester. These test runners combine the benefits of smoke testing, sanity testing, and acceptance testing in verifying an application’s stability and behavior. You can run E2E tests automatically by integrating Playwright or Cypress into your CI/CD pipeline.
Integration testing: Integration testing represents the most significant part of the Testing Trophy. Today, one of the most popular developer tools for performing integration testing is Storybook. Storybook lets you render each UI component and state representation as a separate debuggable story. Then, you can use each story as an integration test case, to test how your UI interacts with different libraries and modules.
Unit testing: Unit testing continues to be a core way of testing applications.
Static testing: Static testing involves using developer tools like TypeScript and linters to check your code quality during development. These tools can ensure the quality of your product both in real-time and during builds, minimizing the likelihood of bugs being introduced accidentally.
Functional vs non-functional testing
Using a workflow like the Testing Trophy enables you to validate your application's stability. However, there's more to application functionality than behavior and utility alone, and you need to ensure your application also provides the polished experience that your users and customers expect. This requires a complementary type of testing known as non-functional testing, which is more concerned with how an application functions than the boolean of whether it works or not.
One of the most prominent non-functional testing methods used by teams today alongside traditional functional tests is visual testing, which involves validating application appearance and UX. Chromatic enables you to automate visual testing within your functional testing suite, whether that's Storybook, Playwright, or Cypress. This addition enhances the Testing Trophy to ensure that your application both works and appears correctly.
Get started with visual and functional testing today by heading to Chromatic’s docs!