Module Implementation And Testing
Animating Algorithms

Team members
Nikhath Akhtar
Edward Clayton
Yuan Chang
Michael Hogg
Mark Howard
Stephen Morley
Tim Steele
Viktor Vafeiadis
Contents
- Objectives
- Individual Progress Reports
- Difficulties
- Amendments To The Specification
- Module Progress
- Testing Procedure
- Test Report
1. Objectives
| Date to be completed by | Task | Deadline met |
|---|---|---|
| Wed 5th Feb | Interfaces completed | Completed |
| Fri 7th Feb | Animation package completed, single mode GUI | Completed |
| Sun 9th Feb | Raced mode GUI completed, widgets finished | Completed |
| Tues 11th Feb | Module Testing entries deadline, user manual started | Completed |
| Thurs 13th Feb | Hand in Module Testing Documentation, at least one working implementation of algorithm | Completed |
| Fri 14th Feb | 2nd review meeting | |
| Sat 15th - Sun 23rd Feb | Complete system integration and debugging, testing | |
| Sun 23rd Feb | Everything completed, user manual draft finished | |
| Mon 24th Feb | Start planning presentation | |
| Tues 25th Feb | All documentation completed including user manual and final report | |
| Wed 26th Feb | Final meeting to check over all documentation and system | |
| Thurs 27th Feb | Hand in Final Report and user manual | |
| Fri 28th Feb | 3rd review meeting | |
| Sun 2nd Mar | Presentation completed | |
| Mon 3rd Mar (noon) | Deadline for project code completion - a copy of group filespace will be taken | |
| Wed 5th Mar | Group presentation |
2. Individual Progress Reports
Individual reports:
Manager
- Writing progress report
- Documentation for Module Testing and Implementation
- Taking minutes of meetings
- Ensuring objectives are met, and deadlines being adhered to
Coders
- Writing code- see status table for full details
Testers
- Devising testing plan
- Writing test harnesses
- Testing the code - see status table for full details
Webmaster
- Generating javadocs daily
- Converting Specification to HTML format
- Putting up minutes of meetings on website
- Started planning the User Manual
3. Difficulties
We had the following problems during the testing phase of this project:
- Communication between testers and programmers. Communication between the coders and testers at this stage is very important. The implementation was not carried out by the testers but it is vital for them to have a good understanding of the code written. Making use of the javadocs and working together with the coders has proved to be a fundamental part of the testing procedure.
- Lack of comments in code. This made it difficult for the testers to understand what a program was doing, and therefore to write a test harness for it.
- Difficulties during testing. For the Widget package, it was difficult at first to grasp exactly how the tests can be done. Scanning through each widget java file provided an understanding of what each widget can do, but did not give an indication of where the widgets can be instantiated and how the results from method calls can be viewed. Testing required knowledge of not only the widgets package but also its interaction with the other packages. Having found it difficult to obtain a good overall understanding of the project code without being involved in the actual implementation, the coders provided a simple frame of how the widgets should be tested. This is similar to what they used in the testing of their code during implementation. The testing code only needs to be added under the runStandard method. In this way, the tester is not required to have advanced knowledge of the other packages and can concentrate on the input and output of the widget method calls instead.
4. Amendments To The Specification
The following modifications to our specification have been necessary:
User Interaction
The original plan involved a system whereby the user (Animation script writer) could construct a complicated dialog asking for multiple inputs. This had the advantage that only one dialog would be displayed for the user (person viewing animation) to acknowledge. However, in most cases the animation script will only require one or possibly two types of input. Our aim is to provide a simple API for the user to construct animation scripts, therefore we have reverted the UserInteraction module design to an earlier version whereby the user has simple methods such as getInteger(title, defaultValues) which return the result, rather than having multiple calls to construct the dialog, display it and then get its results.
AnimationController
Minor changes were made to the API so that the animation scripts can pass the animation controller as an argument when constructing widgets, thus encapsulating the detail of the program.
PseudoCode
Rather than having a set of static labels and an animated arrow pointing to the current line, we have chosen to highlight the current line by changing the background colour. The moving arrow would be very difficult to implement (there are many special cases such as overflowing lines). The original plan will hopefully be implemented in the final stage of the project, time permitting.
Menu structure
In order to load predefined races, the File->Load Many Items item has been replaced by a submenu with items Custom, Sorting and String Matching.
Animation Package
Changes have affected the Animator, QueueAnimation and ParallelAnimation classes. Animator has same interface but different semantics. The new semantics are to execute many animations one after the other. This corresponds to previous QueueAnimation. QueueAnimation was now removed since a bug was discovered in it and was replaced by Animator. The ParallelAnimation class has the semantics of previous version of Animator. It executes several animations in parallel (one step of each). Its use can be demonstrated by the AnimBoxArray.animateSwap() and AnimBox.compareTo() methods.
5. Module Progress
To keep everyone informed and up-to-date on the progress of the code, a status table has been set up in our CVS repository.

