Functional testing
Functional testing is testing that checks whether software does what its requirements say it should: each function is given an input, and the output or behaviour is compared with the specified result. It treats the code as a black box, judging by what the product does rather than how it is built. Non-functional testing, by contrast, checks how well it does it: speed, load, security, accessibility.
The longer version
A functional test starts from a requirement and derives a case: given this input, in this state, the product must produce this result. Logging in with a valid password reaches the dashboard; logging in with an expired one shows a specific message; submitting an order with an empty cart is refused. The tester, or the script, does not read the implementation, so the same case is valid whether the feature was rewritten last week or not. Cases are built from the requirement's boundaries and branches: the valid path, each invalid path, and the edges where one becomes the other.
The contrast is with non-functional testing, which checks qualities rather than behaviours. A functional test asks whether the search returns the right products; a performance test asks how long it takes under load, a security test whether the query can be manipulated, an accessibility test whether a screen reader can operate it. The two are confused because the same flow gets both kinds of test, and because a slow search feels broken. The rule is that functional testing has a specified correct answer for each input; non-functional testing has a threshold. Functional testing also runs at every level: unit, integration, system and acceptance are all functional when they compare behaviour with a requirement.
The practice fails where the requirement is missing or vague. A functional test needs an expected result, and a feature specified as 'the report should look right' has none, so the tester substitutes a guess and the developer disputes the bug. It also fails through coverage that follows the happy path: every valid input tested, no invalid one, and the product ships handling a well-formed order and crashing on a blank postcode. Smoke testing and regression testing select functional cases for particular moments, the build's arrival and the aftermath of a change; user acceptance testing is functional testing done by the people who wrote, or will live with, the requirements.
Common questions
What is the difference between functional and non-functional testing?
Functional testing checks that the software does what its requirements specify: a given input produces the specified result. Non-functional testing checks how well it does it: response time, behaviour under load, security, accessibility and reliability, each against a threshold rather than a correct answer. The same flow usually needs both.
Is functional testing manual or automated?
A functional test is run either way, because it is defined by what it checks, behaviour against a requirement, rather than by who runs it. Functional cases that repeat on every build are usually automated; new features and exploratory sessions are run by people. Manual and automated testing are the two ways of executing the same functional case.
What are the types of functional testing?
Unit, integration, system and acceptance testing are the levels, from a single function up to the whole product judged by its users. Smoke, sanity and regression testing are functional testing at specific moments: on a new build, after a small fix, and after any change. All of them compare behaviour with a specified expected result.
Who performs functional testing?
Developers at the unit level, testing their own functions against the requirement; testers at the system level, working through the product as a user would with cases derived from the specification; and the people who requested the work at the acceptance level. The same case may be executed by a script or a person, and who runs it changes with the level rather than with the kind of testing.
What does a functional test case contain?
The requirement it checks, the preconditions that put the product in the starting state, the input or the steps to take, and the expected result stated precisely enough that pass or fail is a plain comparison. An actual result field is filled in at execution. A case without an expected result is an exploration rather than a test, because nobody can say afterwards whether the product was right.
Bug reports that arrive ready to triage.
Collect replay, console, network and browser context with the Free plan.