0% found this document useful (0 votes)
3 views31 pages

Lec05 Slides

The lecture discusses various testing methodologies such as unit testing, integration testing, and end-to-end testing, emphasizing the importance of early bug detection through incremental testing. It also covers the concept of interfaces in Java, explaining how they facilitate communication between different parts of a program without revealing implementation details. Additionally, the lecture introduces polymorphism and subtype relationships, illustrating how different classes can implement the same interface while maintaining distinct behaviors.

Uploaded by

matthew.lew.04
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)
3 views31 pages

Lec05 Slides

The lecture discusses various testing methodologies such as unit testing, integration testing, and end-to-end testing, emphasizing the importance of early bug detection through incremental testing. It also covers the concept of interfaces in Java, explaining how they facilitate communication between different parts of a program without revealing implementation details. Additionally, the lecture introduces polymorphism and subtype relationships, illustrating how different classes can implement the same interface while maintaining distinct behaviors.

Uploaded by

matthew.lew.04
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/ 31

CS 2110

Lecture 5
Testing (cont.)
Interfaces, subtyping,
polymorphism
A2 will be released soon

A1 will be graded soon


Coming
Can resubmit to fix mistakes
up
Testing
Scopes of testing

Unit testing Integration testing End-to-end testing


Isolated modules Several interacting modules Full application
Why not just end-to-end testing?
• Could just verify that application meets user requirements
• Bug = requirement not met
• No need for intermediate notions of correctness, specs

• How would you debug? When would you debug?


• Unit testing finds bugs sooner and isolates them
• Incremental testing saves time!
Black box testing
• Verify method postconditions against their spec
• Don’t even look at method implementation
• Try to pick inputs that explore “corner cases”
• Remember: goal is to break your code, not baby it
JUnit
• JUnit assertions != Java assert statements
• assertEquals()
• assertTrue() / assertFalse()
• Argument order: expected, then actual

• Floating-point is tricky (see comment in A1Test)


Coverage
• Testing is not sufficient to prove correctness
• How confident are you that there aren’t lingering bugs that weren’t
triggered by your test cases?

• Quantifying coverage for black-box testing is difficult


Glass box testing
• Look at implementation; choose inputs to trigger different branches
• Can measure “line coverage”
• Any code not covered is code where your customer will be the first
person to ever run it, with no evidence that it’s expected to work
• Disadvantage: breaks abstraction barrier
• Focus on breaking the how, not stressing the what
Poll
What is the minimum number of test cases needed for complete line
coverage of Counter.increment()?

A. 0 void increment() {
if (counts == 9999) {
B. 1 counts = 0;
C. 2 }
else {
D. 9,999
counts += 1;
E. 10,000 }
}
Interfaces
“Interfaces”
• Mechanism by which two parties work together, decided ahead of
time
• HDMI cable: interface between laptop and projector
• ¼”-20 screw: interface between tripods and camera gear
• API: interface between client programmers and classes
• Parties don’t need to know each other’s details

• Client interface = a class’s public methods


Discuss
In a class representing a cafeteria,
someone has written a public 1.
method to predict the wait time.
2.
What do you (the client) need to
know in order to make use of this
method? 3.

4.
Java interfaces
• Guarantee to clients what a type /** Closed interval on real
* number line. */
can do, without committing to
details (i.e. fields) public interface Interval {
• Method signatures /** Left endpoint. */
• Method return types double left();
• Method specs /** Right endpoint. */
• Method declarations are double right();
implicitly public /** Whether x is contained
* in interval. */
double contains(double x);
}
Client A code
static boolean intervalsOverlap(Interval i1,
Interval i2) {
return i1.left() <= i2.right() &&
i2.left() <= i1.right();
}
Implementer’s code

Option A Option B
public class TwoPtInterval public class
implements Interval { CenterInterval
/** Left endpoint. */ implements Interval {
private double left; /** Midpoint. */
/** Right endpoint. */ private double center;
private double right; /** Width. */
private double width;
// ...
// ...
}
}
Client B code
TwoPointInterval tpi = new TwoPtInterval(-2, 3);
CenterInterval ci = new CenterInterval(4, 2);

