Test Levels Explained — Component, Integration, System, Acceptance
What is each test level responsible for? Learn the scope, objectives, test basis, and typical defects for component, integration, system, and acceptance testing.
This post is part of the ISTQB Foundation Level series. If you’re just getting started, check out Part 1 — What is Software Testing? first.
Why Test Levels Matter
Not all bugs are created equal — and not all bugs are found in the same place.
A logic error inside a single function looks completely different from a broken contract between two microservices, which in turn looks nothing like a business workflow that a real user can’t complete. Each of these defects lives at a different level of the system, and each requires a different kind of test to find it.
Test levels are a way of organizing testing work so that each layer of the software is verified at the right time, by the right people, with the right tools. The ISTQB Foundation Level syllabus (section 2.2) defines four test levels: component testing, integration testing, system testing, and acceptance testing.
Understanding them is not just useful for passing the ISTQB exam — it’s the foundation for building a coherent test strategy on any real-world project.
Component (Unit) Testing — ISTQB 2.2.1
What is it?
Component testing — also called unit testing — is the lowest level. It focuses on verifying individual, isolated components of the software: a single function, class, module, or stored procedure.
“Isolated” is the key word. You are not testing how the component behaves when talking to a database or a third-party API. You are testing the component’s own logic, independently of everything else. Dependencies are usually replaced with test doubles (stubs, mocks, fakes).
Test basis
The test basis for component testing consists of:
- Detailed design documents
- Source code itself
- Data models
- Component specifications
Typical defects found
- Off-by-one errors and boundary condition failures
- Incorrect logic (wrong operator, inverted condition)
- Null / undefined handling
- Incorrect calculations
- Missing error handling for edge cases
Who runs it?
Component testing is typically performed by developers, often as part of a Test-Driven Development (TDD) practice — write the test first, then write the code to make it pass.
Tools
| Language | Common frameworks |
|---|---|
| Java | JUnit 5, TestNG |
| JavaScript / TypeScript | Jest, Vitest |
| Python | pytest, unittest |
| C# / .NET | xUnit, NUnit, MSTest |
| Go | built-in testing package |
Why it matters
Component tests are the fastest and cheapest tests to run. A well-written suite of unit tests gives developers immediate feedback — within seconds of saving a file — on whether their change broke something. This is why the Testing Pyramid places unit tests at the base.
Integration Testing — ISTQB 2.2.2
What is it?
Once individual components work in isolation, you need to verify that they work together. Integration testing focuses on the interactions and interfaces between components or systems.
This is where many real-world bugs live: a component works perfectly on its own, but when it calls another component, the data format is wrong, the API contract has drifted, or a timing issue emerges under load.
Test basis
- Software and system design documents
- Sequence diagrams and interface specifications
- API contracts (OpenAPI / Swagger, Pact)
- Use cases that span multiple components
Typical defects found
- Mismatched data formats between components (e.g., date strings vs. timestamps)
- Incorrect API contracts (wrong field names, missing required fields)
- Authentication/authorization failures at service boundaries
- Race conditions and timing issues
- Incorrect error propagation across components
Integration strategies
There are several classical approaches to deciding which components to integrate and in which order:
| Strategy | How it works | Pros | Cons |
|---|---|---|---|
| Big Bang | Integrate everything at once | Simple to organize | Hard to isolate failures |
| Top-Down | Start from the top of the call hierarchy, stub lower layers | Tests high-level flow early | Stubs can hide lower-layer bugs |
| Bottom-Up | Start from the lowest components, use test drivers above | Real low-level behaviour early | High-level flow tested last |
| Incremental | Add one component at a time in a logical order | Easy to isolate failures | Requires planning |
In modern service-oriented architectures, contract testing (using tools like Pact) has become a popular alternative — each service verifies independently that it honours the contract agreed with its consumers, without needing to deploy the full system.
Tools
- Testcontainers — spin up real databases, message queues, and other dependencies in Docker containers during tests
- Pact — consumer-driven contract testing for APIs and messaging
- WireMock — HTTP mock server for simulating external services
- REST Assured / SuperTest — HTTP-level integration tests
System Testing — ISTQB 2.2.3
What is it?
System testing verifies the complete, integrated system against the full set of functional and non-functional requirements. This is the level where you test “the whole thing” — typically in an environment that resembles production as closely as possible.
Unlike integration testing, which focuses on interfaces, system testing focuses on end-to-end behaviour from the perspective of the entire system. A system test might exercise a user journey from login → search → add to cart → checkout → confirmation email.
Test basis
- System requirements specification (SRS)
- Risk analyses
- Use cases and user stories
- System and user documentation
Typical defects found
- End-to-end workflow failures
- Incorrect system-level calculations and business rules
- Security vulnerabilities in the full system context
- Performance and scalability issues
- Incorrect interactions with external systems (payment gateways, identity providers)
Environment
System tests should run in an environment that mirrors production as closely as possible: same OS, same infrastructure topology, same (or representative) data volumes, same third-party integrations. Running system tests against a stripped-down local setup is a common source of “works on my machine” production incidents.
Functional and non-functional testing
System testing is the level where non-functional testing first becomes fully applicable:
- Performance testing — how fast, how scalable
- Security testing — vulnerability scanning, penetration testing
- Usability testing — is the system easy to use?
- Reliability testing — does it stay up under sustained load?
We’ll cover test types in detail in the next post (Part 5).
Acceptance Testing — ISTQB 2.2.4
What is it?
Acceptance testing is the final level before software is delivered to users or released to production. It answers the question: “Does this system do what the business and users actually need?”
While system testing verifies the system against technical requirements, acceptance testing verifies it against business expectations and real-world usage.
Types of acceptance testing
User Acceptance Testing (UAT) The most common type. Real users or business representatives test the system using realistic scenarios to confirm it supports their workflows. Defects at this stage are often about usability, missing features, or business logic that was misunderstood during development.
Operational Acceptance Testing (OAT) Also called production readiness testing. Verifies that the system is ready to be operated in production: backup and restore procedures work, monitoring is in place, deployments can be rolled back, performance under expected load is acceptable.
Contractual Acceptance Testing Verifies that the system meets the criteria defined in a contract or service level agreement (SLA). Common in outsourced development or government procurement.
Alpha and Beta Testing
| Type | Who tests | Where | Purpose |
|---|---|---|---|
| Alpha | Internal users (employees, QA team) | Developer’s site / controlled environment | Early feedback before release |
| Beta | External users (selected customers) | Users’ own environment | Real-world feedback before GA |
Test basis
- Business requirements
- User stories and acceptance criteria
- Contractual obligations
- Regulatory requirements (GDPR, accessibility standards, etc.)
Comparison Table
| Level | Scope | Typical owner | Speed | Primary confidence |
|---|---|---|---|---|
| Component | Single function / class / module | Developer | Very fast (milliseconds) | Logic correctness |
| Integration | Interactions between components | Developer / QA | Fast–medium (seconds–minutes) | Interface correctness |
| System | Complete end-to-end system | QA team | Slow (minutes–hours) | Full requirements coverage |
| Acceptance | Business workflows and user needs | Business / QA | Slow (hours–days) | Business value delivered |
Common Mistakes at Each Level
Component testing
- Skipping it entirely — “we’ll catch bugs at higher levels.” You won’t, efficiently.
- Testing implementation, not behaviour — tests that break every time you refactor, even when behaviour hasn’t changed.
- Zero assertions — tests that always pass because there’s nothing to fail.
Integration testing
- Using too many mocks — if everything is mocked, you’re not testing integration at all.
- Ignoring asynchronous behaviour — async message queues and event streams need explicit integration tests.
- Not testing unhappy paths — what happens when a downstream service returns 500?
System testing
- Unrealistic test environments — database with 10 rows instead of 10 million, missing third-party integrations.
- Testing only happy paths — production is 90% edge cases.
- No performance baseline — you can’t know if performance has degraded if you never measured it.
Acceptance testing
- Starting UAT too late — finding fundamental misunderstandings in the last week of a project is expensive.
- Wrong testers — UAT performed by developers or testers who know the system too well to spot usability issues.
- No clear acceptance criteria — without explicit criteria, every stakeholder has different expectations.
Conclusion
Each test level exists for a reason:
- Component testing catches logic errors cheaply, immediately, and close to the source.
- Integration testing catches the gaps that appear when components meet.
- System testing verifies the full picture against requirements — functional and non-functional.
- Acceptance testing confirms the business actually got what it asked for.
A mature test strategy covers all four levels intentionally, allocating effort according to risk. The Testing Pyramid is a useful mental model: more unit tests, fewer system tests — not because system tests are less valuable, but because they’re slower and more expensive to maintain.
:::tip[ISTQB Exam Tip] The V-Model is the classic framework that maps each development phase to a corresponding test level. Left side of the V = development (requirements → architecture → design → coding); right side = testing (acceptance ← system ← integration ← component). Each test level’s test basis is the deliverable produced at the corresponding development phase. Knowing this mapping is frequently tested in ISTQB Foundation Level exams. :::
Next up: Part 5 — Test Types: Functional and Non-Functional Testing