L0 · Foundations that don’t expire
L0Reference5 min read

Functional vs non-functional

Does it work, versus how well does it work under conditions nobody planned for. The second category is where the expensive failures live and where the tooling is weakest, which is why four of these layers exist.

A functional requirement says what the product must do. A non-functional requirement, often shortened to NFR, says how well it must do it: how fast, how securely, for how many people, and for whom.

Non-functional requirements are also called quality attributes, and the standard list (ISO 25010) covers performance, security, reliability, usability, accessibility, compatibility and maintainability.

The short version is a door.

Think about a door.

Does it open? That is the functional question, and it has a yes or no answer. A tester can check it in a second.

Now the other questions. Does it open in half a second or four? Does it still work when five hundred people use it in an hour? Is it wide enough for a wheelchair? Can somebody force it from outside? Does it stay shut in a fire?

Every one of those is non-functional, and every one of them is where the expensive failures live.

The terms you will hear

  • Functional requirement. A behaviour: the basket totals correctly, the email sends.
  • Non-functional requirement (NFR). A quality condition: under two seconds, keyboard accessible, encrypted at rest.
  • Quality attribute. The same idea in architecture language. Performance, security, reliability and the rest.
  • Percentile. How the slowest users are measured. A p95 of 3 seconds means 5 in 100 waited longer.
  • WCAG. The accessibility standard most legal requirements point at.
  • Load, soak and spike. Performance tests for normal traffic, sustained traffic and sudden bursts.

The two kinds of question

Functional checks come from the story. Add to basket, apply the code, receive the email. They are the acceptance criteria, and they are what most suites contain.

Non-functional checks come from conditions the story never mentions.

  • Performance. How fast, under what load, at which percentile.
  • Security. Can somebody see or do what they should not.
  • Accessibility. Can it be used with a keyboard, a screen reader, a magnifier.
  • Privacy. What data is stored, for how long, and who can read it.
  • Reliability. What happens when a dependency is slow or gone.
  • Compatibility. Which browsers, devices and screen sizes.

Why these are the expensive ones

A functional bug annoys one person at a time and gets fixed in a sprint.

A non-functional failure arrives all at once and in public. A page that takes nine seconds on a phone loses customers who never file a bug. A form nobody can use with a keyboard is a legal exposure in several countries. A leak of one customer's data to another is a headline rather than a ticket.

They are also structural, so they are expensive to fix late. Performance and security choices are made in the design, which is why a tester who raises them early is worth several who find them at the end.

How to test all four without specialist tools

  1. Performance: measure one journey on a real phone. Load the page, add to basket, check out. Note the seconds. A number beats an impression, and a repeated number beats a single one.
  2. Security: try the boring cases. Log in as one customer and ask for another customer's order by changing the id. It is the cross-account test from jailbreaks and exfiltration. Check whether a logged-out user can reach a private page by pasting the URL.
  3. Accessibility: unplug your mouse. Complete the main journey with the keyboard only. Then run the free axe browser extension. Those two steps catch most of what matters.
  4. Privacy: ask what is stored and for how long. Then look at what you personally copied into a spreadsheet while testing, which is often the real answer.
  5. Reliability: turn something off. Block the payment sandbox, or throttle the network to 3G, and see whether the interface tells the truth about what happened.
  6. Write the numbers into the plan. Once a target exists, it is testable forever, which is what the risk table and the test plan are for.

Functional bugs annoy one customer at a time. Non-functional failures arrive all at once, in public, and are usually decisions rather than defects.

A worked example

For example, here is one afternoon on the gift-card feature at Willow Books, with no specialist tooling at all.

non-functional-afternoon.txt
FEATURE  buy and redeem a gift card       TOOLS  a phone, Chrome, axe

PERFORMANCE (real iPhone, 4G, three runs each)
  balance page          1.4s  1.6s  1.5s      ok
  checkout with card    2.9s  3.1s  6.2s      third run investigated
    -> the 6.2s run happened while the rate service was cold.
       no requirement exists for checkout latency.          GAP

SECURITY (fifteen minutes, no tools)
  changed the order id in the URL to another customer's order
    -> order details displayed                              BUG, critical
  requested a gift card balance for a code I do not own
    -> balance and remaining value shown, no auth needed    BUG
  logged out, pasted the account page URL
    -> correctly redirected                                 ok

ACCESSIBILITY (mouse unplugged, then axe)
  keyboard: could not reach the Apply button on the gift card field
    -> the whole feature is unusable without a mouse        BUG
  axe: 4 issues, 2 serious (contrast on the balance figure,
       missing label on the code input)                     BUG

PRIVACY
  asked where redemption logs go: kept 24 months, includes email
    -> no retention requirement written anywhere             GAP
  my own testing: I had pasted 3 real customer emails into a
    spreadsheet from a production export. Deleted, and raised
    that the export exists at all.                          FINDING

RELIABILITY
  blocked the payment sandbox mid-redemption
    -> spinner forever, no error, card balance already reduced  BUG

Six defects, two gaps and one uncomfortable finding about my own testing habits, in one afternoon, with a phone and a free browser extension. Two of them are the kind that end up in a newspaper.

How to show you know it

  • A number where there was none. "Checkout takes 3.1 seconds on 4G, and no requirement exists." That single line often creates the requirement.
  • A keyboard-only run. Cheap, repeatable, and it finds real exclusions. Worth its own exploratory session.
  • An identifier you changed in a URL. The most valuable fifteen minutes in this topic, every time.
  • A privacy question about your own process. Noticing the customer data in your own spreadsheet is a mark of a professional.

Questions

Are non-functional requirements not somebody else's job?

The targets belong to product and architecture. Noticing that no target exists is testing work, and it is usually the tester who notices, because nobody else runs the journey on a real phone.

Do I need to learn load testing tools?

Later, and only if you own performance. Start by measuring one journey by hand on a real device. Most teams have no number at all, so the first honest number is the valuable one.

How much accessibility testing can I do without training?

More than you would expect. Keyboard-only navigation plus an automated checker covers a good share of common failures. Screen reader testing takes practice and is worth learning next.

Where do I record all this?

In the plan as targets, and in the summary as results. Anything without an owner and a number quietly becomes nobody's problem, which is exactly how these failures reach production.