// Is this allowed?
boolean overlap = intervalsOverlap(tpi, ci);
Object diagram
TwoPointInterval
intervalsOverlap()
left: double -2.0

right: double 3.0


tpi: TwoPointInterval i1: Interval

ci: CenterInterval CenterInterval i2: Interval

center: double 4.0

width: double 2.0


Subtypes
• A TwoPtInterval can do anything an Interval can do
• Behavior bound by same specifications
• Therefore, a TwoPtInterval can be used anywhere an
Interval is expected

• Implementing an interface establishes a subtype relationship


• TwoPtInterval <: Interval
• CenterInterval <: Interval
Subtype compatibility
• Assignment • “If x can store an animal, it can
• T x = expr; is allowed if the store a cat.”
type of expr is a subtype of T
• Argument passing
• “If foo() expects a bird, it can
• void foo(T x);
foo(expr)
work with a robin.”
is allowed if the type of expr is a
subtype of T
• Returning
• T bar() { return expr; }
• “If bar() says it will return an
is allowed if the type of expr is a insect, it’s allowed to give me a
subtype of T cricket.”
(subtype) Polymorphism
Variations in behavior
• The Interval interface abstracted over state, but both
implementations behaved identically
• Sometimes, behavior specifications leave room for variation
• Example: chess pieces
Chess piece interface
public interface Piece {
/** Return whether this piece is able to move
to
* location (`dstRow`, `dstCol`) from its
current
* position, given board config. `board`. */
boolean legalMove(int dstRow, int dstCol,
Board board);
}
Chess board interface
public interface Board {
/** Return 0 if position (`row`, `col`) is
empty,
* 1 if occupied by a white piece, 2 if
occupied
* by a black piece. */
int playerAt(int row, int col);
}
Type hierarchy
• Pawn <: Piece Piece
• Knight <: Piece
• Bishop <: Piece
• Rook <: Piece Pawn Queen
• Queen <: Piece
Knight King
• King <: Piece
Bishop Rook
Knight
public class Knight int dx = abs(row–dstRow);
implements Piece { int dy = abs(col–dstCol);
private int row; return board.playerAt(
private int col; dstRow, dstCol)!
private int player; =player
&& ((dx==1 && dy==2)
@Override
||
public boolean (dx==2 &&
legalMove( dy==1));
int dstRow,
int dstCol, }}
Board board) {
King
public class King int dx = abs(row–dstRow);
implements Piece { int dy = abs(col–dstCol);
private int row; return board.playerAt(
private int col; dstRow, dstCol)!
private int player; =player
private boolean hasMoved; && (dx <= 1 && dy <= 1
|| !hasMoved &&
@Override canCastle(board));
public boolean legalMove( }}
int dstRow
int dstCol,
Board board) {
Object diagram
Piece pickNextPiece() {…} Pawn
// ... ...
Piece p;
while (!gameOver) { King
p = pickNextPiece(); p: Piece ...
// assign r, c
if (p.legalMove(r, c)) { Knight
// ... ...
}
}
Static vs. dynamic type
• While the program is running, the type of the object referenced by p
could change, but it will always be a subtype of Piece

• Static type: types declared for variables & return values, derived for
expressions (compile-time)
• Dynamic type: the type of an object being referenced (runtime)

• Behavior is determined by dynamic type


• “Dynamic dispatch”
Poll
Should client be able to call `p.canCastle()` when the dynamic type of
the object referenced by Piece p is a King?

A. Yes
B. No
C. Only if they know more than the compiler
Compile-time reference rule
• Client can only request behavior supported by the static type

• It is possible to ask about the dynamic type of an object and cast the
reference so that additional behavior is available, but this is usually
not good OOP practice
• instanceof
• Example next time: equals()

You might also like