Rather than being a final step, testing is a continuous quality assurance process embedded across the Software Development Life Cycle (SDLC).
The purpose of testing is to validate that software:
- Matches functional and non-functional requirements
- Works reliably without defects
- Behaves predictably under real-world conditions
- Provides a safe and accessible experience for users
To verify software correctness, teams define test cases, which act as executable proof that requirements were satisfied.
Test Cases
A test case is a documented scenario used to validate a specific behavior of the System Under Test (SUT). Well-written test cases must be clear, deterministic, and traceable to requirements.
A test case contains four essential pillars:
| Component | Description |
|---|---|
| Inputs | The data or events supplied to the system |
| Steps | The exact procedure to execute the test |
| Test Data / Conditions | Environment setup, configurations, or dataset |
| Expected Output | The correct result or behavior the system must produce |
Test cases should be created after requirements are finalized and frozen, ensuring the team is validating a stable specification, not moving targets.
Types of Software Testing
Software testing is categorized into three major branches:
1. Functional Testing
Functional testing ensures that the software behaves according to specified features and workflows. It answers:
- Does the login work?
- Can the user complete the checkout process?
- Does the API return the correct JSON schema?
A dominant technique in functional testing is Black-Box Testing, where the tester verifies the system without inspecting the internal code structure, focusing solely on input → output correctness.
Functional tests can be executed:
- Manually by QA engineers
- Automated using tools such as Playwright, Selenium, Cypress, or Postman
- Accessibility validated to ensure software is usable for all users
Functional testing guarantees that the software is usable, reachable, and behaves correctly from the user perspective.
2. Non-Functional Testing
Non-functional testing validates system characteristics beyond features. It ensures that software meets architectural expectations such as:
- Performance — speed, latency, throughput
- Security — vulnerability resilience, safe failure modes
- Scalability — ability to grow with demand
- Availability — uptime, fault tolerance
- Compatibility — working across different OSs and hardware
It evaluates system behavior under extreme conditions and answers key quality questions:
- What happens under heavy load or stress?
- Can the system support 10,000 users logging in simultaneously?
- Is the system secure against injection, tampering, or unauthorized access?
- Does it behave consistently across Windows, Linux, macOS, iOS, Android?
- Can the system recover from crashes, backups, or disasters?
This level of testing is crucial for ensuring system reliability at scale.
3. Regression Testing
Regression testing validates that new changes do not break existing functionality. It is triggered after:
- Bug fixes
- Feature additions
- Performance improvements
- Dependency updates
- Refactoring
Regression testing ensures stability by confirming that old guarantees remain intact after new code is introduced.