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
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.
- 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.
- 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.
- 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.