Types of Software Testing: A Map for Small Teams

Unit, integration, system and acceptance testing are levels; regression, smoke, performance, security, accessibility and exploratory testing are types. A one-page map of what each one checks, who runs it, what to automate, and which three to start with when a small team has none.

7 min read

The types of software testing sort along two axes. The first is the level, meaning how much of the system a test covers: unit tests check one small piece of code, integration tests check pieces working together, system tests check the whole product, and acceptance tests check whether the people paying for it will accept it. The second is the type, meaning what quality the test looks for: correct behavior (functional testing), or speed, security and accessibility (non-functional testing). Regression, smoke and exploratory testing are ways of choosing and running tests at any level. A small team with no tests should start with three: unit tests on the logic that would hurt most if it broke, a smoke test after every deploy, and a short regression list before each release. The one-page map is below.

Test levels: unit, integration, system, acceptance

The ISTQB glossary, the vocabulary most testing certifications use, defines each level by what it focuses on, and the levels stack from small to large.

  • Unit testing: the smallest part of code that can be tested in isolation, usually a function or a class. Written by developers, run in seconds, run on every change. The full guide is unit testing.
  • Integration testing: the interactions between components or systems, such as your code and its database, or your app and a payment provider’s test environment. Slower than unit tests, and the place where wrong assumptions about someone else’s API surface.
  • System testing (opens in a new tab): ISTQB’s definition is verifying “that a system as a whole meets specified requirements.” This is the whole app, deployed somewhere that looks like production, driven the way a user would drive it.
  • Acceptance testing: deciding whether to accept the system. For most teams that is user acceptance testing, run by the people who will use the software; the UAT checklist covers entry and exit criteria and sign-off. Each test there traces back to acceptance criteria written before the work started.

Functional vs non-functional testing

Functional testing asks whether the software does what it should: the discount applies, the email sends, a normal user cannot open the admin page. Non-functional testing asks how well it does it: how fast, how securely, how accessibly, how reliably under load. Both happen at every level. A unit test can check a calculation (functional) or that a function finishes in under a millisecond (non-functional), and a system test can check a checkout flow or how that flow behaves with 500 people in it at once.

The other kinds of software testing you will hear about

  • Regression testing: re-testing what already worked, after a change, to catch what the change broke somewhere else. Scope and a checklist are in the regression testing checklist.
  • Smoke and sanity testing: a few minutes of broad, shallow checks that a build or deploy works at all, and a narrow check of one area after a small fix. The terms are used inconsistently; smoke testing vs sanity testing sorts them out and gives a post-deploy checklist.
  • Performance testing: response time, throughput and errors under load, including load, stress, spike and soak tests. See performance and load testing.
  • Security testing: whether the software resists misuse. NIST’s Secure Software Development Framework (SP 800-218) (opens in a new tab), version 1.1, lists reviewing code and testing executable code for vulnerabilities as separate practices, with dynamic vulnerability testing, fuzz testing and penetration testing among the examples, and asks that the issues found be recorded in the team’s issue tracking system.
  • Accessibility testing: whether people using a keyboard, a screen reader or magnification can use the product. Testing to the W3C’s WCAG 2.2 (opens in a new tab) at Level AA covers the 2.0 and 2.1 AA levels that US rules cite; automated scanners help, but a person with a keyboard still has to try it.
  • Exploratory testing: ISTQB describes exploratory testing (opens in a new tab) as tests designed and run on the fly, based on the tester’s knowledge and what the previous tests showed. It finds the bugs nobody thought to write a case for. A bug bash is exploratory testing done by the whole team at once.

Manual vs automated, and the test pyramid

Automate what repeats exactly and has a clear pass or fail: calculations, permissions, API responses, the sign-in flow. Keep for people what needs judgment: layout, wording, a new device, and exploratory sessions. Most teams end up with thousands of automated checks and a short manual list.

