Domain Testing
Domain Testing
What is a Domain?
o In software testing, all program inputs are conceptualized as if they are numbers,
even character strings (by concatenating bits).
o Domain testing aims to verify if the program's classification of these input values is
correct.
o Before performing its core functions, a routine classifies the input (e.g., valid, invalid,
or for specific processing cases).
o Domain testing primarily focuses on this classification aspect rather than the
calculations performed after classification.
o This model typically does not require structural knowledge of the program; only a
consistent and complete specification of input values for each case is needed.
o For every defined domain, there must be at least one path through the routine to
process that case.
o The boundaries of domains are crucial, as they are where most domain-related bugs
tend to occur.
o Each boundary is defined by at least one predicate that specifies which numbers
belong to the domain and which do not.
o A domain can have multiple boundary segments, which are defined by the set of
interpreted predicates traversed on a specific path.
Domain Closure
o A domain boundary is closed if the points on the boundary are included within the
domain.
o Incorrect closure bugs (e.g., using >= when > was intended) are common domain
bugs.
o Refer to the document for the diagram (Figure 4.2: Open and Closed Domains).
Domain Dimensionality
o For example, one variable defines domains on a number line, two variables define
planar domains, and three variables define solid domains.
o Every new predicate effectively slices through previously defined domains, often
dividing them in half.
Nice Domains
o Specified domains, however, can be incomplete (missing input vectors for certain
paths) or inconsistent (contradictory specifications).
Complete: Boundaries span the entire number space, meaning one set of
tests can confirm the boundary regardless of how many domains it borders.
Refer to the document for the diagram (Figure 4.4: Incomplete Domain
Boundaries).
Convex: Any two points on the boundary can be joined by a line, and all
points on that line lie within the domain. Nice domains are convex, whereas
"ugly" ones are not. Phrases like "...except if..." or "...but not..." often
indicate non-convex domains.
Simply Connected: The domain exists as one continuous piece, rather than
being fragmented or interspersed with other domains. Convexity implies
simple connectivity, but not vice-versa.
o Bug frequency is typically lower for nice domains compared to ugly domains.
Ugly Domains
Ambiguities: These are "holes" in the input space, either within domains or
in the spaces between them. Refer to the document for the diagram (Figure
4.7c: Overlapped domains).
o Procedure:
1. Classify potential boundary errors and develop specific test strategies for
each.
2. Select enough test points to cover all recognized types of boundary errors.
3. Eliminate redundant test points by utilizing points that check both a domain
and its adjacent domains.
o Extreme Point: A point that does not lie between any other two distinct points of a
convex domain. Refer to the document for the diagram (Figure 4.10).
o Off Point:
For a closed boundary, an off point is located near the boundary but outside
(in the adjacent domain).
For an open boundary, an off point is located near the boundary but inside
(in the domain being tested).
o Refer to the document for the diagram (Figure 4.11: On points and Off points).
o Generic Domain Bugs: These include closure bugs, shifted boundaries, tilted
boundaries, extra boundaries, and missing boundaries. Refer to the document for
the diagram (Figure 4.12: Generic Domain Bugs).
Closure Bug: Detected by an on point (e.g., using x >= 0 instead of x > 0).
Shifted Boundary: Detected by an off point (if shifted away from the on
point) or by the on point (if shifted towards it).
Extra Boundary: Detected by two off points (one for each new boundary).
Refer to the document for the diagrams (Figure 4.13: One Dimensional
Domain Bugs, Open Boundaries; Figure 4.14: One Dimensional Domain Bugs,
Closed Boundaries).
Refer to the document for the diagram (Figure 4.15: Two Dimensional
Domain Bugs).
o Functional Homogeneity of Bugs: Assumes that a bug will only affect the constant
values in a boundary predicate (e.g., ax >= b becomes cx >= d), not change its
functional form (e.g., to ax^2 >= b).
o Loops: Loops are problematic because each iteration can result in a different
predicate expression, leading to potential changes in domain boundaries.
This section addresses how domain testing principles apply to the interfaces between different
software components during integration.
o Interface testing is a form of integration testing that aims to confirm the correctness
of the interface between two components that have already passed their individual
component tests.
o It assumes that the call sequence is correct and there are no type incompatibilities.
o For each input variable, the goal is to ensure compatible domain spans (the range of
values from smallest to largest) and compatible closures between the caller's range
(output values) and the called routine's domain (input values).
o The caller's range must be compatible with the called routine's domain.
1. Caller domain → caller range (verified during the caller's unit test).
2. Caller range → called domain (this is the core integration test focus).
3. Called domain → called range (verified during the called routine's unit test).
o This refers to how the open/closed nature of boundaries aligns between the caller's
output range and the called routine's input domain.
o Refer to the document for the diagrams (Figure 4.16: Range / Domain Closure
Compatibility; Figure 4.17: Equal-Span Range / Domain Compatibility Bugs).
o While there are twelve ways for caller and called closures to disagree, those where
the caller's boundary is open and the called's is closed are generally not considered
buggy. This simply means the caller won't provide such values, but the called routine
is capable of accepting them.
o Harmless Span Incompatibilities: Occur when the caller's range is a subset of the
called routine's domain. This is not necessarily a bug, especially if the called routine
is designed to be used by multiple callers with varying requirements. Refer to the
document for the diagram (Figure 4.18: Harmless Range / Domain Span
incompatibility bug).
When the called routine's domain has a smaller span than the caller
expects.
When ranges and domains don't align, leading to good values being rejected
or bad values being accepted, potentially causing crashes.
Refer to the document for the diagram (Figure 4.19: Buggy Range / Domain
Mismatches).
o Bugs in interface testing are more likely to involve single variables rather than
complex combinations.
o Test each input variable independently to confirm compatibility of the caller's range
and the called routine's domain span and closure.
o For each variable, this typically involves using one on point and one off point per
boundary.
o It is generally recommended to start with the called routine's domains and generate
test points according to the domain testing strategy used for component testing.
Manual application of this procedure is impractical for more than one variable
without specialized tools.
o Testability refers to the ease with which software can be tested. In the context of
domains, "nice" domain properties significantly enhance testability.
o The limitations of domain testing directly point to factors that make domains harder
to test. These include:
Non-Linear Boundaries: These are far more complex to test than the linear
boundaries typically assumed by most domain testing approaches.
Loops: The dynamic nature of loops, where each iteration can modify
predicate expressions and domain boundaries, poses a significant challenge
to consistent domain definition and testing.
In essence, designing software with "nice" domain characteristics from the outset directly
contributes to its testability, reducing the effort and complexity required for effective domain
testing. Conversely, ignoring these principles leads to "ugly" domains that are difficult to specify,
implement, and, consequently, test.