19-Soft-A7 Software Development Process · Undated paper
Nivaar worked solution (AI-drafted; not reviewed by a licensed engineer)
National Exams — 04-Soft-A7, Software Process (closed book, two aid sheets, 3 hours). Notes on the paper: eight questions constitute the exam paper; answer FIVE of the eight, and the first FIVE as they appear in the answer book are marked. Each question is of equal value, and each sub-question within a question is of equal value (shown here as 20 marks per question on a 100-mark basis) — this solution answers all eight as a full study resource. Question 3 asks for a Gantt/timeline schedule for a personal address-book application; Question 4 introduces a hospital patient-registration system that Question 5's Function-Point estimate builds on.
Reference texts. Sommerville, Software Engineering, 10th ed., Ch. 2 (Software Processes), Ch. 3 (Agile Software Development), Ch. 5 (System Modeling), Ch. 8–9 (Testing), Ch. 22–23 (Project Management, Configuration Management), Ch. 9 (Software Evolution/Maintenance); Pressman, Software Engineering: A Practitioner's Approach, 9th ed., Ch. 2–3 (Process Models, Agile), Ch. 23–24 (Project Management, Risk Management), Ch. 29 (Function-Point sizing), Ch. 22 (SQA), Ch. 24 (Software Configuration Management); IEEE/ISO 12207 (Software Life Cycle Processes); SWEBOK v4 (Software Engineering Process, Software Configuration Management, Software Maintenance KAs).
Question text not reproduced: the examination questions are © Engineers and Geoscientists BC. Open the official past paper (linked at the top of this page) to read the question, then follow the worked solution below.
Part a) — test cases and test case design. A test case is a specific set of input values, execution preconditions, and an expected output/result, designed to exercise a particular program path or requirement and reveal whether the software behaves as specified. Tasks in test case design include: identifying what to test (from requirements/design, not just code), selecting representative and boundary/edge input values, deriving the expected result independently of the implementation, and organising cases into a reusable test suite. Inputs to test case design are the requirements specification, design models (Question 4's use cases and classes), and the source code itself (for white-box coverage). Outputs are the documented test cases (inputs, preconditions, expected results), a traceability matrix linking each case back to the requirement it verifies, and (once executed) a test log/defect report.
Part b) — differences between the testing levels.
| Test level | Purpose |
|---|---|
| Unit test | Verify one function/method/class in isolation against its own specification (e.g. Bed.checkAvailability()). |
| Component test | Verify one deployable component (a class plus its immediate collaborators) as a self-contained unit, often still using stubs for external dependencies. |
| Integration test | Verify that multiple components interact correctly once combined (e.g. Clerk → Patient → Admission → Bed working together). |
| System test | Verify the complete, integrated system against its functional and non-functional requirements (Question 4's quality requirements) in an environment resembling production. |
| Acceptance test | Verify the system meets the customer's real needs and is fit for operational use, typically run or observed by the customer (Part d). |
Part c) — stubs and drivers in component/integration testing. When a component under test calls another component that is not yet built, tested, or available, a stub stands in for the callee: it accepts the same calls and returns pre-programmed, minimal responses, letting the caller be tested without the real dependency (e.g. a BedStub that always reports "available" so Admission.allocateBed() can be tested before the real Bed component exists). A driver stands in for the caller: it invokes the component under test with controlled inputs and captures its outputs, letting a lower-level component be tested before the real higher-level caller exists (e.g. a test driver that calls registerPatient() directly with a range of inputs, standing in for the not-yet-built UI). Both are necessary because integration and component testing must proceed level by level as the system is built up; without stubs/drivers, no component could be tested until every other component it depends on (or that depends on it) already existed.
Part d) — when reverse engineering is needed within re-engineering, and when it is not. Reverse engineering is the analysis step of a re-engineering project. It examines the existing system's code and data to recover a higher-level description of its design, data model and business rules, without changing the system. The re-engineering process then uses that description for its transforming steps: source-code translation, program-structure improvement, modularisation and data re-engineering (Sommerville Ch. 9). Reverse engineering is needed when the knowledge the transformation depends on exists only in the code. That happens when the documentation is missing, out of date, or no longer matches the implementation, when the original developers have left, or when undocumented business rules must be kept exactly. An example is a legacy registration system whose bed-allocation rules were patched for years without the design documents being updated. Those rules have to be recovered before the system can be restructured or migrated safely. Reverse engineering is not needed when the specification and design documentation are current and consistent with the code, so re-engineering can work forward from them. It is also not needed when the change is a purely mechanical transformation that needs no design understanding (for example, automated translation to a newer language version or re-hosting on new hardware), or when the old system will be discarded and rebuilt from fresh requirements, so none of its internal behaviour has to be preserved. In that last case the work is forward engineering, not re-engineering.