What is Functional Testing? Definition, Types & Examples

Functional testing in software testing - functional testing types and examples Katalon

What is Functional Testing?

Functional testing is a type of testing where testers check if features of the System Under Test are working as expected according to its specified requirements. These requirements are either collected from the users or provided by the stakeholders (development team or product owner). Functional testing is also known as specification testing for this reason.

The primary goal of functional testing is to ensure that the software performs the functions it was assigned to do, and typically does not concern with the internal code structure or implementation details.

Functional testing can be considered as one of the most common and foundational types of testing. When people refer to "testing" in a general context, they often have functional testing in mind.

Examples of Functional Testing

1. Functional Testing For The Login Feature

Imagine you are testing a web application that requires users to log in. In this case, functional testing simply is used to check if the Login page is working as expected.

What are the “expected” features from a Login page then? Several that come to mind are:

  1. User Authentication
  2. Account Lockout
  3. Password Reset
  4. Remember Me 
  5. Account Recovery
  6. Multi-Factor Authentication (especially critical for high-risk applications)
  7. Session Management (ensure that users are logged out automatically after a period of inactivity for security purposes)
  8. User Monitoring

Those requirements are agreed upon and carefully documented to guide the functional testing effort. Generally, the more emphasis placed on security, the more functional testing needs to be done for the Login feature. Here are several examples of functional test cases on the Login page:

  1. Test that users can successfully log in with valid credentials (e.g., a registered username/email and password).
  2. Test that users receive an error message when attempting to log in with invalid credentials (e.g., incorrect password or non-existent username).
  3. Test that after a specified number of consecutive failed login attempts, the account is locked and the user cannot log in.
  4. Test the password reset feature by initiating a password reset request through the "Forgot Password" link.
  5. Test the "Remember Me" feature to ensure that the user remains logged in across browser sessions.
  6. Test the implementation of MFA by logging in with valid credentials and verifying that the MFA method (e.g., SMS code, app-based token) works correctly.

Read More: 100 Test Cases For The Login Page


2. Functional Testing For eCommerce Websites

Similarly, we also need functional testing for eCommerce websites to check their specific features, such as Product Search functionality, Shopping Cart functionality, or even the Checkout process. Here are some examples of functional testing on those websites:

  1. Test that users can search for products using different search terms.
  2. Verify that the search results display the relevant products along with their prices, descriptions, and images.
  3. Verify that users can update quantities, remove items, and empty the cart as needed.
  4. Test the ability to add products to the shopping cart from product listings and product detail pages.
  5. Test the entire checkout process, including providing shipping information, selecting payment methods, and reviewing the order.


Download a Test Case Template


Find a Tool With Test Management Capabilities


The Issue of Test Coverage For Functional Testing

Software testing in general and functional testing in general is a tricky process.

Yes, at the very essence, functional testing is simply about making sure that the computer code is doing exactly what it is supposed to be doing. However, that is only the tip of the iceberg. An application can work well in one way, but can go wrong in a million ways. By definition, functional testing is about testing if the application-under-test works as expected, but in reality, it is more about testing if the application is not deviating from the expectations

Now comes an issue: test case design. How can we design test cases that cover all of the possibilities of breaking?

Let's do a simple math problem. Your goal is to think of the possible test scenario and corresponding test data for the following program:

The program reads three integer values from an input dialog. These three values represent the lengths of the sides of a triangle. The program then displays a message indicating whether the triangle is scalene, isosceles, or equilateral.

Given that:

Scalene: All three sides have different lengths.
Isosceles: Two sides have the same length, and the third side is different.
Equilateral: All three sides have the same length.


Let's check if you have listed down all of the necessary test cases:

  1. Valid Scalene Triangles
  2. Valid Isosceles Triangles
  3. Valid Equilateral Triangles
  4. Invalid Triangles
    1. Sum of two sides equals the third
    2. Sum of two sides less than the third
  5. Special Cases
    1. One side is zero
    2. One side is negative
    3. All sides are zero
  6. Permutations of Valid Isosceles Triangles
  7. Non-integer Values (if allowed)
  8. Incorrect Number of Inputs (1-2 values instead of 3 values?)

