Week 5 Topics - Computing Sciences
Download
Report
Transcript Week 5 Topics - Computing Sciences
Week 14
Introduction to Computer Science
and Object-Oriented Programming
COMP 111
George Basham
Week 13 Topics
14.1.1 Unit Tests
14.1.2 Providing Test Input
14.1.3 Test Case Evaluation
14.1.4 Regression Testing and
Test Coverage
14.1.5 Logging
14.1.6 Using a Debugger
14.1.1 Unit Tests
• Unit tests are used to test classes in
isolation of one another
• The Unit Testing framework we have been
using in this course is JUnit
• A Unit Testing framework typically allows
the programmer to compare a
predetermined expected result against the
result produced by the program
14.1.1 Unit Tests Cont.
• It is challenging to test a class in isolation
if it depends on another class
• Testing classes in isolation when they
have dependencies requires an advanced
testing technique called mock objects
• Mock objects are objects that are
designed specifically for the purpose of
testing, but don’t actually implement the
functionality of the class being mocked
14.1.1 Unit Tests Cont.
• A Mock class is stuffed with dummy data that the
dependent class needs for its tests and keeps
track of methods that the dependent class calls
on itself
• The testing framework can then validate that the
class interacted properly with the mock class
• Mock objects are so common that there are
several frameworks for dynamically creating
mock objects in Java
14.1.1 Unit Tests Cont.
• A class that is coded for the purpose of
feeding parameters into methods that are
being tested is called a test harness
• A test harness class is in essence a
manual approach to doing unit testing
• A test harness should be repeatable, that
is, data that has already been inputted
should be documented
14.1.1 Unit Tests Cont.
public void testGetRoot() // JUnit method
{
double x = 100.0
RootApproximator r = new
RootApproximator(x);
assertEquals(10.0, r.getRoot(), .0001);
}
14.1.1 Unit Tests Cont.
public void class TestRootApproximator()
{...
// Test harness class, partial code in main
double x = 100.0
RootApproximator r = new
RootApproximator(x);
if (Math.abs(10.0 - r.getRoot()) <= .0001)
System.out.println(“Test case 1 passed”);
}
14.1.2 Providing Test Input
• Crafting test input tests that are repeatable
is an key component of program
debugging and maintenance efforts
• Being able to repeat a test and validate
that the outputs are still correct is
important when coding changes are made
to a program (regression testing)
• Typically, test data is stored in a file or
database
14.1.2 Providing Test Input Cont.
• Positive test cases are test cases that are
expected to pass
• Negative test cases are test cases that are
expected to fail
• Boundary test cases are test cases that
lay right on the boundary of acceptable
inputs (0 would be an example if negative
numbers not allowed)
14.1.2 Providing Test Input Cont.
• Special test cases are test cases that test
situations such as values just to the
positive or negative side of a boundary
test case, or division by zero, etc.
• A table of test cases should be created
prior to testing after doing an analysis of
the problem domain; this activity is at least
as important as program coding and
should precede the coding task!
14.1.3 Test Case Evaluation
• How to determine if an output is correct is
a key factor of a testing methodology
• Sometimes an expected output can be
calculated by hand
• An expected value might be calculated via
code that iterates many times to derive a
value
14.1.3 Test Case Evaluation Cont.
• There may be a less efficient way to
calculate a value than the approach that is
being employed by the method being
tested
• This slower but reliable method is called
an oracle
• Thus, a test harness class can be written
that compares the method output to the
results of an oracle
14.1.4 Regression Testing and Test
Coverage
• A test suite is a set of tests for repeated
testing
• Regression testing involves repeating
previously run tests to ensure that known
failures of prior versions do not appear in
new versions of the software
• White-box testing uses information about
the structure of a program
14.1.4 Regression Testing and Test
Coverage Cont.
• Black-box testing describes a testing
method that does not take the structure of
the implementation into account
• Test coverage is a measure of taking into
account how many parts of a program
have been tested
• For example, you should test every branch
of all if/else code
14.1.5 Logging
• Logging is a way of tracing the execution
of a program through all the method calls
• More than a useful debugging tool, logging
can be a business requirement in many
situations
• Consider that all bank transactions should
be logged for accounting purposes
14.1.5 Logging Cont.
• However, the most common use for
logging is debugging
• A logging API allows a programmer to log
messages at various levels of severity,
capture the log to a file, and even turn
logging on and off entirely
14.1.6 Using a Debugger
• A debugger is a program that you can use
to execute another program and analyze
its run-time behavior
• You can make effective use of a debugger
by mastering just three concepts:
breakpoints, single-stepping, and
inspecting variables
14.1.6 Using a Debugger Cont.
• When a debugger executes a program,
the execution is suspended whenever a
breakpoint is reached
• The single-step command executes the
program one step at a time
• You should step into a method to check if
carries out its job correctly, you should
step over it if you know it works correctly
Reference: Big Java 2nd Edition by Cay
Horstmann
14.1.1 Unit Tests (section 10.1 in Big
Java)
14.1.2 Providing Test Input (section 10.2
in Big Java)
14.1.3 Test Case Evaluation (section
10.3 in Big Java)
14.1.4 Regression Testing and Test
Coverage (section 10.4 in Big Java)
14.1.5 Logging (section 10.5 in Big Java)
14.1.6 Using a Debugger (section 10.6 in
Big Java)