notesonly.in

One notebook for every subject — open it anywhere.

Log in

Software Testing: Unit, Integration and System Testing

Software testing is the process of running a program with the deliberate intent of finding defects before users do. A test case describes an input, the steps to apply it, and the expected result; if the actual result differs, a bug is logged for developers to fix.

It matters because software runs banks, hospitals and aeroplanes, and users abandon apps that crash. Testing is also economics: a bug caught by a unit test costs minutes to fix, while the same bug found by customers costs support tickets, refunds and reputation. Testing does not make software perfect, but it makes it trustworthy.

Key Concepts

  • Unit testing: testing the smallest pieces — individual functions or methods — in isolation, usually by the developer who wrote them, with frameworks like JUnit or pytest.
  • Integration testing: checking that modules work together — does the login module correctly call the database module? This catches interface mismatches unit tests cannot see.
  • System testing: testing the complete, assembled application end to end against its requirements, in an environment like production.
  • Acceptance testing: the customer or product owner verifies the system actually solves their problem before sign-off.
  • Black-box testing: testing from the outside using inputs and outputs only, with no knowledge of the code inside.
  • White-box testing: testing with knowledge of the internals, designing cases to exercise specific branches and paths.
  • Regression testing: re-running old tests after every change to make sure new code did not break working features.

Formulas

  • Statement coverage: (statements executed by tests ÷ total statements) × 100. It measures how much code the tests touch, not how correct it is.
  • Defect density: number of defects ÷ thousands of lines of code (KLOC). Industry-typical released code lands around 1–5 defects per KLOC; the trend matters more than any single number.
  • Test effectiveness: defects found by testing ÷ total defects found (including after release). Higher means testing is catching issues before users do.

Worked Example

A payment module has 240 statements. The test suite executes 204 of them, and testing found 36 defects in 9,000 lines of code. Compute coverage and defect density, then see what improves.

  1. Statement coverage = 204 ÷ 240 × 100 = 85%.
  2. Defect density = 36 defects ÷ 9 KLOC = 4 defects per KLOC.
  3. The team adds tests for the uncovered branches; now 228 statements execute: 228 ÷ 240 × 100 = 95% coverage.
  4. With the new tests, only 18 defects escape to release: 18 ÷ 9 = 2 defects per KLOC — halved.
  5. Lesson: coverage went up 10 points and escaped defects dropped by half, but 95% coverage still did not mean zero bugs — the remaining 5% and plain logic errors can still hide defects.

Common Misconceptions

  • "Testing proves the software has no bugs." As Dijkstra famously noted, testing can show the presence of bugs but never their absence. Confidence grows with testing; certainty does not.
  • "Developers should not test their own code." Developers absolutely should write unit tests — they know the tricky paths. Independent testers add a second, unbiased perspective on top; the two complement each other.
  • "100% coverage means bug-free." Coverage only measures executed lines. A test can execute a wrong formula and still "pass" if nobody asserted the right answer — logic errors slip through any coverage number.

Real-World Applications

  • CI pipelines: every code commit on GitHub or GitLab triggers unit, integration and regression suites automatically before merging.
  • Banking and payments: transaction systems run exhaustive test suites because a single rounding bug can cost millions.
  • Medical devices and aviation: regulated industries require documented system and acceptance testing for certification.
  • Mobile apps: device-fragmentation testing checks the app across screen sizes and OS versions users actually own.

Unit tests guard the bricks, integration tests guard the mortar, and system tests guard the building. Measure coverage and defect density honestly, re-run regression suites relentlessly, and remember that testing buys confidence — the most valuable currency in software.