That is just one example for a simple test scenario. Let's now consider a functional testing scenario on an E-commerce website with thousands of products, millions of product variants, thousands of coupons, and hundreds of shipping locations. Perhaps you can consider the complexity of doing functional testing for an ERP system that handle a rich array of business processes from accounting, inventory management, HR, CRM, and so much more. 

In fact, it is almost impossible to achieve 100% test coverage i.e. covering all possible scenarios. The more complex a program is, the more test cases there are to account for. Considering time and resource constraints, testers can only focus on the most critical functionalities, or automating the necessary test cases to scale testing operations.

You Should Know: How To Go From Manual Testing To Automation Testing?

How Do We Know If We Have Done Enough Functional Testing?

As we have mentioned, it is actually impossible to address ALL bugs. At a certain level of complexity, there will always be the risk of a bug hidden somewhere in the obscure corners of your application. These bugs usually require a complex chain of interactions to trigger. If that is the case, how can we know that we have done “enough” functional testing" to “ensure that the application is working as intended”?

The short answer: we don't. Once all tests have passed, all requirements satisfied and all user stories considered, testers have done the job of making sure that developers are doing the right thing. However, the battle of finding obscure bugs go on and on. Exploratory testing and manual testing is the key to this.

How To Use Functional Tests Drive Development

Functional tests rely heavily on requirements, and these requirements change (quite frequently). Requirements usually start from user stories, which are a brief and information description of a feature from the perspective of an end-user. The challenge presented to the dev team and QA team is clear: how do we translate that user story into a test and a feature? 

Functional tests here play a much bigger role than just checking if the feature works or not. Now it is a valuable and powerful tool to guide the dev team towards developing the right feature that the customers want.

Read More: What is TDD? A Complete and Easy-to-Understand Explanation

How to do TDD

These functional tests drive coding. They are written in executable format, usually automated so that the team can run them as many times as they prefer. Over time, these tests can be grouped into a regression test suite so they can be run in future development cycles to check if new features change system behavior or not.

How To Do Functional Testing

Functional testing starts from requirements.

Requirements start from user story. 

At its core, functional testing is about translating that user story into the right requirements, which will then be turned into the right test cases.

A user story typically follows a specific format:

  • As a [role]: This describes the type of user or stakeholder who will benefit from the feature.
  • I want [feature]: This describes the specific functionality or capability that the user desires.
  • So that [benefit]: This explains the reason or goal behind the desired feature, providing context for its implementation.

For example, a user story might look like this:

"As a customer, I want to be able to view my order history online so that I can track the status of my purchases."

This is a good user story, but it is not enough for the development team and QA team. They work as a starting point at best. Testers need to work with the end users, sit with them, look at the issue from their perspective, and put that user story into specific context to ensure that the developed feature aligns with what they want. A user story combined with a realistic example and conversation becomes a requirement. From this requirement comes the first functional tests to guide development activities later down the road.

So, how do we actually do that? The keyword here is “divide to conquer”. 

A user story might be too general. The user wants X, but to achieve X, what are the action items we need to take, specifically? Break the user story into smaller chunks that are easier to tackle. This practice also significantly mitigates risks associated with the story, and you can also code and test that small chunk of the story faster.

From the user story above, we can immediately break it into 8 smaller slices:





Basic Order History Page Setup

- Create the Order History page in the navigation menu.

- Set up a basic HTML/CSS structure for the page.

- Display a placeholder message like "No orders found" or "Your order history will appear here."


Fetching Order Data

- Create an API endpoint that fetches the customer's order history.  

- Connect the frontend to this API to fetch data.


Displaying Order List

- Design a list view for orders.  

- Populate the list with order data (e.g., order ID, date, and total amount).


Order Details View

- Enable each order item in the list to be clickable.  

