1. Purpose of Testing and Model of Software Testing
Purpose of Testing
The purpose of testing in software development is to identify bugs and ensure that the software meets its specifications and requirements. Testing helps in:
- Revealing bugs that cannot be attributed to specific components, thus ensuring overall system reliability.
- Reducing the perceived risk of software failures to an acceptable level, enhancing user confidence.
- Validating that the software performs under different scenarios, including performance and security testing.
- Preventing bugs rather than just detecting them, leading to a more reliable software product.
- Providing critical feedback for developers to improve the software before its release.
Model of Software Testing
The model of software testing includes three main components:
- Environment: This refers to the hardware and software needed for the program to function, including operating systems and utility routines. It is essential to recognize that bugs should not be blamed on the environment since hardware and firmware are typically stable.
- Program: Due to the complexity of most programs, a simplified model is created for testing purposes. If the initial model fails to explain unexpected behaviors, it may need to be adjusted, or the program itself may require modifications.
- Bugs: Bugs are often more complex than anticipated. Testing results may prompt a reevaluation of what constitutes a bug and how they are modeled, emphasizing the need for a realistic understanding of bugs.
2. Detection of Anomalies and Data Flow Anomalies
How Anomalies Are Detected
Anomalies can be detected using static analysis (analyzing source code without execution) or dynamic analysis (monitoring program behavior during execution). Static analysis is effective for detecting issues like uninitialized variables, while dynamic analysis identifies runtime anomalies such as division by zero.
Types of Data Flow Anomalies
Anomalies are represented by two-character sequences (d, k, u), where:
- dd: Suspicious but harmless (redefining without usage).
- dk: Likely a bug (defining without usage).
- du: Normal (define then use).
- kd: Normal (kill then redefine).
- kk: Harmless but suspicious (killing twice).
- ku: Bug (using a killed variable).
- ud: Usually okay (reassigning).
- uk: Normal.
- uu: Normal.
Single-Character Situations
- -k: Possibly anomalous (killing an undefined variable).
- -d: Okay (first definition).
- -u: Possibly anomalous (using an undefined variable).
- k-: Not anomalous (last action is kill).
- d-: Possibly anomalous (defined but unused).
- u-: Not anomalous (used but not killed).
Limitations of Static Analysis
Static analysis struggles with:
- Dead Variables: Determining if a variable is dead or alive is often unsolvable.
- Arrays/Pointers: Dynamic calculations make static validation impossible.
- Concurrency/Interrupts: Interrupts and multitasking complicate anomaly detection.
- False Anomalies: Some anomalies (e.g.,
ku) may not be bugs if the path is unachievable.
Why Static Analysis Isn’t Enough
Static analysis cannot handle:
- Dynamically allocated objects or files.
- Context-dependent anomalies.
- System-level issues like concurrency or interrupts.
Dynamic analysis complements static methods by addressing runtime behaviors and complex scenarios. While static analysis reduces testing effort, both methods are essential for comprehensive anomaly detection.
3. Domain Boundary Bugs for One-Dimensional Domain
Explanation of Domain Boundary Bugs
Domain boundary bugs occur at the edges of input domains where input values transition between domains. In a one-dimensional domain, common issues include:
- Closure Errors: Incorrect boundary definitions, such as confusing
>with≥. - Boundary Shifts: A shifted boundary causes incorrect processing of inputs.
- Missing Boundaries: Undefined boundaries lead to unexpected behavior.
- Extra Boundaries: Unnecessary boundaries complicate the domain unnecessarily.
- Incorrect Assignments: Variables assigned to the wrong domain cause errors.
Testing Strategies for Open and Closed Boundaries
-
Open Boundaries:
- Use an off point inside the domain (e.g., just inside A) to detect boundary shifts or missing boundaries.
- An off point within A can also identify if inputs meant for A are incorrectly processed in B.
- To detect extra boundaries, test two off points near the respective boundaries.
-
Closed Boundaries:
- A test point on the boundary detects closure errors.
- Use off points just outside the domain to validate other anomalies.
- Similar strategies apply as with open boundaries, but off points are placed outside the domain.
These testing techniques ensure proper handling of edge cases by verifying software behavior at, inside, or outside boundaries.