NTD = Not Done - The code has not yet been started. NRD = Nearly Done - Code has started, but not completed. MTD = Mostly Done - Code has been completed, but not checked for errors by programmer.
6. Testing Procedure
Testing is the process of executing a program/system with the intent of finding errors.
The emphasis is on the deliberate intent of finding errors. This is quite different to simply proving that a program or system works. The fundamental purpose of software testing is to find problems in the software so that they can be fixed, resulting in code that is more reliable, stable and more closely matches what the real end-user wants.
The testing procedure employed by our team is to split the testers up so that each person primarily does one package each. Mike is testing the Animation package, Tim is doing AA and Yuan is testing the Widgets package. Once they've each tested their package, they will rotate round and test each other's. This will ensure that testing is rigorous and that the test harnesses themselves are correct.
Each test report is in the form of a java source file, split into three sections:
- A summary of the test (date, tester, etc)
- Test code
- Actual test results
Therefore each report will have the standard header, and will be self contained and complete:
/*****************
* TEST REPORT *
*****************
*
* File tested: widgets/AnimBox
* Tested by: Michael Hogg
* Tested on: 4th Feb 2003
* Version tested: v1.3
* Summary of test results:
* No problems found
*/
Then the rest of the report will consist of:
Public class Test01
{
//test code here
}
/* Test Results
******************
*
* output of the test code pasted here...
* ...
*
*
*/
The test/directory of the group filespace contains aa/, animation/ and widgets/ subdirectories. This mirrors the structure of the src/ directory. Further subdirectories have been created within these, one for each class file to be tested. This allows us to keep together all testing files relevant to a particular program file.
Within the directory, a new test file called TestXX.java is made, where the XX refers to the numeric value following the previous file, i.e Test01.java, Test02.java.
As discussed in our specification, there are two potential ways of dealing with a bug. If the error is sufficiently small, such that the tester may correct the code, then this will be done. In doing so, a new version of the code will be created, and the testing stage must be repeated. A more complicated error means the original coder will be informed in order to deal with it, and the above testing cycle will be started again.
A bug list has been set up in the tests directory as well, to provide an easy up-to-date list of problems in the code. This avoids the testers having to open each file to find out its current testing status.
Bug List Total Bugs: 0 Unresolved Bugs: 0 File: src/cam/cl/alpha2003/widgets/test Tester: Me Date/Time: yesterday Description: Status: Fixed/Not a bug/works for me
Currently, the project is a work in a progress and any test results from this stage are dynamic and likely to change as code is constantly modified and improved by the programmers.
Test Report
7.1 Animation Package classes
Animation (Interface)
Every animation is divided into a number of steps. Each step represents a single
action the animation does (move the object some distance, change its colour, etc
...). The Animator class is responsible for calling the animation at fixed time
intervals.
/*****************
* TEST REPORT *
*****************
*
* File tested: animation/Animation.java
* Tested by: Michael Hogg
* Tested on: 6th Feb 2003
* Version tested: N/A
* Summary of test results:
* No problems found
*/
import cam.cl.alpha2003.animation.Animation;
public class Test01 implements Animation
{
public boolean finished() {return true;}
public boolean animateStep() {return true;}
}
/* Test Results
* ************
*
* To test an interface such as Animation, all one needs to do
* is write a simple test class which implements the interface,
* provide simple definitions for the methods, and check that
* both the interface and test class compile. This has been
* confirmed for Animation, and so its testing is complete.
*
*/
Animator
This class handles the animation. Conceptually there is one thread running this
class on the background. An animation is added to the animator with the
addAnimation (cam.cl.alpha2003.animation.Animation) method and is removed
automatically when it finishes. This class is to be used in two ways:
1. as a top-level animator animating all the animations of an algorithm.
Methods animate(), getDelay() and setDelay(int) are to be used.
2. in conjunction with WaitAnimation and QueueAnimation to produce more
complicated animations. Methods finished() and animateStep() are to be
used.
Current Status: Needs to be tested.
Colorable (Interface)
Every animation object that has a colour that can be changed or made to blink
needs must implement this interface.
/*****************
* TEST REPORT *
*****************
*
* File tested: animation/Colorable.java
* Tested by: Michael Hogg
* Tested on: 6th Feb 2003
* Version tested: N/A
* Summary of test results:
* No problems found
*/
import cam.cl.alpha2003.animation.Colorable;
import java.awt.Color;
public class Test01 implements Colorable
{
public Color getColor() { return Color.red; }
public void setColor(Color color) {}
}
/* Test Results
* ************
*
* To test an interface such as Colorable, all one needs to do
* is write a simple test class which implements the interface,
* provide simple definitions for the methods, and check that
* both the interface and test class compile. This has been
* confirmed for Colorable, and so its testing is complete.
*
*/
ColourChangeAnimation
Animation to change an object's colour for some number of steps.
/*****************
* TEST REPORT *
*****************
*
* File tested: animation/ColorChangeAnimation
* Tested by: Michael Hogg
* Tested on: 10th Feb 2003
* Version tested: 1.6
* Summary of test results:
* No problems found
*/
import cam.cl.alpha2003.animation.Animation;
import cam.cl.alpha2003.animation.Colorable;
import cam.cl.alpha2003.animation.ColorChangeAnimation;
import java.awt.Color;
public class Test01
{
public static void main(String[] args)
{
System.out.println("Testing single-step permanent-colour-change animation");
System.out.println(" Desired final colour = "+Color.red);
Colorable t = new Test01Object();
Animation a = new ColorChangeAnimation(t, Color.red);
if(a.finished())
{
System.out.println(" Error: finished() returned TRUE prematurely");
}
if(!a.animateStep())
{
System.out.println(" Error: animation did not terminate when expected");
}
Color c = t.getColor();
if(c.equals(Color.red))
{
System.out.println(" Final colour of object is correct - "+c);
}
else
{
System.out.println(" Error: Final colour of object is incorrect - "+c);
}
if(a.finished())
{
System.out.println(" finished() returned correct value (TRUE)");
}
else
{
System.out.println(" Error: finished() returned incorrect value (FALSE)");
}
System.out.println(" ");
System.out.println("Testing multiple-step temporary-colour-change animation");
t = new Test01Object();
int totalSteps = 10;
a = new ColorChangeAnimation(t, Color.blue, totalSteps);
int myCounter = 0;
Color initColour = t.getColor();
System.out.println(" Initial colour = "+initColour);
System.out.println(" Desired temporary colour = "+Color.blue);
System.out.println(" Desired colour duration = "+totalSteps+ "steps");
if(a.finished())
{
System.out.println(" Error: finished() returned TRUE prematurely");
}
while(!a.animateStep())
{
myCounter++;
c = t.getColor();
if(c.equals(Color.blue)) {
System.out.println(" Colour at step "+myCounter+" is correct - "+c);
}
else
{
System.out.println(" Error: Colour at step "+myCounter+" is incorrect - "+c);
}
}
c = t.getColor();
if(c.equals(initColour))
{
System.out.println(" Final colour of object is correct - "+c);
}
else
{
System.out.println(" Error: Final colour of object is incorrect - "+c);
}
if(myCounter==totalSteps)
{
System.out.println(" Correct number of animation steps ("+myCounter+")");
}
else
{
System.out.println(" Error: Incorrect number of animation steps ("+myCounter+")");
}
if(a.finished())
{
System.out.println(" finished() returned correct value (TRUE)");
}
else
{
System.out.println(" Error: finished() returned incorrect value (FALSE)");
}
}
}
class Test01Object implements Colorable
{
private Color thisColour;
public Test01Object()
{
thisColour = Color.black;
}
public Color getColor()
{
return thisColour;
}
public void setColor(Color color)
{
thisColour = color;
}
}
/* Test Results
* ************
*
* Testing single-step permanent-colour-change animation
* Desired final colour = java.awt.Color[r=255,g=0,b=0]
* Final colour of object is correct - java.awt.Color[r=255,g=0,b=0]
* finished() returned correct value (TRUE)
*
* Testing multiple-step temporary-colour-change animation
* Initial colour = java.awt.Color[r=0,g=0,b=0]
* Desired temporary colour = java.awt.Color[r=0,g=0,b=255]
* Desired colour duration = 10 steps
* Colour at step 1 is correct - java.awt.Color[r=0,g=0,b=255]
* Colour at step 2 is correct - java.awt.Color[r=0,g=0,b=255]
* Colour at step 3 is correct - java.awt.Color[r=0,g=0,b=255]
* Colour at step 4 is correct - java.awt.Color[r=0,g=0,b=255]
* Colour at step 5 is correct - java.awt.Color[r=0,g=0,b=255]
* Colour at step 6 is correct - java.awt.Color[r=0,g=0,b=255]
* Colour at step 7 is correct - java.awt.Color[r=0,g=0,b=255]
* Colour at step 8 is correct - java.awt.Color[r=0,g=0,b=255]
* Colour at step 9 is correct - java.awt.Color[r=0,g=0,b=255]
* Colour at step 10 is correct - java.awt.Color[r=0,g=0,b=255]
* Final colour of object is correct - java.awt.Color[r=0,g=0,b=0]
* Correct number of animation steps (10)
* finished() returned correct value (TRUE)
*
*/
The following classes are in the process of being tested. As the test harnesses
are not entirely complete, test reports have not been included here. Their
current status is: Nearly done
CurvedMovementAnimation
Animation to gradually move an object in curve.
The object initially moves slowly, and accelerates reaching its maximum velocity
at the middle of the curve and then decelerates towards the end. Its path should
be symmetric to the perpendicular of the line segment joining the starting and
ending points.
Positioner
This class arranges the absolute positions and sizes of objects on screen. This
cannot be tested at this moment in time, as we need to wait until the full
system integration stage to see how this interacts with everything else (?)
Movable (Interface)
Every animation object that can be moved by an animated algorithm must implement
this interface.
/*****************
* TEST REPORT *
*****************
*
* File tested: animation/Movable.java
* Tested by: Michael Hogg
* Tested on: 7th Feb 2003
* Version tested: 1.7
* Summary of test results:
* No problems found
*/
import cam.cl.alpha2003.animation.Movable;
public class Test01 implements Movable
{
public int getX() {return 0;}
public int getY() {return 0;}
public void setLocation(int x, int y) {};
}
/* Test Results
* ************
*
* To test an interface such as Movable, all one needs to do
* is write a simple test class which implements the interface,
* provide simple definitions for the methods, and check that
* both the interface and test class compile. This has been
* confirmed for Movable, and so its testing is complete.
*
*/
QueueAnimation
This class holds a queue of animations and executes them one after the other.
It runs the first animation step by step until it finishes, Then it runs the
second one, then the third etc.
/*****************
* TEST REPORT *
*****************
*
* File tested: animation/QueueAnimation.java
* Tested by: Michael Hogg
* Tested on: 7th Feb 2003
* Version tested: 1.7
* Summary of test results:
* One exception occurred.
*/
import cam.cl.alpha2003.animation.Animation;
import cam.cl.alpha2003.animation.QueueAnimation;
public class Test01
{
public static void main(String[] args)
{
System.out.println("Simple test for default queue size");
QueueAnimation q = new QueueAnimation(); // can hold 5 animations
for(int i=1; i<=5; i++) {
System.out.println(" Adding animation "+i);
q.addAnimation(new Test01Anim(i));
}
if(q.finished())
{
System.out.println(" Error: finished() returned TRUE prematurely");
}
int targetSteps = 20;
System.out.println(" Expected total step count = "+targetSteps);
System.out.println(" ");
int totalSteps = 0;
while(!q.animateStep())
{
totalSteps++;
System.out.println(" Step count = "+totalSteps);
if(q.finished()) {
System.out.println(" Error: finished() returned TRUE prematurely");
}
System.out.println(" ");
}
System.out.println(" Actual total step count = "+totalSteps);
if(totalSteps != targetSteps) {
System.out.println(" Error: incorrect total number of steps");
}
}
}
class Test01Anim implements Animation {
/* A simple test Animation
* that runs for four steps
*/
private int animID;
private int stepsLeft;
public Test01Anim(int q)
{
this.animID = q;
this.stepsLeft = 4;
}
public boolean finished()
{
return (stepsLeft == 0);
}
public boolean animateStep()
{
stepsLeft--;
System.out.println(" "+stepsLeft+" steps left of animation "+animID);
return finished();
}
}
/* Test Results
* ************
*
* Simple test for default queue size
* Adding animation 1
* Exception Occurred:
* java.lang.ArrayIndexOutOfBoundsException
* at cam.cl.alpha2003.animation.QueueAnimation.addAnimation(Compiled
* code)
* at Test01.main(Compiled Code)
*
*
*/
The problem encountered with this was that in the addAnimation method of
QueueAnimation. When a new QueueAnimation is created, it's obviously empty (no
Animations in it). When it is added to the first Animation, it brings up error
messages saying 'ArrayIndexOutOfBoundsException'. This has been rectified as
stated in section 4 of this documentation.
ParallelAnimation
This has been written to replace the original QueueAnimation class. It executes
several animations in parallel. It is used with WaitAnimation and QueueAnimation
to produce more complicated animations. The methods finished() and animateStep()
are to be used. For full test results, please refer to Appendix 1.1.
/*****************
* TEST REPORT *
*****************
*
* File tested: animation/ParallelAnimation.java
* Tested by: Michael Hogg
* Tested on: 12th Feb 2003
* Version tested: 1.1
* Summary of test results:
* No problems found
*/
import cam.cl.alpha2003.animation.Animation;
import cam.cl.alpha2003.animation.ParallelAnimation;
public class Test01
{
public static void main(String[] args)
{
firstTest();
secondTest();
}
public static void firstTest()
{
int animCount = 10;
int targetSteps = 4;
ParallelAnimation p = new ParallelAnimation(); // can hold 20 animations
System.out.println("Test using "+animCount+" animations, each of "+targetSteps+" steps");
System.out.println(" Expected step count = "+targetSteps);
for(int i=1; i<=animCount; i++)
{
System.out.println(" Adding animation "+i+" with "+targetSteps+" step(s)");
p.addAnimation( new Test01Anim(i,targetSteps) );
}
int totalSteps = 0;
do {
System.out.println(" ");
totalSteps++;
System.out.println("ParallelAnimation step count = "+totalSteps);
if(p.finished())
System.out.println("Error: finished() returned TRUE prematurely");
}
while(!p.animateStep());
System.out.println(" ");
if(totalSteps == targetSteps)
System.out.println(" Actual step count is correct ("+totalSteps+")");
else
System.out.println(" Error: Actual step count is incorrect ("+totalSteps+")");
System.out.println(" ");
System.out.println(" ");
}
public static void secondTest()
{
int animCount = 25;
int maxSteps = 10;
ParallelAnimation p = new ParallelAnimation(); // can hold 20 animations
System.out.println("Test using "+animCount+" animations, each of between 1 and "+maxSteps+" steps");
int targetSteps = 0;
for(int i=1; i<=animCount; i++)
{
int randSteps = (int)(10.0 * Math.random()) + 1;
if(randSteps > targetSteps)
targetSteps = randSteps;
System.out.println(" Adding animation "+i+" with "+randSteps+" step(s)");
p.addAnimation( new Test01Anim(i,randSteps) );
}
System.out.println(" Expected step count = "+targetSteps);
int totalSteps = 0;
do {
System.out.println(" ");
totalSteps++;
System.out.println(" ParallelAnimation step count = "+totalSteps);
if(p.finished())
System.out.println(" Error: finished() returned TRUE prematurely");
}
while(!p.animateStep());
System.out.println(" ");
if(totalSteps == targetSteps)
System.out.println(" Actual step count is correct ("+totalSteps+")");
else
System.out.println(" Error: Actual step count is incorrect ("+totalSteps+")");
}
}
class Test01Anim implements Animation
{
/*
* A simple test Animation
*/
private int animID;
private int stepsLeft;
public Test01Anim(int newID, int newSteps)
{
this.animID = newID;
this.stepsLeft = newSteps;
}
public boolean finished()
{
return (stepsLeft == 0);
}
public boolean animateStep()
{
stepsLeft--;
System.out.println(" "+stepsLeft+" step(s) left of animation "+animID);
return finished();
}
}
/* Test Results
* ************
* Test using 10 animations, each of 4 steps
* Expected step count = 4
* Adding animation 1 with 4 step(s)
* Adding animation 2 with 4 step(s)
* Adding animation 3 with 4 step(s)
* Adding animation 4 with 4 step(s)
* Adding animation 5 with 4 step(s)
* Adding animation 6 with 4 step(s)
* Adding animation 7 with 4 step(s)
* Adding animation 8 with 4 step(s)
* Adding animation 9 with 4 step(s)
* Adding animation 10 with 4 step(s)
*
* ParallelAnimation step count = 1
* 3 step(s) left of animation 1
* 3 step(s) left of animation 2
* 3 step(s) left of animation 3
* 3 step(s) left of animation 4
* 3 step(s) left of animation 5
* 3 step(s) left of animation 6
* 3 step(s) left of animation 7
* 3 step(s) left of animation 8
* 3 step(s) left of animation 9
* 3 step(s) left of animation 10
*
* ParallelAnimation step count = 10
* 0 step(s) left of animation 7
*
* Actual step count is correct (10)
*
*
*/
WaitAnimation
Waits a number of steps and then runs a given animation.
This is to delay the start of animation (for instance of colour change animation
in order to match with some point of some other concurrently executed animation).
/*****************
* TEST REPORT *
*****************
*
* File tested: animation/WaitAnimation
* Tested by: Michael Hogg
* Tested on: 10th Feb 2003
* Version tested: N/A
* Summary of test results:
* No problems found
*/
import cam.cl.alpha2003.animation.Animation;
import cam.cl.alpha2003.animation.WaitAnimation;
public class Test01
{
public static void main(String[] args)
{
for(int i=1; i<=100; i++)
{
System.out.println("Testing with "+i+" step(s)");
Animation a = new Test01Anim();
WaitAnimation w = new WaitAnimation(i,a);
int c = 1; // to count animateSteps before finish
if(w.finished())
{
System.out.println(" Error: finished() returned TRUE prematurely");
System.out.println(" Current test aborted");
System.out.println(" ");
break;
}
while(!w.animateStep())
{
c++;
}
if(c!=i)
{
System.out.println(" Error: animation waited for "+c+" step(s) instead of "+i+" step(s)");
System.out.println(" Current test aborted");
System.out.println(" ");
break;
}
System.out.println(" Test successful");
System.out.println(" ");
}
}
}
class Test01Anim implements Animation
{
/* This test Animation is always finished,
* ie. finished() always returns TRUE
*/
public boolean finished()
{
return true;
}
public boolean animateStep()
{
return true;
}
}
/* Test Results
* ************
* Testing with 1 step(s)
* Test successful
* Testing with 2 step(s)
* Test successful
* Testing with 97 step(s)
* Test successful
* Testing with 98 step(s)
* Test successful
* Testing with 99 step(s)
* Test successful
* Testing with 100 step(s)
* Test successful
*/
MovementAnimation
This is the animation to gradually move an object in straight lines. The
CurvedMovementAnimation class is used for a special movement animation.
The problem is: objects being animated seem to arrive at their destination one
step too soon. For example, if an object is meant to reach somewhere in 10
steps, instead it will reach there in 9 steps and then sit there stationary for
the final step.
/*****************
* TEST REPORT *
*****************
*
* File tested: animation/MovementAnimation.java
* Tested by: Michael Hogg
* Tested on: 13th Feb 2003
* Version tested: 1.9
* Summary of test results:
* Problem identified in animateStep() method
*/
import cam.cl.alpha2003.animation.Movable;
import cam.cl.alpha2003.animation.MovementAnimation;
public class Test01
{
public static void main(String[] args)
{
firstTest();
}
public static void firstTest()
{
System.out.println("Testing single-phase movement");
Movable m = new Test01Object(0,0);
System.out.println(" Object intially at (0,0)");
int desX = 200; // desired final x coord
int desY = 100; // desired final y coord
int desSteps = 10; // desired number of steps
System.out.println(" Desired final position is ("+desX+","+desY+")");
System.out.println(" Desired intermediate steps = "+desSteps);
MovementAnimation a = new MovementAnimation(m,desX,desY,desSteps);
int stepCounter = 0;
do {
stepCounter++;
System.out.println(" ");
System.out.println(" Step "+stepCounter+" of animation");
if(a.finished())
System.out.println(" Error: finished() returned TRUE prematurely");
}
while(!a.animateStep());
System.out.println(" ");
if(m.getX() == desX)
System.out.println(" Final X coordinate is correct ("+m.getX()+")");
else
System.out.println(" Error: Final X coordinate is incorrect ("+m.getX()+")");
if(m.getY() == desY)
System.out.println(" Final Y coordinate is correct ("+m.getY()+")");
else
System.out.println(" Error: Final Y coordinate is incorrect ("+m.getY()+")");
if(stepCounter == desSteps)
System.out.println(" Step count is correct ("+stepCounter+")");
else
System.out.println(" Error: Step count is incorrect ("+stepCounter+")");
}
}
class Test01Object implements Movable
{
private int xCoord;
private int yCoord;
public Test01Object(int newX, int newY)
{
this.xCoord = newX;
this.yCoord = newY;
}
public int getX()
{
return xCoord;
}
public int getY()
{
return yCoord;
}
public void setLocation(int x, int y)
{
System.out.println(" setLocation() called");
xCoord = x;
yCoord = y;
System.out.println(" Moved to ("+x+","+y+")");
}
}
/* Test Results
* ************
*
* Problem identified in animateStep() results
*
* Although the animation lasts for the correct number of steps,
* the object is not moving in the final animation step.
*
* In other words, the object takes one step too few to reach
* its destination, and then remains stationary for the final step.
*
* For example, in the test program below, the object should move
* by (20,10) every step, and arrive at its destination after 10 steps,
* but instead it moves by (22,11) every step, arrives at its
* destination after 9 steps, and then freezes for 1 step.
*
* Test program output appears below:
*
*
* Testing single-phase movement
* Object intially at (0,0)
* Desired final position is (200,100)
* Desired intermediate steps = 10
*
* Step 1 of animation
* setLocation() called
* Moved to (22,11)
*
* Step 2 of animation
* setLocation() called
* Moved to (44,22)
*
* Step 3 of animation
* setLocation() called
* Moved to (66,33)
*
* Step 4 of animation
* setLocation() called
* Moved to (88,44)
*
* Step 5 of animation
* setLocation() called
* Moved to (110,55)
*
* Step 6 of animation
* setLocation() called
* Moved to (132,66)
*
* Step 7 of animation
* setLocation() called
* Moved to (154,77)
*
* Step 8 of animation
* setLocation() called
* Moved to (177,88)
*
* Step 9 of animation
* setLocation() called
* Moved to (200,100)
*
* Step 10 of animation
* setLocation() called
* Moved to (200,100)
*
* Final X coordinate is correct (200)
* Final Y coordinate is correct (100)
* Step count is correct (10)
*
*/
7.2 Widgets Package
Testing of the widgets requires the instantiation of each widget and the testing
of the methods defined within the class.
After discussions with the coders, it was decided that an animation test script
should be written for each widget and added to the scripts directory. The
scripts can be loaded from file by running the main application. It is then
possible for the test method calls to be viewed both as animation in the main
application and output print streams in the command window.
The implementation of an animation script required knowledge of other packages.
The coders were able to provide a simple animation script frame which can be
expanded easily.
An animation script must extend abstract class AnimationScript and provide
implementations for all the field and method definitions.
public class AnimBoxTest extends AnimationScript implements RacedIntArrayAnimation
{
public void startRace (cam.cl.alpha2003.aa.AnimationController animator,
int[] values)
{runStandard (animator);}
public AnimBoxTest()
{
author = "Yuan Chang";
title = "Animation Box Test";
description = "Testing the methods defined for animation boxes";
created = "11 February";
}
public void runStandard (AnimationController animator)
{
// Testing code goes here
}
}
With in the testing code, an instance of the widget to be tested is made by
providing suitable arguments to the widget constructor.
// creates an animation box
Comparable string = new String ("hello");
AnimBox animBoxA = new AnimBox (string, animator);
An instance of the widget allows method calls defined in the widget class to be
made. Suitable data is provided for the testing procedure. For example:
Comparable integerA = new Integer (5); animBoxA.setContents (integerA);
System.out.println (animBoxA.getContents());
By outputting an appropriate print stream to the command window, it provides an
indication of whether a method call has achieved its purpose. Testing of the
method is complete if the expected result is displayed in the output.
AnimBoxArray
Provides for arrays of AnimBoxes to be displayed on screen in an ordered
fashion, for swapping within an array, for splitting arrays and adding and
removing items.
/*******************************************************
*
TEST REPORT
*
********************************************************
* *
* File tested: ..widgets/AnimBoxArray.java *
* Tested by: Yuan Chang *
* Tested on: 12th February 2003 *
* Version tested: *
* Summary of test results: no problems found *
* *
******************************************************/
import cam.cl.alpha2003.aa.*;
import cam.cl.alpha2003.widgets.*;
import cam.cl.alpha2003.animation.*;
import java.awt.*;
import javax.swing.*;
public class AnimBoxTest extends AnimationScript implements RacedIntArrayAnimation
{
public void startRace (cam.cl.alpha2003.aa.AnimationController animator ,
int[] values)
{
runStandard (animator);
}
public AnimBoxTest()
{
author = "Yuan Chang";
title = "Animation Box Test";
description = "Testing the methods defined for animation boxes";
created = "11 February";
}
public void runStandard (AnimationController animator)
{
// creates an animation box
Comparable string = new String ("hello");
AnimBox animBoxA = new AnimBox (string, animator);
// Test: get or set the content of an animation box
System.out.println (animBoxA.getContents());
Comparable integerA = new Integer (5); animBoxA.setContents (integerA);
System.out.println (animBoxA.getContents());
// Test: compare the contents of two animation boxes
Comparable integerB = new Integer (10);
AnimBox animBoxB = new AnimBox (integerB, animator);
int value = animBoxA.compareTo (animBoxB);
if (value < 0) System.out.println ("contents of AnimBoxA less than contents of AnimBoxB" );
else if (value == 0) System.out.println ("contents of AnimBoxA equals contents of AnimBoxB" );
else System.out.println ("contents of AnimBoxA greater than contents of AnimBoxB");
// Test: get or set the colour of an animation box
System.out.println ("Colour of animBoxA is " + animBoxA.getColor() + " .");
animBoxA.setColor(Color.red);
System.out.println ("Colour of animBoxA is " + animBoxA.getColor() + " .");
// Test: get or set the location and width of an animation box in its container
System.out.println ("X coordinate of animBoxA is " + animBoxA.getX() + " .");
System.out.println ("Y coordinate of animBoxA is " + animBoxA.getY() + " .");
animBoxA.setLocation(50, 100);
System.out.println ("X coordinate of animBoxA is " + animBoxA.getX () + " .");
System.out.println ("Y coordinate of animBoxA is " + animBoxA.getY () + " .");
System.out.println ("Width of animBoxA is " + animBoxA.getWidth() + " .");
}
}
The testing of the following classes is not complete, but is in progress.
UserInteraction
Constructs a system for requesting data input from the user. A UserInteraction
object should be instantiated, then sections should be added to it using the
add*** methods. A string key should be specified with this, which will be used
later to recover the data. This key must be unique, else there will be problems
when retrieving data. Input requests will be displayed in the dialog in the same
order as the add***Request methods were called. A call to showDialog() will
present the created input dialog to the user. They will be able to enter their
data (or press the 'random' button); this method will end only when the dialog
is complete. Following this, the data can be retrieved using the get*** methods,
supplied with the String given when adding that section to the dialog.
AnimString
Extends AnimBoxArray with more methods more suitable for working with strings.
Also provides for a different display width of boxes, etc. to allow for longer
strings (i.e. better for comparison). As with AnimBoxArrays, all strings are
fixed length. Max length is 100 characters, Minimum is 1.
AnimBar
AnimBar can be used in sorting algorithms to graphically display numerical data
as a series of bars. As such, its contents may only be ints. It may be used to
make algorithms look nicer, and perhaps easier to understand. This could
especially be the case when comparing two algorithms for speed as the size of
the bars will allow more values to be displayed on screen.
AnimBarArray
Provides for Arrays of AnimBars to be displayed on screen in an ordered fashion.
Extends AnimBoxArray, for swapping within an array, for splitting arrays and
adding and removing items.
AnimVariableBox, AnimIndex
Extends AnimBox to provide for boxes with captions/labels. These have both yet
to be coded.
AnimBox
Animbox contains methods and properties necessary for drawing a box containing a
Comparable on the output device, and performing certain functions on it.