Unit Testing, Integration Testing, Memory Leaks & Bug Fixing
Idea in plain words
Unit Testing: Testing individual class member functions in isolation (testing edge cases, zero/negative inputs, max bounds).
Explanation
Testing verifies that the software satisfies all initial functional requirements without regressions or security vulnerabilities. In C++, dynamic memory leaks degrade host OS performance over long execution runs, making systematic lifecycle verification a critical project deliverable.
Key points
- Integration Testing: Verifying correct interaction between UI menus, business logic validation, and file persistence storage.
- Boundary Value Analysis: Testing inputs at extreme boundaries (e.g., 0 balance, max array size, end-of-file conditions).
- Memory Leak Detection: Ensuring every heap allocation via new or new[] is paired with an equivalent delete or delete[].
- Defensive Programming: Adding assertions (assert.h) and structured try-catch exception blocks.
Example
Example
Testing file corruption resilience: What happens if the data file is deleted or read-only? The system must gracefully report an error rather than abruptly crash.
Code examples
// Defensive Unit Testing Test-Harness Pattern in C++
#include <iostream>
#include <cassert>
using namespace std;
class Calculator {
public:
static int divide(int a, int b) {
if (b == 0) throw invalid_argument("Zero division");
return a / b;
}
};
void runUnitTests() {
assert(Calculator::divide(10, 2) == 5);
assert(Calculator::divide(-6, 2) == -3);
try {
Calculator::divide(5, 0);
assert(false); // Should not reach here!
} catch (const invalid_argument&) {
// Exception expected and successfully caught!
}
cout << "All automated unit tests passed cleanly!" << endl;
}
Exam questions
- [7 Marks] Differentiate between unit testing and integration testing. Describe test cases for a bank withdrawal function.
- [7 Marks] Explain common memory management errors in C++ (dangling pointers, double-free, memory leaks) and their remedies.