- Create a detailed order view that shows items in the order, quantities, prices, etc.


Order Status Tracking

- Display the current status of each order (e.g., processing, shipped, delivered).  

- Provide a status timeline or progress bar if applicable.


Pagination and Sorting

- Implement pagination to handle a large number of orders.  

- Allow sorting by date, amount, or status.


Mobile Responsiveness

- Adjust the layout and styles for different screen sizes.  

- Test and refine user interactions on mobile devices.


Error Handling and Notifications

- Display error messages if the order data fails to load.  

- Show loading indicators while data is being fetched.  

- Provide user-friendly messages for any issues encountered.

Of course, you can break it into even smaller slices and more slices depending on how granular you want to go.

The next steps is to write test cases to define each slice at the same time with programmers writing the code. After that, we can run the tests, and then we can show the new functionalities to the customers to ensure that it aligns with their requirements. This approach can save a lot of time compared to starting with the entire user story and leave testing at the very end of the iteration. Tackling one small chunk of the user story at a time also helps to spread out the functional testing effort.


See How You Can Write Tests Without Code


Functional Testing vs Non-functional Testing: Key Differences

While indeed accounting for a major part of any test plan, functional testing should not be the only testing type your team performs. Non-functional testing is the much needed counterpart to functional testing, and it nicely covers what functional testing misses.

1. What is Non-functional Testing?

Non-functional testing is a type of software testing that focuses on evaluating the non-functional such as the system's performance, reliability, and stability.

Put simply, when doing functional testing, testers try to answer the question Can the system do what it was built to do?. When doing non-functional testing, testers try to answer the question Can the system do what it was built to do well enough?

Here are 5 non-functional test cases for you to better understand the concept:

  1. Measure the response time of the system under normal load conditions.
  2. Simulate concurrent user connections to determine how the system performs under heavy load, checking for response time degradation or failures.
  3. Conduct usability testing with actual users to gather feedback on navigation, intuitiveness, and overall user experience.
  4. Assess the system's ability to handle an increased workload by gradually increasing the load and observing performance metrics like CPU and memory usage.
  5. Test user roles and permissions to ensure that users can only access the features and data they are authorized for.

2. What are The Differences Between Functional and Non-functional Testing?

Functional testing primarily focuses on whether the system delivered the output desired. Non-functional testing validates the “hows” of the AUT’s features, performance, security, scalability, etc.


Functional Testing

Non-Functional Testing


To verify if the software functions as intended and meets functional requirements.

To evaluate non-functional attributes like performance, security, usability, and more.


Tests what the software should do.

Tests how well the software performs certain functions or behaves under specific conditions.


Typically focuses on specific features or functionalities.

Covers a broader range of attributes beyond functionality.

Examples of Testing Types

Unit Testing, Integration Testing, System Testing, User Acceptance Testing.

Performance Testing, Security Testing, Usability Testing, Compatibility Testing.

Test Criteria

Pass/fail criteria are often straightforward based on expected outcomes.

Pass/fail criteria may involve thresholds or benchmarks (e.g., response time should be below 2 seconds).

User Focus

Ensures that the software meets user needs and expectations in terms of features.

Ensures that the software meets user needs and expectations in terms of performance, security, usability, etc.

Objective Measurement

Often involves binary outcomes (pass/fail) based on expected behavior.

Often involves quantitative measurements and benchmarks for non-functional attributes.

Tools and Technologies

Functional testing tools may include Selenium, JUnit, TestNG, etc.

→ Check out the top functional testing tools

Non-functional testing tools may include JMeter, OWASP ZAP, LoadRunner, etc.


Types Of Functional Testing and Examples

Functional testing extends from component-level testing all the way to regression testing of existing features. It finds itself in any types of testing involved with a functionality.

1. Unit testing

Unit testing is a type of functional testing executed by developers as they write code and build the application. The purpose of unit testing is to validate the functionality of a unit or component, making sure the desired outputs are generated given a set of inputs. As the most granular test, it sets up a solid foundation for more complicated, integrated, and comprehensive features.