The test pyramid says how to split the automated part. As Martin Fowler tells it in his Test Pyramid (opens in a new tab) article, Mike Cohn popularized the idea in his 2009 book Succeeding with Agile: many fast unit tests at the bottom, fewer service-level tests in the middle, and only a handful of end-to-end tests through the user interface at the top. The reason is cost. Fowler describes tests through the UI as slow, brittle and expensive to write, so a suite built mostly from them takes too long to run and breaks on every redesign. He calls the upside-down version, mostly UI tests and few unit tests, an ice-cream cone.

Treat the pyramid as a direction, not a quota. A thin web app that mostly moves data between a form and an API may get more value from integration tests than from unit tests. The point is to push each check down to the cheapest level that can still catch the bug.

The one-page map

Types of software testing at a glance
TYPE           CHECKS                              WHO          WHEN                 AUTOMATE?
-------------  ----------------------------------  -----------  -------------------  ---------
Unit           one function or class, isolated     developer    every change         yes
Integration    pieces together: DB, APIs, queues   developer    every change / PR    yes
System         whole app, prod-like environment    QA / team    before release       mostly
Acceptance     does it meet the agreed criteria    users        before release       partly
Regression     what worked still works             QA / CI      every release        mostly
Smoke          is this build or deploy alive       CI / deployer after every deploy  yes
Sanity         one fixed area, quick and narrow    whoever fixed after a small fix   either
Performance    speed and errors under load         developer    before big launches  yes
Security       resists misuse; no known vulns      dev / expert every change + yearly partly
Accessibility  keyboard, screen reader, contrast   QA / team    every release        partly
Exploratory    what nobody wrote a case for        anyone       new features         no

Which testing to start with

If your team has no tests at all, do not start with a framework debate. Start with the three that pay back fastest, in this order.

  1. A smoke test after every deploy. Five to ten checks that the site loads, sign-in works and the one action your product exists for still completes. It catches the worst failures within minutes of shipping them.
  2. Unit tests on the riskiest logic. Money, dates, permissions and anything with a formula. Add a test each time you fix a bug in that code, so the bug cannot come back unnoticed.
  3. A short regression list before each release, run by a person until it is stable enough to automate.

Then wire the automated part into your pipeline so nobody has to remember to run it; what a CI/CD pipeline is covers where tests sit in the stages. Add performance testing before a launch you expect to be busy, accessibility checks into the QA checklist you already run before releases, and a security review on a schedule. Write down which tests a task must pass before anyone calls it finished; that is part of a definition of done.

Recording what was tested

fenbs does not run tests and has no CI integration or test-run tracking; your test runner and pipeline do that. What it holds is the record on each task. Every task has a test status (Not tested, Tested, Partly tested, Failed, or Needs owner check for what only a person can confirm, such as a real payment) and test notes saying what was checked, where, and what was not. AI assistants connected over MCP set the same fields as testStatus and testNotes, so a card in Completed says how it was verified, whoever moved it. If your team agrees on a rule such as “every bug fix ships with a unit test”, put it on the Decisions and rules page; every connected AI assistant reads the rules first.

Related

Writing a single case well: test case template. Filing what testing finds: bug report template. Checking work an assistant produced: reviewing AI-generated code. A board set up for bugs: bug tracker template.

Questions people ask.

What are the main types of software testing?

By level: unit, integration, system and acceptance testing. By what they check: functional testing for correct behavior, and non-functional testing for performance, security, accessibility and reliability. Regression, smoke, sanity and exploratory testing describe how tests are chosen and run, and apply at any level.

What is the difference between functional and non-functional testing?

Functional testing checks what the software does, such as whether a discount applies or a permission is enforced. Non-functional testing checks how well it does it, such as how fast it responds, how it behaves under load, and whether it is secure and accessible.

What is the test pyramid?

A model for splitting automated tests: many fast unit tests at the bottom, fewer service or integration tests in the middle, and a small number of slow end-to-end UI tests at the top. Martin Fowler credits Mike Cohn with popularizing it in his 2009 book Succeeding with Agile.

Which type of testing should a small team start with?

A smoke test after every deploy, unit tests on the riskiest logic such as money, dates and permissions, and a short regression list before each release. Add performance, accessibility and security testing as the product and its users grow.

Start with one thing.

There is nothing to set up first. Write one line and you’ve started.