Professional Documents
Culture Documents
(Updated) Week 06 - Lecture 2021
(Updated) Week 06 - Lecture 2021
(Updated) Week 06 - Lecture 2021
Semester 1, 2022-23
Errors, Black-box &
White-box Testing
We have to deal with
errors
• Early errors are usually syntax errors
– The compiler will spot these
– These are errors with the Java code that the compiler
can’t process
• Later errors are usually logic errors
– The compiler cannot help with these
– These are errors we as programmers make that cause
unexpected outputs.
– Also known as bugs
• Some logical errors have no immediately obvious
manifestation
– Commercial software is rarely error free
Prevention vs Detection
(Developer vs Maintainer)
• We can lessen the likelihood of errors
– Use software engineering techniques, like
encapsulation
• We can improve the chances of
detection
– Use software engineering practices, like
modularisation and documentation
• We can develop detection skills
Testing and debugging
• These are crucial skills
• Testing searches for the presence of
errors
• Debugging searches for the source of
errors
– The manifestation of an error may well
occur some ‘distance’ from its source
Approaches to Test
Case Generation
Black Box Testing
inputs outputs
No knowledge of code
okCounter() private
incCounter() public
decCounter() public
Observation
s
• First thing we must do is test a
constructor
– How do we observe the results?
– Test getCounter() at same time?
• with one attribute okay, but may not always be
so
– The more methods tested at one go the
more difficult it is to track down any bugs
Java solution
toString
toString
• Every class is a subclass of Object
• Object has a method
String toString()
• For each of our classes, we should
create a toString() method. (Overiding
the objects default toString)
• E.g. for Counter we use
public String toString()
{ return "" +
counter; }
toString
• We have used these methods before, when using
variables from of different data types. Such as
when we converted our students’ IDs from integer
to string:
Integer.toString(ID)
De stab
• Test the constructors first
Te
sig ili
n
• Test public query methods
fo
r
ty
next
• Test public commands next
• Initially write drivers to test one and
only one method at a time
• When the initial testing is complete
drivers may be merged as appropriate
Worked Example: Using MCC
Counter() No values
Counter(int i) A positive integer
getCounter() No input
toString() No input
okCounter() count +ve count 0
setCounter(int i) A positive integer
incCounter() No input
decCounter() count +ve; count 0
JUnit
Unit testing
• Each unit of an application may be tested
– Method, class, package, module (in Java)
• Should be done during development
– Finding and fixing early lowers development costs
(e.g. programmer time)
– A test suite is built up
Unit testing within BlueJ
• In BlueJ, objects of individual classes
can be created
• Individual methods can be invoked
• Inspectors provide an up-to-date view
of an object’s state
• But more it supports JUnit
4.11
JUnit
• JUnit is a framework for writing tests
– JUnit uses Java’s reflection capabilities
(Java programs can examine their own code)
– JUnit helps the programmer:
• define and execute tests and test suites
• formalise requirements and clarify architecture
• write and debug code
• integrate code and always be ready to release a
working version
– JUnit API (not part of Java API):
https://junit.org/junit4/javadoc/latest/
Terminology
• A test fixture sets up the data that
are needed to run tests
– Example: If you are testing code that updates an
employee record, you need an employee record to
test it on
• A unit test is a test of a single class
• A test case tests the response of a
single method to a particular set of
inputs
• A test suite is a collection of test cases
JUnit operation
• Within a test:
– Call the method being tested and get the actual
result
– Assert what the correct result should be using one
of the provided assert methods
– These steps can be repeated as many times as
necessary
• An assert method is a JUnit method that
performs a simple test, and throws an
AssertionFailedError if the test fails
• JUnit catches these Errors and shows
you the result
Assert methods
• I
static void assertTrue(boolean condition)
static void assertTrue(boolean
Condition, String message, )
• assertNotNull(Object object)
assertNotNull(String message, Object object)
• fail()
fail(String message)
What JUnit does
• JUnit runs a suite of tests and reports
results
• For each test in the test suite:
– JUnit calls setUp()
• This method should create any objects you may
need for testing
• Indicated by @Before annotation
What JUnit does
•
…
– JUnit calls one test method
The test method may comprise multiple test
cases; that is, it may make multiple calls to the
method you are testing
• Marked with @Test annotation
• In fact, since it’s your code, the test method
can do anything you want
• The setUp() method ensures you entered the
test method with a virgin set of objects; what
you do with them is up to you
– JUnit calls tearDown()
• This method should remove any objects you
created
• Marked with @After annotation
Test classes in BlueJ
The class The menu you
The class to to test it get when you
be tested right-click
the test class
Use these
to run tests
Use
these to
create
tests
Creating a test class in
BlueJ
• If you have an existing class, right-click
on it and choose Create Test Class
– If your class is named MyClass, the new test
class will be named MyClassTest
Creating the setUp()
method
• BlueJ has an Object Bench
– You can create objects on the Object Bench by
right-clicking on a class and choosing one of its
new constructors
• You can right-click on a test class and
choose:
– Object Bench To Test Fixture or
– Test Fixture To Object Bench
• Since setUp() is your code, you can modify it
any way you like (such as creating new objects
in it)
Implementing the tearDown()
method
• In most cases, the tearDown() method
doesn’t need to do anything
– The next time you run setUp(), your
objects will be replaced, and the old
objects will be available for
garbage collection
– It doesn’t hurt to set to null the objects
you created in setUp()
Recording test cases
• An easy way to create a test method is to
right-click a compiled test class and choose
Create Test Method...
– Enter the name of the method you want to test
– It is usually a good idea to give them a name
with 'test' at the beginning
– If you wish, you can copy Test Fixture To Object
Bench
Recording test cases…
– Use BlueJ to make calls to the method
• After each call, BlueJ will tell you its result, and ask you
to type in the result you expected
– The result can be equal to, the same as, not the same as,
null, not null, or equal to (double or float)
• You can even create a new object to use as a result
– When you are done click the End button (under
Recording)
The structure of a test
method
• A test method doesn’t return a result
• If the tests runs correctly, a test
method does nothing
• If a test fails, it throws an
AssertionFailedError
– Hence, a test method just calls one or more
assertion methods, any of which may throw an
AssertionFailedError
• The JUnit framework catches the error and
deals with it; you don’t have to do
anything
Testing Example –
Counter test
public class Counter {
// count should only take positive values.
// 0 is positive
private int count;
•hit OK
•the recording light comes on
•create a new Counter object using the default
constructor
• hit the End button
•look at code in CounterTest
public void testDefaultConstructorT1()
{
Counter counter1 = new Counter();
}
• Need to add an assert manually
enter a value
• end recording
public void testDefaultConstructorT1()
{
Counter counter1 = new Counter();
assertNotNull(counter1);
}
public void testDefaultConstructorT2()
{
Counter counter1 = new Counter();
assertEquals("0", counter1.toString());
}
Run tests
Change code in the default constructor, say count = 1;
Fixtures
• Test methods often require you to set up the
same sets of objects for each test
• A group of such objects is know as a fixture
• We can use Object Bench to Fixture to have
these placed in the method setUp() which
is called before every test
protected void setUp()
{
counter1 = new Counter();
}
//tearDown() goes here but does nothing
public void
testDefaultConstructorT1()
{
assertNotNull(counter1);
}
public void
testDefaultConstructorT2()
{
assertEquals("0",
counter1.toString());