Example: a restaurant needs an app that helps customers order at their tables without a server. The developer would create a unit test to examine the “add to order” function. Other individual functions such as “remove from order” or “submit order” would also go under unit testing.


2. Component testing (Module testing)

Component testing is similar to unit testing because they both isolate a single functionality and validate that individually. However, testing for components at this phase might call for stimulative interactions with sample test data, aka stub and driver.

Example: A healthcare service app has a functionality to help patients schedule to meet with medical professionals of their choice. The component to be tested is how the system displays the “nearby” hospitals or healthcare centers using data from the user’s GPS. To test for this function, the user’s profile is the stub and the driver is the available schedules from the health care provider.


3. Integration Testing

integration testing as a type of functional testing

While modules and components can pass individually, quality engineers still need to ensure their functionalities as a group. Since a system’s modules and components are commonly built separately by different developers, integration testing is critical to validate that they work together correctly. 

Modern software infrastructure often includes microservices that communicate with one another. These communications need to be included in integration testing and ensured that they operate properly. 

Example: A banking app has a function where users can set up a saving account. It includes a money-transferring capability from their main account to the saving account. As they are separate modules, testers need to perform integration testing to ensure that the transactions happen smoothly and correctly between the two. 


4. System testing

As the name suggests, in this phase, the software is tested as a complete, integrated system to verify that all business and functional requirements are met. Hence it is also referred to as end-to-end testing and often occurs right before User Acceptance Testing. 

To yield correct validation, the test environment for system testing needs to be an accurate replication of the production environment. On top of that, it is performed in the white-box testing method, where testers have no involvement in the development of the system. 

Example: a fitness app was created with capabilities such as setting up and tracking monthly fitness goals, consolidating fitness and wellness metrics, building personalized exercise sessions, and smart-watch integration,... Each of these functions will be assessed individually as well as all together in system testing. 

The types of testing above can be distinguished by their level of granularity. For instance, if you are validating a webpage with the login function, this is how the level of granularity progresses:

  • Unit test: validate the independent function of the login button
  • Component test: validate the entire login page independently
  • Integration test: validate the transition between the login page and other pages
  • System test (end-to-end test): function of the entire webpage

Unit, component, integration and system tests are performed in multiple processes within the software testing life cycle, including regression testing, sanity testing, and smoke testing. 


5. Regression testing


Any new change or feature added to the software can wreck its existing functionalities. Regression testing is performed every time alterations are made to check for the software’s stability and functionalities. Due to its work-intensive nature, regression testing is often automated.

Example: A food delivery app added a function to help users add multiple promotions on top of each other. A regression test needs to be done to make sure the checkout and payment process is not affected.


6. Sanity testing

Similar to regression testing, sanity testing is conducted for a new build with minor bug fixes, or new code added. If rejected in the sanity testing phase, the build will not proceed to further testing. While regression testing checks the entire system after alterations, sanity testing targets specific areas that are affected by the new code or bug fixes only. 

Example: On an e-commerce webpage, users cannot add a particular product to their cart even when the stock is available. After the issue was fixed, sanity testing is performed to ensure that the “add to cart” function is indeed working.


7. Smoke testing 

When a new build is completed, it is handed to the QAs for smoke testing. In this phase, only the most critical and core functionalities are tested to ensure that they yield the intended results. As an early-stage acceptance test, smoke testing adds a verification layer to determine whether or not the new build can proceed to the next stage or needs re-work. 

Example: A utility company built an app with the function to report outages in customers’ homes. This function reports the address and other relevant information as well as notifies the homeowner when a dispatcher is on the way to help. Smoke testing will validate this feature on a fundamental level to assure that when an outage is reported, the correct information is sent so a dispatcher can be there on time. 

Read More: Sanity Testing vs Smoke Testing: Key Differences


Why Automate Functional Testing?

Softwares are powerful. AIs can even paint and write poetry now. If you are not leveraging softwares to test softwares, you are definitely missing out.

