Testing Some OO Concepts/Environment (chapters 16,17 & 18)

advertisement
Testing in OO Environment
• The reasons for testing is not any different for
any of the design and implementation
methodologies, including OO methodology.
– Find faults and fixing them before releasing
– Show that the software works (at least in chosen
areas)
• In OO we are especially interested in testing
because we want to “reuse” the tested objects.
• Does our approach have to change because of
OO?
– Not really - - - but we do have to focus on a few
characteristics
Basic Levels of Testing in OO
Same as before;
testing the whole
system
System Test
Unit A
Integration test
Unit X
Integration test
Unit
Testing
Same as before;
testing “related”
units as a group
What is a “unit”
In OO?
What is a “unit” in OO
• A “unit” of code for unit testing before was
left with a loose definition of a module,
– a sequence of code that performs something,
– a compiled program,
– something assigned to 1 person
• In OO we have the same problem with the
definition of a “unit” in unit testing. Is it:
– A method?
– A set of code that performs something?
– A Class?
Considering Class as a “unit” has a lot of support among testers.,
but it is not a fixed law or something
Class and Object instantiation
•
There are at least two concerns with viewing class as
a “unit”:
1.
We should view Class as a fundamental unit and test it as an
independent entity by itself.
•
scaffolding
2.
integration
What and how much “scaffolding” code do we need to write to
invoke and test this Class.
–
–
e.g. Class1 x1; - - - You may need to write the public static void “main” method to test the
class (possible scaffolding code)
If there is a large method inside the Class and we know (via
white-box testing approach) that the method invokes other
methods in other Classes, should we follow (test) the thread of
methods across different Classes?
–
the module-module (mm-path) approach may be employed for
testing the “thread” of methods, that may go beyond one Class
3 important concepts in OO
1.
Encapsulation:
–
–
–
2.
In OO, the notion of self contained and only know/operate
within its own domain is very important
Good encapsulation gives rise to good reusable classes
that can be composed with other classes to deliver more
service.
We are also after highly cohesive and loosely coupled units
with encapsulation.
Inheritance:
–
A way to gain on the concept of reuse through a class
taking (inheriting) portions from a super class.
Overload/Polymorphism”
3.
–
Another way to gain on the reuse concept through using
parts of class or method for different purposes based on
the passed parameter or based on run time usage (late
binding).
How do these concepts affect us in testing?
Encapsulation
• Both data and methods may be encapsulated and
protected. Depending on the programming language
used there may be slight differences in implementing
the encapsulation mechanism:
– Public (visible) - - - pretty much same in all languages
– Private (hidden) - - - only methods in the class can access
– Protected (secret)- - - subclass methods can access
• Test the access of encapsulated data
• Test the access of encapsulated methods
Read the discussion on the positions of “dial’ and “lever” of the windshield wiper example
on page 287. The exchange of “positions” of these two may be different depends on the
design and how the data is encapsulated.
Inheritance Example (JAVA)
• One may want to test the methods in the inherited
class which were previously tested in the superclass.
• An example is a method, m1, that only returns positive
integers and is used in another method, m2, as a divisor.
An inherited subclass modifies (over rides) m1 to allow
all integers, including zero. (We will need to ensure that
the inherited and previously tested m2 is retested).
public class Example {
int y;
public int m1 {
y = (test * test) +1;
return y;
}
public void m2 {
z=w/y;
}
import Example ;
public class Example2 extends Example {
public int m1 {
y = test * test ;
return y;
}
}
Similar Inheritance Problem Example
(C++)
Class Test1 {
int some_variable;
.
Original CLASS
.
int method1 ( ) { return 1; }
int method2 ( ) { return 1 / method1( ); }
}
Class Test_child : Public Test1 {
int mehtod1 ( ) { return 0; }
}
Inherited CLASS
over-riding method1
Inheritance
• Do we need to test multiple inheritance,
where there may be conflicts in inheritance?
– Two subclasses, Sub1 and Sub2, are inherited from a superclass, S1, and they both modify the method, method1, but
differently. If we further inherit from both Sub1 and Sub2,
what should we expect method1 to be like?
Mother
Varx : int
method1 ( )
method2 ( )
Sibling 1
Note: JAVA does not allow
multiple inheritance
Sibling 2
(method1)
(method1)
overridden
Overridden differently
Grand_Sibling 1
Inheritance
•
Inheritance provides us with the ability to reuse (and save both
implementation and testing expenses) what is there and make
incremental changes by creating a subclass by either adding to or
modifying the :
–
–
•
Instance variable
Methods
Using “Flattened Class” concept:
1.
2.
3.
One may want to test subclass access of the “encapsulated” data or
methods in the super-class.
One may want to test all the methods in the inherited class which were
previously tested in the super-class.
•
An example is a method, m1, that only returns positive integers and is
used in another method, m2, as a divisor. An inherited subclass modifies
m1 to allow all integers, including zero. (We will need to ensure that the
inherited and previously tested m2 is retested).
Do we need to test multiple inheritance, where there may be conflicts in
inheritance?
•
Two subclasses, Sub1 and Sub2, are inherited from a super-class, S1,
and they both modify the method, m1, but differently. If we further inherit
from both Sub1 and Sub2, what should we expect m1 to be like?
Testing flattened Classes of all inherited subclasses will cause duplication of
testing the same (non-overridden) methods that appear in all the inherited subclasses
Polymorphism and Late Binding (in C++)
•
Polymorphism and late binding is a special feature that allows us to have
multiple behavior based on which class a statement is bound to. e.g. in C++
Class Cube{
protected:
float length;
public:
virtual float area( ) {return (length* length);} // area of square
void set_length(float z) {length = z} // set passed parameter, length
void volume( ) {cout<< “volume is” << area( ) * length;} // the area( ) method is not bound
};
Class Cylinder: public Cube
{
virtual float area( ) {return (3.14* length**2);} // area of circle
}
.
.
Cube c1, Cylinder cyl1;
.
c1.volume( ); // give us the volume of cube
cyl1.volume( ); // give us the volume of circle
•Both classes must be tested, especially if one of them is a division by length.
Polymorphism via dynamic instantiation (in JAVA)
class Shape { - - - - - - - }
class Rectangle extends Shape { - - - - }
class Triangle extends Shape { - - - - }
class Circle extends shape { - - - - }
import Rectangle;
import Triangle;
import Circle;
public class Example
{
public static void main ( String[ ] args)
String S = get_shape_type ( ) ; // some method that reads and returns a string to S
Shape myFigure;
myFigure = (Shape) java.lang.class.forName(S).newinstance( );
/* myFigure is instantiated to what the string read in --- hopefully it is rectangle, circle or triangle */
/* Note that it is “casted’ as type Shape, which is the parent Class */
}
Is equivalence class testing of valid vs invalid shape good enough?
Do you need to test everyone of the valid shape?
Polymorphism via “interface” (in JAVA)
public interface Speaker
{ --public void speak( );
}
public class cat implements Speaker
{ --public void speak ( )
{ system.out.println(“meow”); }
}
public class dog implements Speaker
{ --public void speak ( )
{ system.out.println(“woof woof”);}
}
Import cat;
Import dog;
Public class AnimalTalk
{ public static void main ( string[ ] arg)
{ Speaker current;
system.out.println(“enter 1 or 2”);
/* 1 = cat and 2 = dog */
int j = keyboard.readInt ( );
if (j == 1)
current = new cat ( );
else
current = new dog ( );
current.speak ( );
}
}
All Branch Test will take care of both cat and dog ?-----
OO concepts and testing
• Assume a “unit” is a CLASS.
– Inheritance can be dealt with at the subclass level
through unit testing the “flattened” subclass as the
basic “unit”.
• Flattened class is the class expanded to include all the
inherited methods (operations) and variables/constants
(attributes)
– Encapsulation can be dealt with by both unit
testing the individual class and integration testing
the related classes. (More burden is placed on the
integration test - - - especially if the design is “tightly”
coupled classes.)
– Overload and polymorphism can be dealt with
unit testing the overload or the polymorphic function
individually and then use integration testing to
further test the overriding and the polymorphism
mechanisms
Basic Levels of Testing in OO
Same as before;
testing the whole
system
System Test
Unit A
Integration test
Unit X
Integration test
Unit
Testing
Test relations
and
Inheritance;
Encapsulation;
Polymorphism
Test class
and
class Inheritance
More Considerations of Unit Testing
1.
Each method as a “unit”
–
2.
Once a method of interest is designed and written one still
needs to develop “scaffolding” test code such as stubs for the
yet-to-complete other methods and driver for the “main”
program to test the finished method.
The completed class as a “unit”
–
–
All the methods are and the data are available for testing.
We may view the class in 3 ways:
–
–
–
3.
Source code level (reviewing the code – possibly with “flattened”
class)
Compiled code level ( code inheritance takes place and all the
classes in the hierarchy above the class must be available)
Execution code level (code is constructed and the interactions
among the methods can be tested much like an integration test
within a class)
Also, we need to deal with abstract method and abstract
class which are generic concept. (It is almost like a stub
itself).
Integration Testing
• Assumes the unit or units are unit-tested.
• Use the collaboration diagram and the
sequence diagram from UML to design the
integration test cases.
1
2
3
Collaboration diagram where
boxes are classes and numbered
arrows indicate sequenced
messages
Sequence diagram where the boxes
are classes and the arrows indicate
the sequence of messages
Download