0% found this document useful (0 votes)
14 views

Object Oriented Testing Strategy

Software Configuration Management (SCM) is a critical process in software development, ensuring that changes to software products are tracked, managed, and maintained systematically. Below is a detailed description of slides that might be included in a presentation on SCM:

Uploaded by

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

Object Oriented Testing Strategy

Software Configuration Management (SCM) is a critical process in software development, ensuring that changes to software products are tracked, managed, and maintained systematically. Below is a detailed description of slides that might be included in a presentation on SCM:

Uploaded by

Zakriya Malik
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 26

Object Oriented Testing

Strategy
Objective
The objective of testing, stated simply, is to find the greatest possible number of
errors with a manageable amount of effort applied over a realistic time span.
unit testing focuses on the smallest compilable program unit—the subprogram (e.g.,
component, module, subroutine, procedure).
Once each of these units has been testing individually, it is integrated into a
program structure while a series of regression tests are run to uncover errors due to
interfacing the modules and side effects that are caused by the addition of new units.
Finally, the system as a whole is tested to ensure that errors in requirements are
uncovered.
Unit Testing in the OO Context
Rather than testing an individual module, the smallest testable unit is the
encapsulated class.
We can no longer test a single operation in isolation (the conventional view of unit
testing) but rather, as part of a class
Class testing for OO software is the equivalent of unit testing for conventional
software.Unlike unit testing of conventional software, which tends to focus on the
algorithmic detail of a module and the data that flows across the module interface,
class testing for OO software is driven by the operations encapsulated by the
class and the state behavior of the class.
Hierarchy testing

consider a class hierarchy in which an operation X() is defined for the superclass
and is inherited by a number of subclasses.
Each subclass uses operation X(), but it is applied within the context of the private
attributes and operations that have been defined for each subclass.
Because the context in which operation X() is used varies in subtle ways, it is
necessary to test operation X() in the context of each of the subclasses
Testing a single class as unit testing
class Product {
public: Product(string name, double price) : name(name), price(price) {}
string getName() const { return name; }
double getPrice() const { return price; }
private: string name; double price;
};
// Testing the independent class `Product`
int main()
{
Product p1("Laptop", 1200.50);
std::cout << "Product: " << p1.getName() << ", Price: $" << p1.getPrice() << std::endl; return 0;
}
Integration Testing in the OO Context
Thread-based testing, integrates the set of classes required to respond to one input or
event for the system. Each thread is integrated and tested individually. Regression testing
is applied to ensure that no side effects occur.
use-based testing, begins the construction of the system by testing those classes
(called independent classes) that use very few (if any) of server classes. After the
independent classes are tested, the next layer of classes, called dependent classes, that
use the independent classes are tested. This sequence of testing layers of dependent
classes continues until the entire system is constructed.
Cluster testing is one step in the integration testing of OO software. Here, a cluster of
collaborating classes (determined by examining the CRC and object relationship model)
is exercised by designing test cases that attempt to uncover errors in the collaborations
Examples
In thread-based testing for this "Place Order" process, we would simulate the sequence of steps
triggered by the user's action:

1. User logs in: User::login().


2. Order is created: Order::createOrder() for that user.
3. Payment is processed: Payment::processPayment() for the created order.

Use based Testing


Product - an independent class representing a product.

Order - a dependent class that uses Product.

Invoice - a further dependent class that uses Order and Product.


Cluster Testing
For instance, we might group the User, Profile, and Address classes together since they often
collaborate to manage user data

void updateProfileInfo(int userId, const std::string& newInfo)

