0% found this document useful (0 votes)
5 views20 pages

Software Engineering Study Guide - MD

This study guide assists students in preparing for their software engineering final exam, covering key topics such as Agile (Scrum), design principles, and testing methodologies. It includes detailed explanations of Scrum roles, events, and artifacts, as well as design concepts like class diagrams and sequence diagrams. Additionally, the guide provides conceptual and scenario-based problems with solutions to reinforce understanding of the material.

Uploaded by

amnashoukat140
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views20 pages

Software Engineering Study Guide - MD

This study guide assists students in preparing for their software engineering final exam, covering key topics such as Agile (Scrum), design principles, and testing methodologies. It includes detailed explanations of Scrum roles, events, and artifacts, as well as design concepts like class diagrams and sequence diagrams. Additionally, the guide provides conceptual and scenario-based problems with solutions to reinforce understanding of the material.

Uploaded by

amnashoukat140
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Software Engineering Final Exam Study

Guide

Introduction
This study guide is designed to help students prepare for their software engineering final
exam. It covers key concepts, principles, and practices across various topics, including Agile
(Scrum), Design (Class Diagrams, Sequence Diagrams, Architectural Patterns), Design
Quality (Coupling & Cohesion, Design Patterns), and Testing (Black Box, White Box/Control
Flow). The guide provides conceptual explanations, scenario-based problems with
solutions, and tutorials for creating relevant diagrams.
1. Agile (Scrum)
Agile is an iterative and incremental approach to software development that emphasizes
collaboration, customer feedback, and adaptability to change. Scrum is a popular
framework within Agile that provides a structured yet flexible way to manage complex
projects.
Core Concepts of Scrum
Scrum operates on the principles of transparency, inspection, and adaptation. It breaks
down development into fixed-length iterations called Sprints, typically lasting 2-4 weeks.
Each Sprint aims to deliver a potentially shippable increment of the product.
Scrum Roles
Scrum defines three primary roles, each with distinct responsibilities:
• Product Owner: Responsible for maximizing the value of the product resulting from the
work of the Development Team. This includes managing the Product Backlog,
prioritizing items, and ensuring clear communication of product goals.
• Scrum Master: A servant-leader who ensures that Scrum is understood and enacted.
The Scrum Master facilitates Scrum events, helps the team remove impediments, and
coaches the team and organization on Scrum practices.
• Developers: A self-organizing, cross-functional team responsible for delivering a
potentially shippable Increment at the end of each Sprint. They are responsible for
designing, building, and testing the product.
Scrum Events
Scrum prescribes specific events to create regularity and minimize the need for other
meetings:
• Sprint Planning: An event where the Scrum Team collaborates to define the work to be
performed in the upcoming Sprint. It answers
what will be delivered in the Increment and how that work will be achieved.
• Daily Scrum: A 15-minute time-boxed event for the Developers to synchronize activities
and create a plan for the next 24 hours. It inspects progress toward the Sprint Goal and
adapts the Sprint Backlog as necessary.
• Sprint Review: Held at the end of the Sprint to inspect the Increment and adapt the
Product Backlog if needed. The Scrum Team and stakeholders collaborate on what was
done in the Sprint and what has changed in their environment.
• Sprint Retrospective: An opportunity for the Scrum Team to inspect itself and create a
plan for improvements to be enacted during the next Sprint. It focuses on processes,
tools, and interactions.
Scrum Artifacts
Scrum's artifacts represent work or value to provide transparency and opportunities for
inspection and adaptation:
• Product Backlog: An ordered list of everything that might be needed in the product
and is the single source of requirements for any changes to be made to the product.
• Sprint Backlog: A set of Product Backlog items selected for the Sprint, plus a plan for
delivering the product Increment and realizing the Sprint Goal.
• Increment: The sum of all the Product Backlog items completed during a Sprint and all
previous Sprints. It must be usable and meet the Scrum Team's Definition of Done.
Conceptual Problems - Agile (Scrum)
Problem 1.1: Explain the primary difference between the Product Owner and the Scrum
Master roles in a Scrum team.
Solution 1.1: The Product Owner is responsible for what the team builds, focusing on
maximizing the value of the product by managing the Product Backlog and prioritizing
features. The Scrum Master is responsible for how the team builds it, ensuring the Scrum
framework is followed, facilitating events, and removing impediments to the team's
progress. The Product Owner is focused on the product, while the Scrum Master is focused
on the process.
Problem 1.2: A development team consistently fails to deliver all planned items by the end
of a Sprint. During the Daily Scrum, team members often report on individual tasks rather
than their progress towards the Sprint Goal. What Scrum event is being misused or
overlooked, and what adjustments would you recommend?
Solution 1.2: The Daily Scrum is being misused. Its purpose is for the Developers to
inspect progress toward the Sprint Goal and adapt the Sprint Backlog as necessary, not just
to report individual task status. The team should focus on collective progress and identify
any impediments to achieving the Sprint Goal. Additionally, the Sprint Planning might be
flawed if the team consistently overcommits. The Scrum Master should coach the team on
proper Daily Scrum practices and facilitate better Sprint Planning to ensure realistic
commitments.
Scenario-Based Problem - Agile (Scrum)
Scenario 1.1: A software company is developing a new e-commerce platform. The Product
Owner frequently adds new, high-priority features to the Product Backlog mid-Sprint,
causing the Development Team to miss their Sprint Goals. The team is becoming
demotivated, and stakeholders are losing confidence in the project's predictability.
Question 1.1: As a Scrum Master, how would you address this situation to restore
predictability and team morale, while still ensuring valuable features are delivered?
Solution 1.1: As the Scrum Master, I would first facilitate a discussion with the Product
Owner and the Development Team, emphasizing the importance of Sprint stability. I would
explain that changes during a Sprint undermine the Sprint Goal and predictability. I would
propose the following actions:
1. Reinforce Sprint Goal Protection: Educate the Product Owner that once a Sprint Goal
is set and the Sprint Backlog is committed, new items should generally not be added to
the current Sprint. If an urgent, high-priority item emerges, it should be discussed with
the Development Team. If the team agrees to pull it into the current Sprint, an
equivalent amount of lower-priority work must be removed to maintain the Sprint's
scope and integrity.
2. Improve Product Backlog Refinement: Encourage more frequent and thorough
Product Backlog Refinement sessions. This ensures that the Product Backlog is well-
ordered, emergent, and contains clear, ready-to-be-developed items for upcoming
Sprints, reducing the likelihood of urgent, unplanned additions.
3. Facilitate Communication: Improve communication channels between the Product
Owner, Development Team, and stakeholders. This could involve inviting key
stakeholders to Sprint Reviews to provide feedback and understand the development
progress, and for the Product Owner to manage their expectations regarding mid-Sprint
changes.
4. Empower the Development Team: Remind the Development Team of their right to say
"no" to changes that threaten the Sprint Goal. The Scrum Master should support the
team in these discussions.
5. Conduct a Sprint Retrospective: Facilitate a Sprint Retrospective focused on the
causes of missed Sprint Goals and demotivation. Encourage the team to identify
solutions and create actionable improvement items for the next Sprint. This could
include refining the Definition of Done, improving estimation techniques, or
establishing clearer communication protocols with the Product Owner.
By implementing these measures, the Scrum Master can help stabilize the Sprints, improve
predictability, and rebuild team morale, ultimately leading to a more effective and
sustainable development process.
2. Design
Software design involves defining the architecture, components, interfaces, and other
characteristics of a system. Effective design is crucial for building robust, maintainable, and
scalable software.
Class Diagrams
Purpose: Class diagrams are a fundamental part of the Unified Modeling Language (UML)
and are used to model the static structure of a system. They depict the classes, their
attributes, operations (methods), and the relationships between them.
Components of a Class Diagram:
• Class: Represented by a rectangle divided into three sections: Class Name, Attributes,
and Operations.
• Name: The name of the class.
• Attributes: The properties or data fields of the class. They can include visibility
(public + , private - , protected # ), name, and type.
• Operations (Methods): The behaviors or functions of the class. They can include
visibility, name, parameters, and return type.
• Relationships: Describe how classes interact with each other.
• Association: A general relationship between two classes, indicating that instances
of one class are connected to instances of another. Can be unidirectional or
bidirectional.
• Aggregation: A specialized form of association representing a
whole-part relationship where the part can exist independently of the whole (e.g., a
Department has Professors ).
•Composition: A stronger form of aggregation where the part cannot exist
independently of the whole (e.g., a House has Rooms ; if the house is destroyed, the
rooms are too).
• Inheritance (Generalization): Represents an "is-a" relationship, where a subclass
inherits attributes and operations from a superclass (e.g., Car is a Vehicle ).
• Realization: Represents an "implements" relationship, where a class implements
the operations defined in an interface.
• Multiplicity: Indicates how many instances of one class are associated with instances of
another class. Common notations include:
• 0..1 : Zero or one
• 1 : Exactly one
• * : Zero or more
• 1..* : One or more
Conceptual Problems - Class Diagrams
Problem 2.1: Differentiate between Aggregation and Composition in UML Class Diagrams,
providing a real-world example for each.
Solution 2.1: Both Aggregation and Composition represent a "whole-part" relationship
between classes, but they differ in the strength of their dependency. Aggregation is a
weaker form, implying that the part can exist independently of the whole. For example, a
Library (whole) can have many Books (parts). If the library ceases to exist, the books can
still exist independently. Composition is a stronger form, where the part cannot exist
without the whole. For example, a Car (whole) has an Engine (part). If the car is destroyed,
the engine typically cannot function independently as part of that specific car.
Problem 2.2: In a Class Diagram, how would you represent a scenario where a Student can
enroll in multiple Courses , and a Course can have multiple Students ? What multiplicity
would you use for each end of the association?
Solution 2.2: This scenario represents a many-to-many association between Student and
Course classes. You would draw an association line between the Student class and the
Course class. At the Student end of the association, the multiplicity would be * (zero or
more courses), and at the Course end, the multiplicity would also be * (zero or more
students). Alternatively, if a student must enroll in at least one course, it would be 1..* at
the Course end, and if a course must have at least one student, it would be 1..* at the
Student end.
Scenario-Based Problem - Class Diagrams
Scenario 2.1: Design a simplified Class Diagram for a university system that includes
University , Department , Professor , and Course entities. Consider the following
relationships:
• A University has multiple Departments .
• Each Department belongs to one University .
• A Department employs multiple Professors .
• Each Professor works for one Department .
• A Professor can teach multiple Courses .
• A Course is taught by one Professor .
Question 2.1: Draw the Class Diagram, including attributes (e.g., name for all, employeeID
for Professor , courseCode for Course ) and appropriate relationships with multiplicities.
Solution 2.1: (This solution will be represented as a diagram in Phase 3. For now, here's a
textual description of the classes and their relationships):
• University Class: name: String
• Department Class: name: String
• Professor Class: name: String , employeeID: String
• Course Class: name: String , courseCode: String
Relationships and Multiplicities:
• University -- (1) owns -- Department (*)
• Department -- (1) employs -- Professor (*)
• Professor -- (1) teaches -- Course (*)
(Note: The actual diagram will be generated in Phase 3.)
Sequence Diagrams
Purpose: Sequence diagrams are UML interaction diagrams that show how processes
operate with one another and in what order. They depict the dynamic behavior of a system
by illustrating the sequence of messages exchanged between objects over time.
Components of a Sequence Diagram:
• Lifeline: Represents an individual participant in the interaction, typically an object or
an actor. It is shown as a dashed vertical line extending downwards from the
participant's rectangle.
• Actor: An external entity that interacts with the system (e.g., a user).
• Object: An instance of a class within the system.
• Message: Represents communication between lifelines. Messages are shown as
horizontal arrows between lifelines. Types include:
• Synchronous Message: A solid arrow with a filled arrowhead. The sender waits for
a response before continuing.
• Asynchronous Message: A solid arrow with an open arrowhead. The sender does
not wait for a response.
• Return Message: A dashed arrow with an open arrowhead, indicating the return of
control or a value.
• Activation Bar (Execution Specification): A thin rectangle on a lifeline, indicating the
period during which an object is performing an action directly or through a subordinate
operation.
• Combined Fragments: Used to model complex interactions:
• Alt (Alternative): Represents an exclusive choice between two or more message
sequences. Only one sequence will be executed.
• Opt (Option): Represents a sequence that is optional and may or may not be
executed.
• Loop: Indicates that a sequence of messages may be repeated multiple times.

Conceptual Problems - Sequence Diagrams


Problem 2.3: Describe a scenario where an asynchronous message would be more
appropriate than a synchronous message in a Sequence Diagram.
Solution 2.3: An asynchronous message is more appropriate when the sender does not
need to wait for an immediate response from the receiver to continue its own processing.
For example, in an online order processing system, when a Customer places an Order , the
OrderService might send an asynchronous message to an EmailService to send an order
confirmation. The OrderService does not need to wait for the email to be sent before it can
continue processing the order (e.g., updating inventory or initiating payment). A
synchronous message would block the OrderService until the email is confirmed as sent,
which is often unnecessary and can lead to performance bottlenecks.
Problem 2.4: Explain the purpose of an "Activation Bar" in a Sequence Diagram.
Solution 2.4: An Activation Bar (also known as an Execution Specification) in a Sequence
Diagram indicates the period during which an object is actively performing an operation. It
visually represents the focus of control or the execution of a method. When an object sends
a message and then performs some processing, an activation bar appears on its lifeline.
When it receives a message and starts processing, an activation bar also appears. It helps to
visualize the call stack and the duration of an object's active participation in an interaction.
Scenario-Based Problem - Sequence Diagrams
Scenario 2.2: A user wants to log in to a web application. The process involves the User
interacting with the Login UI , which then communicates with an Authentication Service . The
Authentication Service validates credentials against a User Database and, if successful, returns
a token to the Login UI , which then redirects the User to the Dashboard .
Question 2.2: Draw a Sequence Diagram illustrating this login process.
Solution 2.2: (This solution will be represented as a diagram in Phase 3. For now, here's a
textual description of the sequence):
1. User enters credentials into Login UI .
2. Login UI sends authenticate(username, password) (synchronous) to Authentication Service .
3. Authentication Service sends validateCredentials(username, password) (synchronous) to User
Database .
4. User Database returns isValid: Boolean to Authentication Service .
5. If isValid is true, Authentication Service returns authToken to Login UI .
6. Login UI redirects User to Dashboard .
(Note: The actual diagram will be generated in Phase 3.)
Architectural Patterns and Styles
Architectural patterns and styles provide proven solutions to recurring architectural
problems. They describe fundamental structural organization schemas for software
systems.
• Layered Architecture (N-tier): Organizes the system into horizontal layers, each with a
specific role. Communication typically flows downwards. Common layers include
Presentation, Business Logic, Application, and Data Access. This promotes separation of
concerns and modularity.
• Client-Server Architecture: A distributed application structure that partitions tasks or
workloads between the providers of a resource or service (servers) and service
requesters (clients). Clients request services, and servers provide them.
• Microservices Architecture: An approach to developing a single application as a suite
of small services, each running in its own process and communicating with lightweight
mechanisms, often an HTTP resource API. These services are built around business
capabilities and can be deployed independently.
• Model-View-Controller (MVC): A software architectural pattern for implementing user
interfaces. It divides an application into three interconnected components:
• Model: Manages the data, logic, and rules of the application.
• View: Presents the data to the user.
• Controller: Handles user input and updates the Model and View accordingly.
• Pipe and Filter Architecture: A processing pipeline where data is transformed by a
series of sequential filters. Each filter takes input, transforms it, and passes it to the next
filter. This is common in data processing and Unix command-line tools.
Conceptual Problems - Architectural Patterns and Styles
Problem 2.5: A company is developing a new social media platform that needs to handle a
large number of concurrent users and allow for independent deployment of features like
user profiles, news feeds, and messaging. Which architectural style would be most suitable,
and why?
Solution 2.5: The Microservices Architecture would be most suitable. This style allows for
the application to be broken down into small, independent services, each responsible for a
specific business capability (e.g., user profiles, news feeds, messaging). This enables
independent deployment, scaling of individual services based on demand, and the use of
different technologies for different services. This approach enhances scalability, resilience,
and agility, which are crucial for a large social media platform with evolving features.
Problem 2.6: Explain the primary benefit of using a Layered Architecture in software
design.
Solution 2.6: The primary benefit of using a Layered Architecture is the separation of
concerns. Each layer has a specific responsibility and interacts only with the layers
immediately above and below it. This modularity makes the system easier to understand,
develop, test, and maintain. Changes in one layer are less likely to impact other layers,
promoting loose coupling and enhancing system robustness.
Scenario-Based Problem - Architectural Patterns and Styles
Scenario 2.3: A legacy desktop application for managing customer records is being re-
architected into a web application. The new application needs a clear separation between
the user interface, business logic, and data storage. The development team wants to ensure
that changes to the user interface do not directly affect the core business rules.
Question 2.3: Which architectural pattern would you recommend for this web application,
and how would it address the team's requirements?
Solution 2.3: I would recommend the Model-View-Controller (MVC) architectural pattern.
MVC inherently separates the application into three distinct components:
• Model: Would contain the core business logic and data management for customer
records. Changes to business rules would primarily affect the Model.
• View: Would be responsible for presenting the customer data to the user through the
web interface. Changes to the UI (e.g., layout, styling) would primarily affect the View.
• Controller: Would handle user input from the web interface, interact with the Model to
retrieve or update data, and then select the appropriate View to display the results.
This separation ensures that changes to the user interface (View) do not directly impact the
business logic (Model), addressing the team's requirement for clear separation and
minimizing the ripple effect of UI changes on core business rules. It also promotes
modularity and testability.
3. Design Quality
Design quality is paramount in software engineering, influencing maintainability,
extensibility, and overall system robustness. Key aspects include managing coupling and
cohesion, and applying established design patterns.
Coupling and Cohesion
Coupling and Cohesion are two fundamental metrics used to evaluate the quality of a
software system's design, particularly concerning its modularity.
• Cohesion: Refers to the degree to which the elements within a module belong together.
High cohesion means that the module's elements are functionally related and work
together to achieve a single, well-defined purpose. It indicates a strong, focused
responsibility for the module. High cohesion is desirable.
• Coupling: Refers to the degree of interdependence between software modules. Low
coupling means that modules are relatively independent of each other, and changes in
one module have minimal impact on others. High coupling, conversely, means modules
are highly dependent, making the system harder to maintain and modify. Low coupling
is desirable.
Conceptual Problems - Coupling and Cohesion
Problem 3.1: A module calculates an employee's salary, generates their payslip, and
updates their attendance record. Is this module exhibiting high or low cohesion? Justify
your answer.
Solution 3.1: This module is exhibiting low cohesion. It is performing three distinct and
unrelated tasks: salary calculation, payslip generation, and attendance record update. A
highly cohesive module should ideally focus on a single, well-defined responsibility. This
module would be better refactored into separate, more cohesive modules, each handling
one of these specific functions.
Problem 3.2: Consider two modules, Module A and Module B. Module A directly accesses
and modifies a private variable within Module B. Is this an example of high or low coupling?
What are the potential drawbacks of this design?
Solution 3.2: This is an example of high coupling, specifically content coupling (the
highest form of coupling). Module A is directly dependent on the internal implementation
details of Module B. The potential drawbacks include:
• Reduced Maintainability: Any change to the private variable in Module B (e.g., its
name, type, or internal logic) would require a corresponding change in Module A,
making maintenance difficult.
• Reduced Reusability: Module B cannot be easily reused in other contexts without also
bringing along Module A, or without Module A being modified.
• Increased Complexity: The interdependencies make the system harder to understand
and debug.
• Fragility: Changes in one part of the system are likely to break other, seemingly
unrelated parts.
Scenario-Based Problem - Coupling and Cohesion
Scenario 3.1: A software system has a ReportGenerator module that directly queries the
database, formats the data, and then sends the formatted report via email. The
EmailSender functionality is embedded directly within the ReportGenerator .
Question 3.1: Analyze the coupling and cohesion of this design. Suggest improvements to
enhance design quality.
Solution 3.1:
• Cohesion Analysis: The ReportGenerator module exhibits low cohesion. It is
responsible for multiple distinct tasks: data retrieval (querying the database), data
formatting, and email sending. These are separate concerns that should ideally be
handled by different, more focused modules.
• Coupling Analysis: The design exhibits high coupling. The ReportGenerator is tightly
coupled with the database (direct queries) and the email sending mechanism
(embedded EmailSender functionality). If the database schema changes, or if the email
sending service needs to be replaced, the ReportGenerator module would require
significant modifications.
Suggested Improvements to Enhance Design Quality:
1. Improve Cohesion: Break down the ReportGenerator into more cohesive modules:
• A DataRetriever module responsible solely for querying the database and returning
raw data.
• A ReportFormatter module responsible for taking raw data and formatting it into a
report.
• An EmailService module responsible for sending emails.
2. Reduce Coupling: Introduce interfaces and dependency injection to decouple the
modules:
• The ReportGenerator (now potentially renamed to ReportOrchestrator ) would depend
on abstractions (interfaces) for DataRetriever and EmailService , rather than concrete
implementations. This way, different implementations can be swapped in without
changing the ReportOrchestrator .
• The ReportFormatter would receive data from the DataRetriever and pass the
formatted report to the EmailService .
By implementing these improvements, the system would become more modular, easier to
maintain, test, and extend, as each module would have a single responsibility and fewer
dependencies on others.
Design Patterns
Design patterns are reusable solutions to common problems in software design. They are
not direct solutions but rather templates that can be adapted to solve specific problems.
The exam focuses on three patterns.
• Singleton Pattern: Ensures a class has only one instance and provides a global point of
access to that instance. This is useful for managing shared resources like a database
connection pool or a configuration manager.
• Conceptual Example: A single Logger instance for an entire application to ensure
all log messages go to the same output stream.
• Observer Pattern: Defines a one-to-many dependency between objects so that when
one object (the subject) changes state, all its dependents (observers) are notified and
updated automatically. This is fundamental to event-driven systems.
• Conceptual Example: A WeatherStation (subject) notifies multiple Display devices
(observers) whenever the weather data changes.
• Factory Method Pattern: Defines an interface for creating an object, but lets subclasses
decide which class to instantiate. It defers instantiation to subclasses. This promotes
loose coupling by removing the need to bind application-specific classes into the code.
• Conceptual Example: A Document class might have a createPage() factory method
that subclasses like DrawingDocument and TextDocument override to create specific
types of Page objects (e.g., DrawingPage , TextPage ).
Conceptual Problems - Design Patterns
Problem 3.3: You are designing a system where there should only ever be one instance of a
ConfigurationManager class, which is responsible for loading and providing application
settings. Which design pattern would you use to enforce this constraint, and why?
Solution 3.3: I would use the Singleton Pattern. The Singleton pattern ensures that a class
has only one instance and provides a global point of access to it. This perfectly matches the
requirement for a single ConfigurationManager instance, preventing multiple, potentially
conflicting, configurations from being loaded or managed simultaneously. It guarantees
that all parts of the application access the same configuration settings.
Problem 3.4: In a stock trading application, multiple user interfaces (e.g., a chart display, a
stock ticker, a portfolio view) need to update whenever the price of a particular stock
changes. Which design pattern would be most appropriate to manage these updates
efficiently, and how would it work?
Solution 3.4: The Observer Pattern would be most appropriate. In this pattern, the Stock
object (the subject) would maintain a list of dependent Observer objects (the user
interfaces like ChartDisplay , StockTicker , PortfolioView ). When the Stock price changes, it
would notify all its registered observers, which would then update themselves accordingly.
This decouples the Stock object from the specific user interfaces, allowing new displays to
be added or removed without modifying the Stock class, and ensures all relevant
components are automatically updated.
Scenario-Based Problem - Design Patterns
Scenario 3.2: A game development company needs to create various types of Enemy
characters (e.g., Goblin , Orc , Dragon ) for different levels of their game. The game engine
should be able to create these enemies without knowing their specific classes at compile
time, allowing for easy addition of new enemy types in the future.
Question 3.2: Which design pattern would you recommend for creating these Enemy
objects, and how would it facilitate the addition of new enemy types?
Solution 3.2: I would recommend the Factory Method Pattern. Here's how it would work:
1. Define a common interface/abstract class for Enemy : This would specify methods
like attack() , takeDamage() , etc., that all enemy types must implement.
2. Create a GameLevel (Creator) abstract class: This class would declare an abstract
createEnemy() method that returns an Enemy object.
3. Create Concrete GameLevel subclasses: For each level or environment that requires
specific enemy types (e.g., ForestLevel , MountainLevel ), a concrete GameLevel subclass
would be created. Each subclass would override the createEnemy() method to return a
specific concrete Enemy type (e.g., ForestLevel might create Goblin s, MountainLevel
might create Orc s).
This pattern facilitates the addition of new enemy types because:
• Decoupling: The GameLevel classes are decoupled from the concrete Enemy classes.
They only interact with the Enemy interface.
• Extensibility: To add a new enemy type (e.g., Dragon ), you would simply create a new
Dragon class implementing the Enemy interface and then create a new DragonLevel (or
modify an existing one) that overrides createEnemy() to instantiate Dragon objects. The
core game engine code that uses the GameLevel to create enemies would not need to
change.
4. Testing
Software testing is a critical phase in the software development lifecycle, ensuring that the
software meets its requirements and is free of defects. It can be broadly categorized into
Black Box and White Box testing.
Black Box Testing
Focus: Black Box Testing, also known as functional testing, focuses on the functionality of
the software without any knowledge of its internal structure, code, or implementation
details. Testers interact with the software through its external interfaces, providing inputs
and observing outputs to verify that it behaves according to specifications.
Techniques:
• Equivalence Partitioning (EP): A technique that divides the input domain of a software
component into partitions of equivalent data. Test cases are then designed to pick one
representative value from each partition. The assumption is that if one value in a
partition works, all values in that partition will work.
• Example: For an age input field accepting values between 18 and 60, partitions
could be: age < 18 (invalid), 18 <= age <= 60 (valid), age > 60 (invalid).
• Boundary Value Analysis (BVA): A technique that focuses on testing at the boundaries
of input partitions. It is often used in conjunction with Equivalence Partitioning. Test
cases are created for values at the minimum, just above the minimum, at the maximum,
and just below the maximum of each valid partition.
• Example: For the age input field (18-60), BVA would test: 17, 18, 19, 59, 60, 61.
Conceptual Problems - Black Box Testing
Problem 4.1: A web form requires a user to enter a quantity for an item, with valid
quantities ranging from 1 to 100. Using Equivalence Partitioning, identify the equivalence
classes and suggest one test case for each.
Solution 4.1:
• Invalid Equivalence Class (Less than 1): e.g., 0
• Valid Equivalence Class (Between 1 and 100): e.g., 50
• Invalid Equivalence Class (Greater than 100): e.g., 101
Problem 4.2: For the same quantity input field (1 to 100), apply Boundary Value Analysis to
suggest test cases.
Solution 4.2:
• Lower Boundary: 0 (invalid), 1 (valid), 2 (valid)
• Upper Boundary: 99 (valid), 100 (valid), 101 (invalid)
Scenario-Based Problem - Black Box Testing
Scenario 4.1: A banking application allows users to transfer funds between their accounts.
The transfer amount must be between $10 and $5000, inclusive. The user's account balance
must also be sufficient for the transfer.
Question 4.1: Using both Equivalence Partitioning and Boundary Value Analysis, propose a
set of black box test cases for the transfer amount input field, ignoring the account balance
for this specific question.
Solution 4.1:
Equivalence Partitioning (EP) Test Cases for Transfer Amount (10-5000):
• Invalid (Amount < 10): e.g., $5
• Valid (10 <= Amount <= 5000): e.g., $1000
• Invalid (Amount > 5000): e.g., $5500
Boundary Value Analysis (BVA) Test Cases for Transfer Amount (10-5000):
• Lower Boundary: $9 (invalid), $10 (valid), $11 (valid)
• Upper Boundary: $4999 (valid), $5000 (valid), $5001 (invalid)
White Box Testing (Control Flow)
Focus: White Box Testing, also known as structural testing or glass box testing, examines
the internal structure, design, and implementation of the software. It involves testing the
code's logic, paths, conditions, and loops to ensure that all parts of the code are exercised
and function correctly.
Key Concepts:
• Control Flow Graph (CFG): A graphical representation of all paths that might be
traversed through a program during its execution. Nodes in the CFG represent basic
blocks (sequences of statements with a single entry and exit point), and edges
represent possible transfers of control.
• Coverage Metrics: Used to measure the thoroughness of white box testing:
• Statement Coverage: Ensures that every executable statement in the code is
executed at least once.
• Branch Coverage (Decision Coverage): Ensures that every branch (e.g., if-else ,
switch , loops) in the code is executed at least once in both its true and false
outcomes.
• Path Coverage: Ensures that every possible path through the program's control
flow graph is executed at least once. This is the strongest but often impractical
coverage criterion for complex programs.
• Cyclomatic Complexity: A software metric used to indicate the complexity of a
program. It is a quantitative measure of the number of linearly independent paths
through a program's source code. It can be calculated from a Control Flow Graph using
the formula: M = E - N + 2P , where:
• M = Cyclomatic Complexity
• E = Number of Edges in the CFG
• N = Number of Nodes in the CFG
• P = Number of connected components (usually 1 for a single program or function).
Conceptual Problems - White Box Testing
Problem 4.3: Consider the following pseudocode:
Plain Text
function calculateDiscount(price, quantity):
if price > 100:
if quantity > 5:
return price * quantity * 0.8
else:
return price * quantity * 0.9
else:
return price * quantity

Draw the Control Flow Graph (CFG) for this function and calculate its Cyclomatic
Complexity.
Solution 4.3: (This solution will be represented as a diagram in Phase 3. For now, here's a
textual description of the CFG and complexity calculation):
CFG Nodes (Basic Blocks):
1. Entry
2. price > 100 (Decision)
3. quantity > 5 (Decision)
4. return price * quantity * 0.8
5. return price * quantity * 0.9
6. return price * quantity
7. Exit
CFG Edges:
• 1 -> 2
• 2 -> 3 (True)
• 2 -> 6 (False)
• 3 -> 4 (True)
• 3 -> 5 (False)
• 4 -> 7
• 5 -> 7
• 6 -> 7
Cyclomatic Complexity Calculation (M = E - N + 2P):
• E (Edges) = 8
• N (Nodes) = 7
• P (Connected Components) = 1
M=8-7+2*1=1+2=3
Therefore, the Cyclomatic Complexity is 3.
(Note: The actual diagram will be generated in Phase 3.)
Problem 4.4: What is the difference between Statement Coverage and Branch Coverage,
and why is Branch Coverage considered a stronger testing criterion?
Solution 4.4:
• Statement Coverage: Measures whether every executable statement in the code has
been executed at least once during testing. It ensures that no line of code is left
untested.
• Branch Coverage (Decision Coverage): Measures whether every branch (or decision
point, like an if statement or a loop condition) in the code has been executed at least
once for both its true and false outcomes. This means testing both the if block and the
else block, or both the loop entry and exit conditions.
Branch Coverage is considered a stronger testing criterion than Statement Coverage
because it ensures that all possible outcomes of decision points are tested. A test suite
achieving 100% statement coverage might still miss bugs if it doesn't execute all branches.
For example, if an if statement's else block contains a critical piece of logic, statement
coverage might pass if only the if block is ever executed, but branch coverage would fail,
highlighting the untested else path.
Scenario-Based Problem - White Box Testing
Scenario 4.2: A function processOrder(orderAmount, isPremiumCustomer) calculates a final
price. If isPremiumCustomer is true, a 10% discount is applied. If orderAmount is greater than
$500, an additional 5% discount is applied (cumulative with the premium discount).
Otherwise, no discounts are applied.
Question 4.2: Design a set of test cases to achieve 100% Branch Coverage for this
processOrder function.
Solution 4.2: To achieve 100% Branch Coverage, we need to ensure that all possible true
and false outcomes of the decision points ( isPremiumCustomer and orderAmount > 500 ) are
exercised. The decision points are:
1. isPremiumCustomer == true (True/False)
2. orderAmount > 500 (True/False)
Here's a set of test cases:
• Test Case 1: Premium Customer, Large Order
• orderAmount = 600 , isPremiumCustomer = true
• Expected outcome: Both discounts applied (10% + 5%)
• Covers: isPremiumCustomer (True), orderAmount > 500 (True)
• Test Case 2: Premium Customer, Small Order
• orderAmount = 100 , isPremiumCustomer = true
• Expected outcome: Only 10% premium discount applied
• Covers: isPremiumCustomer (True), orderAmount > 500 (False)
• Test Case 3: Regular Customer, Large Order
• orderAmount = 600 , isPremiumCustomer = false
• Expected outcome: Only 5% large order discount applied
• Covers: isPremiumCustomer (False), orderAmount > 500 (True)
• Test Case 4: Regular Customer, Small Order
• orderAmount = 100 , isPremiumCustomer = false
• Expected outcome: No discounts applied
• Covers: isPremiumCustomer (False), orderAmount > 500 (False)
This set of four test cases ensures that all combinations of the two decision points are
covered, thus achieving 100% Branch Coverage.
5. Diagram Tutorials and Examples
This section provides tutorials on how to create the diagrams discussed in the study guide,
along with visual examples.
How to Create a Class Diagram
1. Identify Entities: Start by identifying the key classes or entities in your system.
2. Define Attributes and Operations: For each class, list its properties (attributes) and
behaviors (operations).
3. Determine Relationships: Identify how the classes interact. Use association,
aggregation, composition, or inheritance as appropriate.
4. Add Multiplicities: Specify the number of instances involved in each relationship.
5. Draw the Diagram: Use a tool like Lucidchart, [Link], or Mermaid to create the visual
representation.
Example: University Class Diagram

How to Create a Sequence Diagram


1. Identify Participants: List the actors and objects involved in the interaction.
2. Define the Timeline: Arrange the participants horizontally and draw vertical lifelines
for each.
3. Map the Messages: Identify the sequence of messages exchanged between
participants. Use synchronous, asynchronous, and return messages as needed.
4. Add Activation Bars: Indicate when each participant is actively performing an
operation.
5. Use Combined Fragments: Incorporate alt , opt , and loop fragments to model
complex logic.
Example: Login Sequence Diagram

How to Create a Control Flow Graph (CFG)


1. Identify Basic Blocks: Break down the code into sequences of statements with a single
entry and exit point.
2. Identify Decision Points: Locate if , else , switch , and loop conditions.
3. Draw Nodes: Represent each basic block and decision point as a node in the graph.
4. Draw Edges: Connect the nodes with directed edges to represent the possible flow of
control.
5. Calculate Cyclomatic Complexity: Use the formula M = E - N + 2P to determine the
program's complexity.
Example: Control Flow Graph

References
[1] The Scrum Guide
[2] UML Class Diagrams - GeeksforGeeks
[3] Sequence Diagrams - GeeksforGeeks
[4] Software Architecture Patterns - GeeksforGeeks
[5] Coupling and Cohesion - GeeksforGeeks
[6] Design Patterns - Refactoring Guru
[7] Black Box Testing - GeeksforGeeks
[8] White Box Testing - GeeksforGeeks

You might also like