Functional Testing is a process of ensuring quality assurance in software testing. By using Black-Box methods, different pieces of functionality are tested.
Important to QA teams, functional testing is a broad type of testing designed to determine whether an application performs a specified set of business functions.
The easiest way to think of functional testing is to ask yourself the question “does it function?” In other words, “does it work?” This isn’t a test of how something works but only if it successfully follows the instructions given from a business point of view.
The primary characteristic of a functional test is that it checks business requirements or scenarios. Functional tests are tests to make sure that an application correctly follows a set of business logic specifications - that an application does what it is supposed to do. This can comprise of both positive (happy path) tests as well as tests to ensure that rules that are intended to be followed in ideal circumstances are not executed when conditions are not ideal.
To get an idea, let’s look at an example.
Let’s say a website must have a basic method for users to login with the password requirements of having at least 6 characters, at least one capital, and at least one number.
Positive test: A positive functional test will determine whether it successfully takes the above input. Create a password such as “Pa55word”. If it accepts this input, it has passed the positive test.
Negative test: A negative functional test will evaluate what happens if the input supplied does not match specifications. In other words, how does the application handle unexpected data? If you create a password named “password” does it fail? If so, that should pass the negative test.
If there are multiple scenarios, each one should be tested individually. Using our login example, different levels of user permission would be tested in separate functional tests. Do users have access? Do users have the right access? What happens if they don’t? can they access pages they shouldn’t? Is information displayed correct?
Functional testing is how we know whether an application meets business requirements. It is quite possible to get an application that meets smoke test requirements (as in, the most basic function of the feature works and is therefore stable enough for further testing) but still performs in ways that it should not.
Functional testing is essentially a “real world” test of applications. If you write a program which says it will open a door for a person to walk through, a good functional test will make sure that A) the door opens, B) it opens wide enough for someone to walk through, and C) gives them enough time to go through it. It also makes sure that someone cannot walk through the door before it is opened, or that the door cannot open without turning the doorknob, etc.
Functional tests make sure that an application does what it was built to do and doesn’t do what it is not supposed to do or allow things to happen which should not.
Functional testing only tests what an application does and what it is supposed to do, but not how it interacts with its users. To get an understanding of what functional test is or is not, it may be best to show a few examples of non-functional testing.
Non-functional testing tests areas of the app that is independent from the individual features or components of the app, such as performance testing. In our door example before, we wanted to be sure someone could open a door and walk through it. A non-functional test could measure the amount of time that it takes for the user to walk through the door.
Nonfunctional testing measures product behavior and characteristics, such as usability, reliability, accessibility, and performance. For example, a performance test will test the speed, stability, and responsiveness of the software in a real-world environment. It will identify things such as how well it responds when hundreds of users at a time attempt to access an asset in the app. While this type of activity does interact with the functionality of the app, we're measuring the system based on its response to external input.
Usability testing is another form of non-functional testing, measuring how well people can use the software as it is designed to function. This type of test doesn't checks whether the functionality is working, rather it tests if the functionality is effective. It is often done throughout the development of software as a type of real-world sanity test, and can be seen as a type of prerequisite to design, but not to test if the software functions in itself.
Neither of these tests are functional. Other types of non-functional testing include scalability testing, compliance testing, and portability testing.
Functional testing covers a wide range of different testing types, and functional tests can cover both broad and narrow scopes of the system under test. Here’s a brief summary of a few common types of functional tests.
Unit testing is a narrow type of functional testing to determine whether or not individual pieces of code function in the specific method that they were intended. It only looks at the direct interface and a specified method as a standalone unit to make sure it works as designed
Component testing is a little broader than Unit Testing. It looks at any parts of code which take input and generate an expected output. It can include multiple modules, or units.
This is simply a test to make sure that the software will run and not “catch fire” (no smoke, no fire) when it is fired up. It is not particularly broad, but checks to see if the application meets the minimum requirements for functioning in an ideal environment.
Integration testing is a form of testing designed to ensure that different modules of an application work well with each other. Once an application has passed sufficient unit and component testing, integration tests can ensure that components as a group function adequately. The different modules alone can have entirely different purposes and functions, but they should interact together successfully.
Regression testing is a form of testing done after code changes are made to the app under test to ensure that the code changes have not broken or negatively affected the app - either in areas that were directly modified or in seemingly unrelated areas of the app. Regression testing ensures that an entire application is still working as intended after changes have been made, and is well-suited for automation.
Sanity testing is generally considered to be a subset of Regression Testing. If minor modifications are made, it’s a simple test to make sure that the main components are still functioning as designed. It is not as extensive as full regression testing, and is often done manually. It tends to be used when a small change has occurred that is unlikely to affect other areas of the application.
System testing tests the entirety of the application in an environment much like production. It is designed to ensure that the code meets technical, functional, and business requirements set at the beginning of the project.
User acceptance testing is often done by the primary stakeholder in a project, and is a test to ensure that the entirety of an application functions within a real-world environment. It is ideally tested by someone who may not know much about the inner workings of the application to identify if it works the way that an actual user would approach it.
Work from a set of business specifications. Identify desired behavior, and mark down each of the steps. Define the happy path, define what should happen if path is unhappy.
Let’s go back to our door example again. The first “happy path” test you would want to check is “what happens when a person goes to a door? Can they unlock it? Can they turn the doorknob? Can they walk through the doorway? Can they close the door afterward?
After this, you’d construct several tests to make sure what happens if a person tries to open the door prior to unlocking it, etc. We can use the same sort of scenario for a login page on a website. What happens if a good password is entered? What happens if a bad password is entered, etc.
Because coding UI test scripts is often painful and slow to code and quick to become outdated with the speed that many teams ship code today, functional UI tests are often conducted manually. However, mabl intelligent test automation makes functional UI testing easy to automate because of the speed and ease of test creation, and maintainability of test scripts. Using a DevOps-first UI testing solution like mabl should boost up your functional UI test coverage considerably.
See why mabl was named a strong performer in the Forrester Wave: Continuous Functional Test Automation Suites, Q2 2020.