Investment into automation testing is the most valuable thing you can do on your testing journey. Functional testing benefits so much from automation. If you embrace TDD, chances are you are writing automated tests so that the dev team can repeatedly re-execute the tests until the feature passes.

Read more: Automated vs. Manual Testing: When and Why?

Automation can also reduce the costs of errors significantly. Teams who adopt test automation can test earlier, fail faster, and is less likely to discover a bug when it is way too deep into the development process. Moreover, it is important to note that functional testing is the second-most commonly automated type of test, after regression testing, according to the State of Quality Report 2024.

functional testing is a good candidate for test automation

Test automation for functional testing increases productivity, collaboration, and visibility among stakeholders and quality engineers. By leveraging a software quality management platform that auto-generates reports, dashboards, and notifications and integrates with project management tools, all parties involved are informed about the product’s latest status, enabling fast and data-driven decision-making. 

With repetitive and time-consuming test cases automated, quality engineers have more time to develop more insightful test scenarios, thoroughly test the product inside-out, and examine the product under edge cases and exploratory testing.


Explore Top Automated Testing Tools


Choosing The Right Tool For Functional Testing Automation

Functional testing plays a crucial role and is tied to many other activities in the software development life cycle. However, teams usually use a number of fragmented tools that solve separate testing needs, which creates a collection of complex, brittle, and hard-to-scale tool-stack for quality management.

In the long term, as products and teams scale, this approach will be the biggest hindrance to continuous growth and shortened time-to-market. The solution is a software quality management platform that assists in all testing activities, from planning, and testing to reporting and releasing.

test execution out of the stages in software testing life cycle

You have 3 options to do functional testing:

Option 1: Build Your Own Testing Framework with Open-Source Libraries

  • Choose an open-source testing library as the foundation.
  • Use libraries, drivers, design patterns, and coding standards to build.
  • Requires coding and testing expertise but offers high customization.
  • Setup time is significant, but it's budget-friendly.
  • Maintenance and issue resolution may extend testing cycles.

Option 2: Single-Point Commercial Automation Testing Tools

  • Commercial tools for specific testing purposes.
  • Great for focused testing but may lack flexibility as needs evolve.

Option 3: Software Quality Management Platforms

  • Integrates all testing functionalities.
  • Streamlines workflows from planning to reporting.
  • Eliminates fragmentation and offers scalability.
  • Initially underutilized but adapts to organizational needs easily.


Shop Around For A Good Functional Testing Tool



Functional Testing in Action

Katalon logo

Now that you have broken down the user stories into small slices, let's see how you can automate them.

To start, you can download Katalon. In Katalon alone, you can do test planning, write tests, manage them in suites, schedule for execution across environments, and generate test summary reports. This comprehensiveness allows for a lot of customization and flexibility, no matter how complex the application under test is.


Download Katalon and Give It A Try


Once you have downloaded and installed Katalon, navigate to File > New > Project. You can choose the type of testing for this project, either web, API, mobile, or desktop app. 

Create a new project in Katalon Studio


You have up to 3 modes of test creation:

  1. No-code: turn on the Record-and-Playback mode, and record your screen, just like how an end-user would. Katalon automatically turns that sequence of actions into an executable test script.
  2. Low-code: leverage the rich library of keywords to craft your test scripts. All you have to do is choose the keyword for the action you want to automate and set the parameters. Switch to Full script mode whenever you want.
  3. Full code: write your test scripts in Groovy. Enjoy the customizability along with the simplicity of No-code and Low-code within your hands.


Interested? Have a look at the demo here:

Moreover, Katalon sets itself apart by incorporating cutting-edge, native AI features to enhance functional testing. Users can autonomously generate test scripts from plain language input or use the "Explain Code" feature to add comments to code snippets for better understanding among stakeholders and team members. Check out our pioneering AI features here.

Do your team need a better solution for functional testing? Start now with Katalon Studio.

Get started now for free