void updateAddress(int userId, const std::string& newAddress) {

Test that Profile::updateProfileInfo() and Address::updateAddress() can successfully update


information for the same user.
Validation Testing in an OO Context
At the validation or system level, the details of class connections disappear.
To assist in the derivation of validation tests, the tester should draw upon use
cases that are part of the requirements model.
The use case provides a scenario that has a high likelihood of uncovered errors in
user-interaction requirements
Example of Validation testing
library management system. Imagine we’re validating the Borrow Book feature, which is a typical use case.

System Overview

● User (class): Represents the library user.


● Book (class): Represents a book in the library.
● LibraryAccount (class): Handles borrowing limits, fees, and other account-related actions.
● LibrarySystem (class): Main system class that coordinates actions between users and books.
Validation Testing Steps

1. Define Use Case - Borrow Book:


○ Scenario: A user borrows a book from the library.
○ Steps:
■ The user logs in.
■ The user searches for a book and selects one to borrow.
■ The system checks if the user has borrowing privileges (no overdue books, within borrowing limit).
■ If eligible, the book is marked as borrowed, and the user’s borrowing count is updated.
■ The system confirms the successful borrowing transaction.
2. Design Test Cases Based on Use Case:
○ Test Case 1: Valid borrow action.
■ Input: User with no overdue books, selecting an available book.
■ Expected Output: System displays a confirmation that the book has been successfully borrowed.
○ Test Case 2: User with overdue books tries to borrow.
■ Input: User with an overdue book, attempting to borrow another.
■ Expected Output: System denies borrowing with a message like "You have overdue books. Please return them first."
○ Test Case 3: Borrowing limit exceeded.
■ Input: User has reached the maximum borrowing limit.
■ Expected Output: System displays "Borrowing limit exceeded."
Testing Methods Applicable at Class Level
Random Testing for OO Classes:
Consider a banking application in which an Account class has the following
operations: open(), setup(), deposit(), withdraw(), balance(), summarize(),
creditLimit(), and close() .
minimum test sequence for account
Open•setup•deposit•withdraw•close
A variety of different operation sequences can be generated randomly. For
example:
Test case r1:
open•setup•deposit•deposit•balance•summarize•withdraw•close
Test case r2:
open•setup•deposit•withdraw•deposit•balance•creditLimit•withdraw•close
Partition Testing at the Class Level
Partition testing reduces the number of test cases required to exercise the class in
much the same manner as equivalence partitioning for traditional software.
Input and output are categorized and test cases are designed to exercise each
category
State-based partitioning

● State-based partitioning categorizes class operations based on their ability to change


the state of the class.
● Again considering the Account class, state operations include deposit() and
withdraw().
● nonstate operations include balance(), summarize(), and creditLimit().
● Tests are designed in a way that exercises operations that change state and those
that do not change state separately.
Test case p1: open•setup•deposit•deposit•withdraw•withdraw•close
Test case p2: open•setup•deposit•summarize•creditLimit•withdraw•close
Test case p1 changes state, while test case p2 exercises operations that do not change
state (other than those in the minimum test sequence).
Attribute-based partitioning

Attribute-based partitioning categorizes class operations based on the attributes that


they use.
For the Account class, the attributes balance and creditLimit can be used to define
partitions.
Operations are divided into three partitions:
(1) operations that use creditLimit,
(2) operations that modify creditLimit,
(3) operations that do not use or modify creditLimit.
Test sequences are then designed for each partition.
Category-based partitioning

Category-based partitioning categorizes class operations based on the generic


function that each performs.
For example, operations in the Account class can be categorized in initialization
operations (open, setup), computational operations (deposit, withdraw), queries
(balance, summarize, creditLimit), and termination operations (close).
Interclass Test case design
Test-case design becomes more complicated as integration of the object-oriented
system begins. It is at this stage that testing of collaborations between classes
must begin.
Like the testing of individual classes, class collaboration testing can be
accomplished by applying random and partitioning methods, as well as
scenario-based testing and behavioral testing
This process is called class collaboration testing or multiple class testing.
The direction of the arrows in the figure indicates the direction of messages, and the labeling indicates the
operations that are invoked as a consequence of the collaborations implied by the messages
Multiple Class Testing
Following sequence of steps to generate multiple class random test cases.
● For each client class, use the list of class operations to generate a series of
random test sequences. The operations will send messages to other server
classes.
● For each message that is generated, determine the collaborator class and the
corresponding operation in the server object.
● For each operation in the server object (that has been invoked by messages
sent from the client object), determine the messages that it transmits.
● For each of the messages, determine the next level of operations that are
invoked and incorporate these into the test sequence.
consider a sequence of operations for the Bank class relative to an ATM class
A random test case for the Bank class might be
Test case r3 verifyAcct•verifyPIN•depositReq
In order to consider the collaborators involved in this test, the messages associated with each of the
operations noted in test case r3 are considered. Bank must collaborate with ValidationInfo to execute the
verifyAcct() and verifyPIN(). Bank must collaborate with Account to execute depositReq(). Hence, a new test
case that exercises these collaborations is
Test case r4
verifyAcct [Bank:validAcctValidationInfo]•verifyPIN [Bank: validPinValidationInfo]•depositReq [Bank:
depositaccount]
verifyAcct [Bank: validAcct ValidationInfo] means that when Bank runs verifyAcct, it checks
account validity by working with ValidationInfo.
Tests Derived from Behavior Models
The use of the state diagram as a model that represents the dynamic behavior of
a class.
The state diagram for a class can be used to help derive a sequence of tests that
will exercise the dynamic behavior of the class (and those classes that collaborate
with it).
initial transitions move through the empty acct and setup acct states.
The majority of all behavior for instances of the class occurs while in the working acct state. A final
withdrawal and account closure cause the account class to make transitions to the nonworking acct and
dead acct states, respectively.
The tests to be designed should achieve coverage of every state.
That is, the operation sequences should cause the Account class to make transition through all allowable
states:
Test case s1: open•setupAccnt•deposit (initial)•withdraw (final)•close It should be noted that this sequence
is identical to the minimum test sequence . Adding additional test sequences to the minimum sequence,
Test case s2: open•setupAccnt•deposit(initial)•deposit•balance• credit•withdraw (final)•close
Test case s3: open•setupAccnt•deposit(initial)•deposit•withdraw•accntInfo•withdraw (final)•close
The state model can be traversed in a “breadth-first” manner.
In this context, breadth-first implies that a test case exercises a single transition and that when a
new transition is to be tested only previously tested transitions are used.
Consider a CreditCard object that is part of the banking system. The initial state of CreditCard is
undefined (i.e., no credit card number has been provided). Upon reading the credit card during a
sale, the object takes on a defined state; that is, the attributes card number and expiration date,
along with bank-specific identifiers are defined. The credit card is submitted when it is sent for
authorization, and it is approved when authorization is received. The transition of CreditCard
from one state to another can be tested by deriving test cases that cause the transition to occur.
A breadth-first approach to this type of testing would not exercise submitted before it exercised
undefined and defined. If it did, it would make use of transitions that had not been previously
tested and would therefore violate the breadth-first criterion.
Breadth-First Approach

● The breadth-first approach means testing transitions in a specific order. You start by testing
the simplest, initial transitions before moving on to new transitions that depend on the first
ones.
● For example, with a CreditCard class in the banking system:
○ Initial State: The credit card might start in an "undefined" state (e.g., no number
provided).
○ Transitions:
■ Defined: After reading the card number and expiration date.
■ Submitted: When the card is sent for authorization.
■ Approved: When authorization is received.
○ Breadth-First Testing: You would test each transition one by one, starting from
"undefined" to "defined," and only move to the next state (like "submitted") after
confirming the previous transition works correctly. This helps ensure each part of the
state sequence works properly before testing complex paths.

You might also like