Test Levels & Types
Unit, integration, regression, smoke, exploratory, black box — the different lenses testing gets done through.
A
A/B testing compares two versions of something — a page, a button, a flow — by showing each to a portion of real users and measuring which performs better against a target metric. It's a product and marketing technique more than a QA one, but QA teams often build and verify the infrastructure that runs it.
Acceptance testing checks whether a system meets the agreed business requirements and is ready for delivery, typically the last test level before release. It's a validation activity — confirming the right product was built — often performed by or with input from the actual stakeholders or users the software is for.
Ad hoc testing is informal, unscripted testing performed without a documented test case or plan — a tester simply uses the application, trying to break it based on intuition and experience. It's fast and requires no upfront preparation, but is hard to repeat exactly and easy to under-document.
Alpha testing is internal testing performed by an organization's own employees — often a dedicated QA team — before software is released to any outside users. It happens in a controlled environment and aims to catch major functional issues before the product goes anywhere near real customers.
B
Beta testing releases a near-final version of software to a limited group of real external users before general availability, gathering feedback and surfacing bugs that internal testing missed. It trades control for realism — beta users bring genuine device diversity, usage patterns, and edge cases a QA team can't fully simulate.
Big bang integration testing combines every module of a system at once and tests them together as a whole, rather than integrating and testing incrementally. It's fast to set up but makes failures hard to isolate — when something breaks, there's no way to tell which of the many newly-combined modules caused it.
Black box testing evaluates software purely by its inputs and outputs, with no knowledge of or access to the internal code — the tester treats the system as an opaque box and checks whether it behaves correctly from the outside. Most manual functional and acceptance testing is black box by nature.
C
Compatibility testing verifies that software works correctly across the different environments it might run in — browsers, operating systems, devices, screen sizes, and versions of dependent software. It exists because "works on my machine" is rarely proof it works everywhere a real user might be.
Compliance testing verifies that software meets a specific external standard, regulation, or legal requirement — accessibility law, data privacy regulation, payment card security standards, or an industry-specific certification. Failing it isn't just a bug, it can mean the product legally can't ship in a given market.
Concurrency testing checks whether a system behaves correctly when multiple processes, threads, or users access shared resources at the same time — looking for race conditions, deadlocks, and data corruption that only appear under simultaneous access. Bugs here are notoriously intermittent and hard to reproduce on demand.
Configuration testing verifies that software behaves correctly across different hardware and software configurations — different memory limits, driver versions, peripheral setups, or application config settings. It overlaps with compatibility testing but focuses more on configurable settings than on the outer environment.
Cross-browser testing verifies that a web application renders and functions correctly across different browsers — Chrome, Firefox, Safari, Edge — and their various versions. Browsers implement web standards with small but real differences, so code that works perfectly in one can render or behave differently in another.
D
E
End-to-end testing verifies a complete user workflow across an entire system — every layer from UI through backend services to the database and back — the way a real user would actually experience it. It's the highest-fidelity form of automated testing, and correspondingly the slowest and most expensive to run and maintain.
Exploratory testing is simultaneous learning, test design, and test execution — a tester actively explores the application with a goal or charter in mind, adapting what they test next based on what they discover, rather than following a pre-written script. It's structured improvisation, not random clicking.
F
G
Gorilla testing is a form of aggressive, repeated testing that pounds on a single module or feature intensively — hammering the same functionality over and over, with unusual or extreme inputs — to check its robustness under sustained pressure, rather than covering the system broadly.
Gray box testing combines elements of both black box and white box testing — the tester has partial knowledge of the internal code or architecture (database schema, API contracts, system design) but tests primarily from the outside, the way a user or client would. It's the pragmatic middle ground most real-world testers actually work in.
I
Incremental integration testing combines and tests modules one at a time, or in small groups, gradually building up the full system rather than integrating everything at once. Each step tests the newly added module together with what's already been verified, making it much easier to isolate where a failure came from.
Installation testing verifies that software installs, upgrades, and uninstalls correctly across the environments it's meant to support — checking for missing dependencies, permission issues, correct default configuration, and clean removal without leftover files or broken system state.
Integration testing verifies that two or more separately developed modules or services work correctly together once combined — checking the interfaces and data flow between them, rather than the internal logic of any one piece in isolation. It sits between unit testing and full system testing.
Internationalization testing (often shortened to i18n) verifies that software is built in a way that can support multiple languages and regions without code changes — correct handling of text expansion, character encoding, date and currency formats, and right-to-left languages. It tests the architecture's readiness, not a specific translation.
Interoperability testing verifies that a system can correctly exchange data and work together with other systems, platforms, or software it's meant to integrate with — different vendors' implementations of the same standard, third-party APIs, or legacy systems it needs to communicate with.
L
M
Migration testing verifies that data and functionality transfer correctly when moving from one system, platform, or database to another — checking that no data is lost, corrupted, or misinterpreted, and that the migrated system behaves the same as the original once the migration completes.
Monkey testing feeds an application random, unstructured input — random clicks, random text, random gestures — with no test cases, no plan, and no expected outcome, purely to see if the system crashes or misbehaves under chaotic, unpredictable use. It trades precision for pure crash-resistance coverage.
N
Negative testing deliberately feeds a system invalid, unexpected, or malformed input to verify it fails gracefully — showing a clear error message and staying stable — rather than crashing, corrupting data, or behaving unpredictably. It's the direct counterpart to positive testing, which only checks valid input paths.
Non-functional testing evaluates how well a system performs a function, rather than whether it performs it correctly — covering qualities like performance, security, usability, scalability, and reliability. It answers "how well does it work" where functional testing answers "does it work at all."
P
R
Recovery testing verifies that a system can recover gracefully from a failure — a crash, a lost network connection, a hardware fault, a database outage — and return to normal operation without data loss or corruption. It deliberately induces failure to observe how the system responds.
Regression testing re-runs existing test cases after a code change to confirm that new code hasn't broken previously working functionality. It's not about testing what's new — it's about proving that everything that already worked still works, which is why it's the first thing automation typically targets in a CI/CD pipeline.
Retesting re-runs the specific test cases that previously failed, after a fix has been applied, to confirm the exact reported defect is actually resolved. It's narrower and more targeted than regression testing, which checks that the fix didn't break anything else nearby.
S
Sanity testing is a narrow, focused check that a specific bug fix or small change works as intended and hasn't obviously broken the immediate area around it. It's quicker and shallower than a full regression test, meant purely to confirm "this makes sense" before deeper testing continues.
Smoke testing is a quick pass over a build's most critical functions — can it launch, log in, and load its core screens — run immediately after a new build to decide if it's stable enough to test further. It answers one question fast: is this build broken in an obvious way, or worth spending real testing time on?
System integration testing verifies that an entire system works correctly with other external systems it depends on — third-party APIs, partner services, payment gateways, legacy platforms — as opposed to integration testing between modules built internally on the same team.
System testing evaluates a fully integrated application as a complete, whole system — verifying it meets its specified requirements end to end, in an environment resembling production. It's the level between integration testing (pieces working together) and acceptance testing (does it satisfy the actual business need).
U
Unit testing verifies the smallest testable piece of code — typically a single function or method — in isolation from the rest of the system, usually written by the developer alongside the code itself. It's the fastest, cheapest test level, and forms the base of the test automation pyramid.
Usability testing evaluates how easy and intuitive a product is to use by observing real or representative users attempting real tasks, rather than checking whether features work correctly. It measures user experience directly — confusion, hesitation, and failed attempts are as much a "finding" as a functional bug.
User Acceptance Testing (UAT) is the final validation phase where real or representative end users test the software against their actual business needs, deciding whether it's ready for release. It's typically the last gate before go-live, run after all internal testing is already complete.