4. How to Convert CFG to Regular Expression? Explain the Steps with an Example.
Converting a Context-Free Grammar (CFG) to a Regular Expression involves simplifying the grammar and deriving an equivalent regular expression that represents the same language. Below are the steps with an explanation and an example.
Steps to Convert CFG to Regular Expression
1. Eliminate Non-Regular Constructs
- Ensure the CFG is in a form that can represent a regular language. A regular language cannot have recursion or nested structures.
- If the CFG contains non-regular constructs, it may not be possible to convert it into a regular expression.
2. Convert CFG to Finite Automata (FA)
- Construct an NFA (Non-Deterministic Finite Automaton) from the CFG:
- Each non-terminal becomes a state.
- Productions define transitions between states.
- The start symbol corresponds to the initial state.
- Add a final state for accepting strings.
3. Simplify the FA
- Minimize the NFA to reduce complexity.
- Remove unreachable or redundant states.
4. Convert NFA to Regular Expression
- Use the State Elimination Method:
- Gradually eliminate intermediate states while preserving paths.
- Replace transitions with equivalent regular expressions.
- Alternatively, use Arden’s Theorem if applicable.
5. Derive the Final Regular Expression
- After eliminating all intermediate states, the remaining transitions will form the regular expression.
Example: Converting CFG to Regular Expression
Given CFG:
S → aA | bB
A → aA | ε
B → bB | ε
Step 1: Represent CFG as an NFA
- States:
S,A,B - Transitions:
- From
StoAona, and toBonb. - From
Ato itself ona, and to a final state onε. - From
Bto itself onb, and to a final state onε.
- From
Step 2: Simplify the NFA
- No unreachable or redundant states exist here.
Step 3: Apply State Elimination Method
- Start eliminating states:
- Eliminate
A:- Transition from
Sto final state viaa*a.
- Transition from
- Eliminate
B:- Transition from
Sto final state viab*b.
- Transition from
- Eliminate
Step 4: Combine Paths
- Combine the two paths:
S → a*a | b*b
Final Regular Expression:
R = a*a + b*b
5. Write a Note on:
Linear and Non-Linear Domain Boundaries
Complete and Incomplete Domain Boundaries
-
Linear Boundaries: Nice domain boundaries are typically defined by linear inequalities or equations. Testing is simplified because:
- A straight line can be determined by two points, a plane by three points, and an n-dimensional hyperplane by ( n+1 ) points.
- Over 99.99% of boundary predicates in practice are either linear or can be linearized through simple variable transformations.
-
Non-Linear Boundaries: These are rare and more complex to handle. Non-linear boundaries do not conform to straight lines or planes, making testing more challenging. Specific methods for handling non-linear boundaries remain largely unexplored due to their infrequent occurrence.

-
Complete Boundaries:
- Span the entire number space from negative to positive infinity across all dimensions.
- Simplify testing as only one set of tests is required to confirm the boundary, regardless of how many domains it bounds.
- Example: A continuous boundary without gaps ensures consistent behavior across all input ranges.
-
Incomplete Boundaries:
- Have gaps or segments where no values exist, complicating testing.
- Can arise due to:
- Unachievable paths corresponding to the boundary.
- Constraints on inputs that prevent certain values from existing.
- Compound predicates defining a single boundary or redundant predicates creating null sets.
- Testing becomes more complex as each segment of the boundary must be tested separately for every domain it bounds.
- Example: Figure 4.4 shows boundaries with gaps (e.g., A and E), requiring additional tests for each segment.

