2. INRODUCTION
Previously computer program was nothing but just a list of commands called functions
where all data getting stored in one single location which creates problem in testing the
program properly. Object-oriented testing and traditional testing are similar in few
aspects. Like we use unit testing, we perform integration testing to make sure all
subsystems work correctly, we perform system testing to make sure software meets the
specified requirements. Object-oriented programming language has features like
inheritance, polymorphism which is completely new and brought technical challenges for
tester while testing.
3. NEED OF TESTING
Testing is a merry-go-round process which includes a good amount of time along with cost, for all. But
the reality is quite opposite, without testing it is not possible to deliver projects successfully, as during
software development, developers make many mistakes throughout the different phase of
development and testing helps in correcting those mistakes. In other way, testing encompasses all
phases of development-in every phase; the work products of that phase are tested. So in every phase
of development there is testing activity. For example, in the requirement engineering stage, the SRS
(System Requirement Specification ) document is written and tested to check whether it captures all
the user requirements or not. The same is applicable for object oriented testing as object-oriented
programming increases software reusability, extensibility, interoperability, and reliability and at the
same time it is necessary to realize these benefits by uncovering as many programming errors as
possible.
4. WHAT TESTING IS AND ISN’T
Testing comprises the efforts to find defects. Testing does not include efforts
associated with tracking down bugs and fixing them. In other words, testing
does not include the debugging or repair of bugs. Testing is a procedure of
finding faults, defects in the software. While debugging is to rectify the faults,
defects find during testing in the software.
5. PROBLEM AND CHALLENGES
The object-oriented paradigm has set of testing and maintenance problems. The inheritance, aggregation and
association relationships among the object classes make an OO program difficult to test. The encapsulation and
information hiding features result in chains of member function invocations that often involve objects of more than
one class. The problems for software testing are:
1. It is difficult to understand the code and prepare the test cases.
2. It is not cost-effective to construct test stubs for member functions since most of them consist of one to two
statements. Rather, one would just use them provided that they have been tested.
3. It is necessary to determine and limit the required regression tests when a function or a class is changed.
4. It requires a fresh look into the traditional coverage criteria and to extend them to include not just coverage of
individual functions, but also invocation sequence, object stated and state sequences, and data definition and
use path across functions and objects.
6. DIFFERENCES FROM TESTING NON-OBJECT ORIENTED
SOFTWARE
• Conventional testing defined for procedural programs do not fit well in the case of testing an object-oriented
program.
• Conventional software testing tends to focus much on the algorithmic detail of a module and the data that
flows across the module interface, whereas object-oriented software tends to focus on the operations that are
encapsulated by the class and the state behavior of the class.
• Several object-oriented features such as data abstraction, inheritance, polymorphism, dynamic binding etc.,
heavily impact on testing that is not straightforward to make object-oriented systems fit the conventional
testing levels.
• There arises the need for object-oriented testing techniques which suits for object oriented system Though
objects and agents have some similarities, they also differ widely.
• Agents can be termed as intelligent object as agents possesses certain unique properties such as autonomy,
pro-activity, reactivity, social ability etc., the studies states that the agent oriented software are currently been
tested by using the existing object-oriented testing techniques, upon mapping of agent-oriented abstractions
into object-oriented constructs. However agent properties such as autonomy, pro-activity, reactivity etc.,
cannot be mapped into object-oriented constructs. There arises the need for agent-oriented testing
techniques for agent-oriented system
7. TESTING OBJECT–ORIENTED CLASSES
• This fact is demonstrated by the different approaches to testing classes.
Classes contain methods and object instances. Each object instance
represents another state. The methods may also have multiple paths through
them, for instance in the case of decision statements and loops. In testing
procedural units, i.e. modules, one was aiming at traversing every path
through the module.
• In testing object-oriented units, i.e. classes, one also has to deal with state.
Not only that, but since individual methods can be invoked from outside, one
must test every potential chain of methods, from entry to exit.
8. BINDER HAS POINTED OUT FOUR APPROACHES TO
CLASS TESTING/ CLASS MODALITY
• Non modal
• Uni Modal
• Quassi Model
• Modal
10. APPROACHES TO CLASS TESTING CONTD..
• Non modal means testing every single method with a single object instance.
• Uni modal means testing every combination of methods with a single object instance.
• Quasi modal implies testing individual methods with multiple object instances
• and modal implies testing every combination of methods with multiple object instances, e.g. all
possible object states.
• On top of this comes the conventional challenge of testing every path through a method. The result
of combining paths, with methods, with states leads to a combinational explosion of potential test
cases. The only way to deal with this is by automatically generating the test cases out of the code
and joining these test cases with those derived from the class specification. Without the support of
automated class test beds there is no way to test complex classes. Tools like JUnit, CPPTest and
NetUnit can fulfill this need if used correctly..
11. STATE-BASED TESTING TECHNIQUES
One commonly used testing technique is to analyze the different abstract states that a class can
take. The state of an object is generally defined as a constraint on the values of its attributes.
According to the state of the object, calls to certain methods may or may not be valid, or the
method's behavior may change. Generally speaking, the process of using state-based testing
techniques is as follows:
• Define the states.
• Define the transitions between states.
• Define test scenarios.
• Define test values for each state.
12. TO SEE HOW THIS WORKS, CONSIDER THE MONEYBAG CLASS FROM JUNIT.
class MoneyBag implements IMoney {
private Vector fMonies= new Vector(5);
public IMoney add(IMoney m) {
return m.addMoneyBag(this);
}
public IMoney addMoney(Money m) {
return MoneyBag.create(m, this);
}
public IMoney addMoneyBag(MoneyBag s) {
return MoneyBag.create(s, this);
}
void appendMoney(Money aMoney) {
if (aMoney.isZero()) return;
}
IMoney old= findMoney(aMoney.currency());
if (old == null) {
fMonies.addElement(aMoney);
return; }
fMonies.removeElement(old);
IMoney sum= old.add(aMoney);
if (sum.isZero())
return;
fMonies.addElement(sum);
private Money findMoney(String currency)
{
for (Enumeration e=fMonies.elements();e.hasMoreElements();)
{
Money m= (Money) e.nextElement();
if (m.currency().equals(currency))
return m;
}
return null;
}
private boolean contains(Money m) {
Money found= findMoney(m.currency());
if (found == null) return false;
return found.amount() == m.amount();
}
}
13. DEFINE STATES
• The first step in using state-based testing techniques is to define the states. From the second line in the code, you can see that the
MoneyBag class can hold from 0 to 5 Money objects.
private Vector fMonies= new Vector(5);
• From this analysis, you can create a state model with the following states:
• EmptyBag
• PartiallyFullBag
• FullBag
• In this example, you can define the following constraints on the fMonies attribute, as shown in the following table:
• Although it is not always necessary to formally define these states, it can be useful when you are defining test data, or if you want to
check the object state during a specific scenario.
State Constraint
EmptyBag fMonies.size()==0
PartiallyFullBag (fMonies.size()>0) && (fMonies.size()<5)
FullBag fMonies.size()==5
14. DEFINE TRANSITIONS BETWEEN STATES
• The next step is to define the possible transitions between states and determine what triggers a transition from one
state to another. Generally, when you test a class, a transition is triggered when a method is invoked. For example,
the transition from the EmptyBag state to the PartiallyFullBag state is triggered by a call to appendMoney.
• Thus, some possible transitions could be defined as follows:
• A transition from the EmptyBag state to the PartiallyFullBag state (appendMoney).
• A transition from the EmptyBag state to the FullBag state in the case where appendBag is called with a bag containing 5 Money
objects. [aBag.size()==5]/appendBag(aBag).
• A transition from the PartiallyFullBag state to the FullBag state in the case where appendMoney is called on a bag already
containing 4 Money objects [fMonies.size()==4]/appendMoney
• To summarize, for each identified state, you should list:
• Valid actions (transitions) and their effects, that is, whether or not there is a change of state
• Invalid actions that should produce an exception
15. DEFINE TEST SCENARIOS
• Tests generally consist of scenarios that exercise the object along a given path through the state machine. Since the
number of possible paths in the state machine is generally infinite, it is not practical to test each possible path.
Instead, you should make sure that you do the following tasks:
• Cover all identified states at least once.
• Cover all valid transitions at least once.
• Trigger all invalid transitions at least once
• Whenever possible, check the state of the object that you are testing throughout the scenario to ensure that the
theoretical state model you have defined is actually the one implemented by the class you are testing. After you
finish with these transitions, you can test for robustness by calling methods in a random sequence and checking that
a class invariant is never violated. For instance, the MoneyBag class should always be a set of Money objects that are
never of the same currency.
• You can use the scenario-based test pattern that is included with the product to create test scenarios.
16. DEFINE TEST VALUES FOR EACH STATE
• Finally, you need to choose test values for each individual state. Choose unique test values and do not
reuse values that you have used previously in the context of other tests. This strategy provides more
diversity in your test suite and increases the likelihood of detecting bugs.
17. MESSAGE SEQUENCE SPECIFICATION/ MESSAGE
SEQUENCE CHART
• message sequence chart (or MSC) is an interaction diagram by the International Telecommunication
Union.
• The purpose of recommending MSC (Message Sequence Chart) is to provide a trace language for the
specification and description of the communication behavior of system components and their
environment by means of message interchange. Since in MSCs the communication behavior is presented
in a very intuitive and transparent manner, particularly in the graphical representation, the MSC language
is easy to learn, use and interpret. In connection with other languages it can be used to support
methodologies for system specification, design, simulation, testing, and documentation.
• The first version of the MSC standard was released in March 12, 1993.
• The 1996 version added references, ordering and inlining expressions concepts, and introduced HMSC
(High-level Message Sequence Charts), which are the MSC way of expressing State diagrams.
• The MSC 2000 version added object orientation, refined the use of data and time in diagrams, and added
the concept of remote method calls.
18.
19. EXAMPLE
• The diagram shows three entities. At start the phone is disconnected. A user
tries to establish a connection. A connection request is sent to the switch and
a timer is started. An alternative deals with two possible responses:
1. The timer goes off because the switch did not reply and the phone goes
back to the disconnected state.
2. The switch grants the connection and the call is established.
20. COMPARISON TO UML
• UML Sequence Diagram looks very similar to the ITU-T MSC but the default basic principles are quite different:
• Lifelines
• In an MSC, the vertical lines are autonomous execution entities. They usually represent state machines executing in parallel. The
state machines need not be on the same computer.
• In a Sequence Diagram, a vertical line is usually an object. The object can be active (in its own thread of execution) or passive (in
the execution context of an active object).
• Arrows
• In an MSC an arrow is usually an asynchronous message sent from one entity to another one. Once the message is sent the
sending entity resumes its execution.
• In a Sequence Diagram an arrow is usually understood as an operation call on a class. It is therefore synchronous and the calling
entity hangs until the operation returns.
• It has been said that MSC has been considered as a candidate for the interaction diagrams in UML.
• However, proponents of MSC such as Ericsson think that MSC is better than UML 2.0 for modelling large or complex
systems.
21. LIVE SEQUENCE CHARTS
• David Harel thinks that MSC still has several shortcomings such as:
• MSC propose a weak partial ordering semantics that makes it impossible
to capture some behavioral requirements,
• The relationship between the MSC requirements and the executable
specification is not clear.
• To address what he sees as weaknesses in the MSC model, David Harel
proposed an extension on the MSC standard called LSC (Live Sequence
Charts).