6. Applications of Path Testing
Path testing is a method used to ensure that all possible paths through a program’s code are executed at least once. Here are some applications of path testing:
- Software Verification: Ensures that the software meets the specified requirements and behaves as intended under various scenarios.
- Error Detection: Identifies logical errors and bugs in the code by executing all paths, thus revealing untested paths that may cause failures.
- Performance Evaluation: Analyzes the performance of different paths to identify bottlenecks or inefficient code segments.
- Regression Testing: Ensures that new code changes do not adversely affect existing functionalities by re-executing paths previously tested.
- Security Testing: Assesses software security by executing paths that may lead to vulnerabilities.
- Code Coverage Improvement: Increases code coverage metrics by ensuring that all paths are explored, helping to identify untested code.
- Integration Testing: Validates the interactions between different software components by testing paths that cross module boundaries.
- System Testing: Tests the entire system by executing paths that represent user workflows and scenarios.
7. Categorization of Different Types of Loops
Kinds of Loops
There are three primary kinds of loops with respect to path testing:
1. Single Loops
Single loops can be categorized into three cases based on their minimum and maximum iteration values and whether excluded values exist:
-
Case 1: Zero Minimum, N Maximum, No Excluded Values
- Bypass the loop (zero iterations). If this fails, either there is a bug or zero is not the true minimum.
- Test for negative or invalid loop-control values.
- Test one pass, two passes, a typical number of iterations, one less than the maximum, the maximum, and one more than the maximum.
-
Case 2: Non-Zero Minimum, No Excluded Values
- Test one less than the minimum, the minimum, one more than the minimum, one pass, two passes, a typical value, one less than the maximum, the maximum, and one more than the maximum.
-
Case 3: Single Loops with Excluded Values
- Treat as two sets of tests for ranges without excluded values. For example, if the range is 1–20 but excludes 7–10, test ranges 1–6 and 11–20 separately.
2. Nested Loops
Nested loops significantly increase the number of test cases due to combinations of iterations. A practical tactic to reduce test cases:
- Start with the innermost loop, setting all outer loops to their minimum values.
- Test the innermost loop for minimum, minimum+1, typical, maximum-1, and maximum iterations while keeping outer loops at minimum values.
- Move outward one loop at a time, testing each loop similarly while holding other loops at typical values.
- Finally, test all loops simultaneously.
3. Concatenated Loops
Concatenated loops occur when one loop follows another on a path from entrance to exit.
- If loops cannot be on the same path, treat them as individual loops.
- If they can be concatenated, test them as such, considering their combined behavior.
4. Horrible Loops
Horrible loops involve complex structures such as nested loops, jumps into or out of loops, intersecting loops, hidden loops, and cross-connected loops.
- These structures make iteration value selection for testing challenging and should be avoided due to their complexity.

Loop Testing Time
Testing loops can be time-consuming, especially for extreme values (e.g., Max-1, Max, Max+1):
- Nested Loops: Testing combinations of extreme values leads to long test times. Options include proving that certain extreme cases are not possible in real-world scenarios.
- Concatenated Loops: Testing time increases but is less severe than nested loops.
- Horrible Loops: Testing becomes exponentially more complex due to the unpredictable nature of these structures.
Efficient testing strategies and prioritization of critical cases are essential to manage testing time effectively.
8. Explain the Rules in Path Products and Path Sums?
Path products and path sums are fundamental concepts used in software testing, particularly in analyzing control flow graphs (CFGs) and deriving regular expressions. These concepts help in understanding the flow of execution and detecting anomalies in programs. Below are the rules governing path products and path sums, along with explanations and examples.
1. Path Product
A path product represents the concatenation of edges (or paths) in a control flow graph. It is analogous to string concatenation in formal language theory. The rules for path products are:
Rules:
-
Concatenation:
- If there are two consecutive edges labeled
aandb, their product is represented asab. - Example: Edge
S → Alabeledafollowed by edgeA → Blabeledbgives the path productab.
- If there are two consecutive edges labeled
-
Identity Element:
- The identity element for path products is
ε(epsilon), which represents an empty path. - For any path
P,P · ε = ε · P = P.
- The identity element for path products is
-
Associativity:
- Path products are associative:
(P1 · P2) · P3 = P1 · (P2 · P3).
- Path products are associative:
-
No Commutativity:
- Path products are not commutative, i.e.,
ab ≠ ba.
- Path products are not commutative, i.e.,
2. Path Sum
A path sum represents the union of multiple paths in a CFG. It is analogous to the logical OR operation or set union in mathematics. The rules for path sums are:
Rules:
-
Union Operation:
- If there are two alternative paths labeled
aandb, their sum is represented asa + b. - Example: Two edges from
StoAlabeledaandbgive the path suma + b.
- If there are two alternative paths labeled
-
Identity Element:
- The identity element for path sums is
∅(empty set), which represents no path. - For any path
P,P + ∅ = ∅ + P = P.
- The identity element for path sums is
-
Commutativity:
- Path sums are commutative:
a + b = b + a.
- Path sums are commutative:
-
Associativity:
- Path sums are associative:
(a + b) + c = a + (b + c).
- Path sums are associative:
-
Idempotence:
- Adding the same path multiple times does not change the result:
a + a = a.
- Adding the same path multiple times does not change the result:
3. Combining Path Products and Path Sums
In practice, path products and path sums are combined to represent all possible paths in a CFG. The combination follows these rules:
-
Distributive Law:
- Path products distribute over path sums:
a · (b + c) = a · b + a · c.
Similarly,(a + b) · c = a · c + b · c.
- Path products distribute over path sums:
-
Kleene Star:
- The Kleene star (
*) represents zero or more repetitions of a path.
Example:a*meansε + a + aa + aaa + ....
- The Kleene star (
9. Differentiate Between Testing and Debugging
| Testing | Debugging |
|---|---|
| Testing starts with known conditions, uses predefined procedures, and has predictable outcomes. | Debugging starts from possibly unknown initial conditions, and the end cannot be predicted except statistically. |
| Testing can and should be planned, designed, and scheduled. | Procedure and duration of debugging cannot be so constrained. |
| Testing is a demonstration of error or apparent correctness. | Debugging is a deductive process. |
| Testing proves a programmer’s failure. | Debugging is the programmer’s vindication (justification). |
| Testing, as executed, should strive to be predictable, dull, constrained, rigid, and inhuman. | Debugging demands intuitive leaps, experimentation, and freedom. |
| Much testing can be done without design knowledge. | Debugging is impossible without detailed design knowledge. |
| Testing can often be done by an outsider. | Debugging must be done by an insider. |
| Much of test execution and design can be automated. | Automated debugging is still a dream. |
10. Explain Nice and Ugly Domains
Nice Domains
Nice domains are well-structured and predictable, making testing straightforward. They exhibit properties that simplify boundary analysis and reduce test complexity.
Key Properties:
-
Linear Boundaries:
- Defined by linear inequalities (e.g., (x < 10), (2x + 3y \geq 5)).
- Testing Advantage: Only (n+1) points are needed to define an (n)-dimensional hyperplane.
- Example: A temperature range defined as (0 \leq T \leq 100).

-
Complete Boundaries:
- Span the entire number space ((-\infty) to (+\infty)) in all dimensions.
- Testing Advantage: One test set verifies all domains bounded by the same boundary.
- Example: A voltage input valid for all values except (5V) (a single exclusion).

-
Systematic Boundaries:
- Follow a pattern (e.g., equally spaced lines).
- Testing Advantage: Tests for one boundary can generate tests for others.
- Example: Parallel lines separated by a constant (c).
-
Orthogonal Boundaries:
- Boundaries are perpendicular (e.g., aligned with coordinate axes).
- Testing Advantage: Independent testing (complexity (O(n))).
- Example: Axes-aligned domains (Fig. 4.3).
- Contrast: Non-orthogonal boundaries (e.g., tilted lines) require (O(n^2)) tests (Fig. 4.5).

-
Closure Consistency:
- Boundaries use consistent operators (e.g., all ).
- Example: All domain edges use , avoiding mixtures like and .
-
Convexity:
- Any line between two points stays within the domain.
- Testing Advantage: No “holes” or exceptions.
- Example: A circular domain (non-convex if dented).
-
Simply Connected:
- No disjoint regions or holes.
- Example: A single solid shape (vs. a donut-shaped domain).
Ugly Domains
Ugly domains are complex, ambiguous, or inconsistent, making testing error-prone and time-consuming.
Key Properties:
-
Nonlinear Boundaries:
- Defined by curves or complex equations (e.g., (x^2 + y^2 = r^2)).
- Testing Challenge: Requires more points and dynamic analysis.
-
Incomplete Boundaries:
- Gaps exist (e.g., due to unachievable paths or constraints).
- Example: A temperature sensor skips (20°C) to (30°C).
- Testing Challenge: Each segment must be tested individually (Fig. 4.4).
-
Ambiguities/Contradictions:
- Overlaps: Two domains claim the same input (Fig. 4.7c).
- Closure Conflicts: A boundary assigned to two domains (Fig. 4.7d).
-
Non-Orthogonal Boundaries:
- Boundaries intersect arbitrarily, increasing test cases.
- Example: Tilted grids (Fig. 4.5).
-
Non-convex/Simply Disconnected:
- Concave Domains: Exceptions like “valid except if (x > 5)“.
- Disconnected: Multiple regions (e.g., valid inputs (<10) or (>20)).
11. Explain Transaction Flow Testing Techniques with an Example
Transaction Flow Testing
Transaction flow testing validates the correct flow of transactions through a system. It involves analyzing paths from entry to exit, ensuring all scenarios are covered. This technique is crucial for systems handling multiple transactions, ensuring functionality aligns with requirements.
Key Steps in Transaction Flow Testing
1. Define Transaction Flows
Detailed transaction flows, akin to control flow graphs, are essential for functional testing. These flows outline how transactions move through the system and help identify gaps or ambiguities. System documentation should include an overview of main transaction flows, with detailed representations serving as prerequisites for rational design and testing.
2. Conduct Reviews and Walkthroughs
- Discuss transaction types accounting for 98%-99% of expected system transactions.
- Use functional terms (e.g., “payment processing”) instead of technical jargon.
- Ensure every flow aligns with system requirements.
- Include test cases for loops, extreme values, and domain boundaries.
- Validate transaction “births” (creation) and “deaths” (termination).
3. Path Selection
Select paths using criteria similar to structural path testing:
- Focus on functionally sensible transactions.
- Identify complex, long, or unusual paths from entry to exit.
- Use covering paths (e.g., C1+C2) to ensure comprehensive coverage.
4. Path Sensitization
Sensitization ensures selected paths are valid:
- Most normal paths are easy to sensitize (80%-95% coverage).
- Remaining issues may indicate bugs in transaction flows or design flaws.
5. Path Instrumentation
Instrumentation tracks transaction paths:
- Record path information using central dispatchers or individual modules.
- Monitor paths using system logs or operating system traces.
Example: Online Shopping System
Consider an online shopping system where a user performs the following steps:
- Item Selection: The user selects items.
- Cart Update: The system updates the cart.
- Checkout Process: The user inputs payment and shipping details.
- Order Confirmation: The system confirms the order.

Testing Steps
-
Define the Flow:
- Create a flow diagram: Item Selection → Cart Update → Checkout → Order Confirmation.
-
Select Paths:
- Test normal paths:
- Path 1: User adds an item → checks out → receives confirmation.
- Test edge cases:
- Path 2: User attempts checkout with no items → system rejects.
- Path 3: User abandons checkout → system retains cart.
- Test normal paths:
-
Sensitize Paths:
- Verify system behavior:
- Empty carts during checkout.
- Incomplete transactions do not corrupt data.
- Verify system behavior:
-
Instrumentation:
- Log transaction paths:
- Example: “User added item X → Checked out → Payment successful.”
- Log transaction paths:
-
Validate Results:
- Ensure successful orders are confirmed.
- Handle failed transactions gracefully.
Benefits of Transaction Flow Testing
- Ensures all transaction paths are tested.
- Identifies gaps, ambiguities, and inconsistencies.
- Improves system reliability by validating real-world scenarios.
- Detects design flaws early, reducing rework.
12. Explain the Step-by-Step Procedure for the Node Reduction Algorithm for a Given Labeled Flow Graph?
The Node Reduction Algorithm is used to simplify a labeled flow graph (e.g., a control flow graph) into a single regular expression that represents all possible paths from the start node to the end node. This algorithm is widely used in software testing and analysis to derive path expressions and detect anomalies. Below is a step-by-step explanation of the procedure, along with key concepts and an example.
Step-by-Step Procedure
1. Label the Edges
- Assign labels to all edges in the flow graph. These labels represent actions, conditions, or transitions between nodes.
- If there are multiple edges between two nodes, combine them using the path sum (
+) operator.
Example:
A → B: a
A → C: b
2. Identify Start and End Nodes
- Identify the start node (entry point) and the end node (exit point). The goal is to derive a regular expression for all paths from the start to the end node.
3. Introduce Intermediate Nodes
- Add intermediate nodes if necessary to ensure clarity in the graph structure. Ensure that loops and branches are properly represented.
4. Eliminate Intermediate Nodes
- Gradually eliminate intermediate nodes while preserving the paths. For each node being eliminated:
- Identify all incoming edges (
I) and outgoing edges (O). - Combine these edges using the path product and path sum rules.
- Replace the eliminated node with equivalent transitions.
- Identify all incoming edges (
Formula:
New Transition = I · (Self-loop)* · O
- Here,
Self-looprepresents any loop on the node being eliminated.
5. Repeat Until Only Start and End Nodes Remain
- Continue eliminating intermediate nodes until only the start and end nodes remain. At this stage, the remaining transitions represent the final regular expression.
6. Combine Paths
- Use the path sum (
+) operator to combine all paths from the start node to the end node.
13. How Do Bugs Affect Software? Explain Various Consequences of Bugs
Bugs are flaws or errors in software that can significantly impact its functionality, reliability, and user experience. Their consequences depend on factors such as frequency, correction cost, installation cost, and severity of the issue. Understanding these impacts is critical for prioritizing bug fixes and ensuring robust software quality.
Factors Influencing Bug Importance
-
Frequency:
Frequent bugs disrupt user experience regularly and demand immediate attention. For instance, a recurring crash during a specific operation is more critical than an occasional aesthetic glitch. -
Correction Cost:
The cost of fixing a bug increases dramatically as it progresses through the development lifecycle. Early detection minimizes costs, while late-stage fixes require extensive rework. Additionally, larger systems incur higher correction costs due to their complexity. -
Installation Cost:
For distributed systems, fixing a bug involves distributing patches to numerous users, which can exceed the original development cost. For example, updating millions of devices with a patch is far more expensive than fixing a single-user application. -
Consequences:
The impact of a bug ranges from mild annoyances to catastrophic failures. A reasonable metric for bug importance is:
Consequences of Bugs
The consequences of bugs can be measured on a human-centric scale (1–10), where 1 represents mild issues and 10 signifies catastrophic failures:
-
Mild (1): Aesthetic issues like misspelled outputs or misaligned printouts. These bugs offend visually but rarely affect functionality.
-
Moderate (2): Outputs are misleading or redundant, impacting system performance. For example, a dashboard displaying incorrect data might confuse users.
-
Annoying (3): Dehumanizing behavior caused by bugs, such as truncating names or arbitrarily modifying inputs. These issues frustrate users but don’t cause functional breakdowns.
-
Disturbing (4): The system refuses to handle legitimate transactions. For instance, an ATM failing to dispense cash or a credit card being incorrectly flagged as invalid creates significant user dissatisfaction.
-
Serious (5): Loss of transaction accountability. If the system fails to record a paycheck deposit or a bill payment, it undermines trust and reliability.
-
Very Serious (6): Incorrect transactions occur, such as crediting funds to the wrong account or converting deposits into withdrawals. These bugs have severe financial and operational implications.
-
Extreme (7): Widespread issues affecting multiple users or transaction types. Frequent and arbitrary failures erode confidence in the system.
-
Intolerable (8): Long-term, unrecoverable corruption of databases occurs without immediate detection. Such bugs may force organizations to consider shutting down the system entirely.
-
Catastrophic (9): Complete system failure, leaving no choice but to shut it down. For example, a stock exchange system crashing during trading hours has devastating consequences.
-
Infectious (10): The most severe consequence, where a failed system corrupts other interconnected systems. Examples include cascading failures in power grids, nuclear reactor meltdowns, or cyberattacks spreading malware across networks.
Impact on Users and Systems
- User Satisfaction: Bugs degrade user experience, leading to frustration, loss of trust, and reduced adoption rates.
- System Reliability: Frequent bugs compromise system integrity, making it unreliable for critical tasks.
- Financial Costs: High correction, installation, and consequential costs strain budgets, especially for large-scale systems.
- Reputation Damage: Publicized bugs harm an organization’s reputation, potentially resulting in lost revenue and legal liabilities.
14. Explain the Domain Boundary Bugs for Two-Dimensional Domain
Domain boundary bugs in two-dimensional domains occur when there are errors in defining or implementing boundaries between adjacent domains. These bugs can lead to incorrect processing of inputs, as the system may assign them to the wrong domain. Testing focuses on identifying and resolving these issues by analyzing boundary points (on points), off points, and extreme points.
Types of Two-Dimensional Domain Bugs
-
Closure Bugs:
- A closure bug occurs when the boundary is incorrectly assigned to one domain instead of another. For example, using
x >= kinstead ofx > k. - Detection: On points (points directly on the boundary) are used to detect closure bugs. If the boundary is closed for domain A but open for domain B, an input point on the boundary processed by B instead of A indicates a closure error (Figure 4.15a).
- A closure bug occurs when the boundary is incorrectly assigned to one domain instead of another. For example, using
-
Shifted Boundaries:
- A shifted boundary occurs when the boundary moves up, down, left, or right due to incorrect constants in the predicate. For instance,
x + y >= 17instead ofx + y >= 7. - Detection:
- A shift upward (Figure 4.15b) is detected by the off point (closed off outside).
- A shift downward (Figure 4.15c) is detected by the on points.
- Shifts alter the region of one domain, causing inputs to be processed incorrectly.
- A shifted boundary occurs when the boundary moves up, down, left, or right due to incorrect constants in the predicate. For instance,
-
Tilted Boundaries:
- A tilted boundary arises when coefficients in the boundary inequality are incorrect. For example,
3x + 7y > 17instead of7x + 3y > 17. - Detection: The tilted boundary creates erroneous segments (A’ and B’) and is detected by on points (Figure 4.15d). The left on point often catches this bug.
- A tilted boundary arises when coefficients in the boundary inequality are incorrect. For example,
-
Extra Boundaries:
- An extra boundary is introduced by an additional predicate, slicing through multiple domains and causing widespread test failures.
- Detection: Extra boundaries (Figure 4.15e) are caught by two on points and possibly the off point, depending on the direction of the boundary.
-
Missing Boundaries:
- A missing boundary results from omitting a predicate, merging different domains and causing multiple test failures.
- Detection: Missing boundaries (Figure 4.15f) are identified using on points, as the processing for merged domains (A and B) becomes identical.

Testing Strategy for Two-Dimensional Domains
-
Identify Input Variables:
- Determine the variables involved in domain-defining predicates (e.g., control flow predicates).
-
Interpret Predicates:
- Express all domain predicates in terms of input variables. For
pbinary predicates, there are at most (2^p) combinations of TRUE-FALSE values, leading to (2^p) domains.
- Express all domain predicates in terms of input variables. For
-
Find Non-Null Domains:
- Use Boolean expressions (e.g.,
ABC + DEF + GHI) to represent sets of linear inequalities defining each domain or part of multiply connected domains.
- Use Boolean expressions (e.g.,
-
Solve Inequalities:
- Solve these inequalities to identify extreme points of each domain using linear programming methods.
-
Test Points:
- Test on points, off points, and extreme points to verify boundaries and detect bugs.
15. Write a Note on Open Domain Boundary and Closed Domain Boundary
Introduction to Open and Closed Domain Boundaries
Domain boundaries in software testing are classified as either open or closed based on whether they include their edge points. Understanding these classifications is critical for designing effective test cases and detecting boundary-related bugs.
Open Domain Boundaries
-
Definition:
- An open boundary does not include its edge points. For example,
x < 10excludes the value10.
- An open boundary does not include its edge points. For example,
-
Off Points:
- For open boundaries, off points lie inside the domain being tested. This is summarized by the acronym COOOOI (Closed Off Outside, Open Off Inside).
- Example: If the boundary is
x < 10, an off point might bex = 9.9, which lies within the domain.
-
Testing Open Boundaries:
- To detect bugs like boundary shifts or missing boundaries, test points close to the boundary but within the domain are used.
- For example, in Figure 4.13d, a shift to the right is detected by an off point inside domain A.

Closed Domain Boundaries
-
Definition:
- A closed boundary includes its edge points. For example,
x <= 10includes the value10.
- A closed boundary includes its edge points. For example,
-
Off Points:
- For closed boundaries, off points lie outside the domain being tested.
- Example: If the boundary is
x <= 10, an off point might bex = 10.1, which lies outside the domain.
-
Testing Closed Boundaries:
- Closure bugs are detected using on points (points directly on the boundary). For example, in Figure 4.14, an on point detects faulty closures.
- Off points just outside the domain are used to detect other boundary bugs, such as shifts.

Comparison of Open and Closed Boundaries
| Aspect | Open Boundary | Closed Boundary |
|---|---|---|
| Edge Inclusion | Excludes edge points | Includes edge points |
| Off Point Location | Inside the domain (Open Off Inside) | Outside the domain (Closed Off Outside) |
| Common Bugs | Boundary shifts, missing boundaries | Closure errors, shifted boundaries |
| Testing Strategy | Use off points inside the domain | Use on points and off points outside |
Practical Implications
- Open Boundaries: Useful for scenarios where edge values are invalid or excluded. For example, rejecting inputs above a threshold.
- Closed Boundaries: Suitable for scenarios where edge values are valid and must be included. For example, accepting inputs up to a maximum limit.