Question
Assignment 1 Testing This assignment will give you practice writing unit tests. You are to write a set of unit tests for the provided Circle
Assignment 1 Testing
This assignment will give you practice writing unit tests. You are to write a set of unit tests for the provided Circle class.
Your unit tests must be written as JUnit 4 tests. The unit testing lecture slides and the Point class tests developed during class will provide explanations and examples of how to write unit tests. The lecture slides include links to additional information online. An internet search for tutorials or examples of unit testing might help you find additional useful sources of information.
Your unit tests must pass and provide complete code coverage of the Circle class. Use the EclEmma code coverage tool to check that your tests provide complete code coverage of the Circle class.
Your unit tests should not produce any console output when run. All results of the tests should be reported by using JUnit assertions as demonstrated in class.
A correct set of unit tests should expose a bug in the Circle class. This means that your unit tests must include at least one test that would fail on the provided code, but will pass after you identify and correct the bug. So, when you discover the bug, correct it and leave your test in place.
Implementation Guidelines:
You must not change any code in the Circle class except to correct the one bug mentioned previously. Hints and Suggestions:
Each unit test should test a single method of the Circle class. Each unit test ideally should have only a single JUnit assertion or test a single exception. This does not mean that the Circle class and your test class will necessarily have the exact same number of methods. It may be possible to achieve complete code coverage of the Circle class without writing tests for every method of the Circle class (this will be true because you will use some methods of the Circle class to help test other methods). In some cases you may need to write several test methods in your test class to thoroughly test a single method of the Circle class. Name each of your test methods appropriately so that the name clearly indicates which Circle class method is being tested.
NOTE: The toString() method of the Circle class internally calls toString() in the Point and Color classes. A call toString() on the default black unit circle centered at the origin would return the following String:
Circle [radius=1.00, center=java.awt.Point[x=0,y=0], color=java.awt.Color[r=0,g=0,b=0]]
(This is correct output, not a bug!)
Stylistic Guidelines:
You will be graded on program style, which includes:
use of descriptive method and variable names
Javadoc comments on your test class and on every constant, field, and method in your test class
Notice that the provided Circle class produces no warnings from the plugin tools. Be careful to write your unit test class in a way which minimizes warnings from the tools. Ideally your unit tests should produce no warnings. If you have questions about what a particular warning means, and a quick online search doesnt help, ask about it as soon as possible.
Remember to include a non-javadoc header comment at the beginning of your test class with some basic information, in addition to full Javadoc comments. Examples of acceptable file header comments and of Javadoc comments appear in the Circle class and in the Point class code example from lecture.
Submission and Grading:
Create your Eclipse project by downloading the hw1-project.zip file from Canvas, importing it into your workspace (as described for hw0-project.zip in Assignment 0), and using Refactor to change username
in the project name to your UWNetID. Remember to make this change before you first share the project to Subversion. Incorrectly named projects will be penalized when graded.
Also, as with Assignment 0, you can use whichever bracket style you like. The provided class uses the same line style which you may change to next line style if you wish.
You must check your Eclipse project into Subversion (following the instructions from Lecture 1 and Assignment 0), including all configuration files that were supplied with it (even if you have not changed them from the ones that were distributed). When you have checked in the revision of your code you wish to submit, make a note of its Subversion revision number. To get the revision number, perform an update on the top level of your project; the revision number will then be displayed next to the project name. Your revision number will pick up where you left off on Assignment 0; if you submitted revision 5 of Assignment 0, the first commit of Assignment 1 will have a number greater than 5. This is because you have a single Subversion repository for all your projects, and the revision number counts revisions in the entire repository.
After checking your project into Subversion, you must submit (on Canvas) an executive summary, containing the Subversion revision number of your submission, an assignment overview explaining what you understand to be the purpose and scope of the assignment, and a technical impression section describing your experiences while carrying out the assignment.
The filename for your executive summary must be username-testing.txt, where username is your UWNetID. As with the naming convention for your Eclipse project, your assignment will be penalized if it does
not follow this naming convention. An executive summary template, which you must use, is available on Canvas. In particular, your executive summary must have a line containing exactly the text Subversion Revision Number: #, with no leading spaces, where # is the Subversion revision number you made a note of above (with no parentheses or other symbols). Executive summaries without a line following this exact format will be penalized. Executive summaries will only be accepted in plain text format other file formats (RTF, Microsoft Word, Acrobat PDF, Apple Pages) are not acceptable. Using an unacceptable file format for the executive summary will be penalized.
Part of your program's score will come from its "external correctness." For this assignment, you will receive full credit for external correctness if your unit tests pass, achieve full code coverage, and produce no console output.
Another part of your program's score will come from its "internal correctness." Internal correctness for this assignment includes following coding conventions and providing documentation of your code (Javadoc comments). It also includes the quality of the tests you write. It is possible to achieve full code coverage with poorly designed tests. I will look at your tests to see if they do a reasonable job of testing the Circle class methods. I will look to see that you have identified and corrected the bug which exists in the Circle class.
Internal correctness also includes whether your source code follows the stylistic guidelines discussed in class. This includes criteria such as the presence of Javadoc comments on every method and field (even private ones!), the use of variable names, spacing, indentation, and bracket placement specified in the class coding standard, and the absence of certain common coding errors that can be detected by the tools. It is therefore to your advantage to be sure the plugin tools like your code before you submit it.
For this assignment, the percentage breakdown is 10% executive summary, 45% external correctness, 45% internal correctness.
/* * TCSS 305 * Assignment 1 - Testing */
import java.awt.Color; import java.awt.geom.Point2D; import java.util.Objects;
/** * Represents a circle. * *
Invariant: * myRadius must be greater than zero * AND myCenter must not be null * AND myColor must not be null
* * @author Alan Fowler acfowler@uw.edu * @version 2.0 */ public class Circle {// class constants
/** * A default radius to use when no other value is specified - (1.0 - a unit circle). */ private static final double DEFAULT_RADIUS = 1.0; // unit circle
/** * A default Point for the center of a Circle - (0.0, 0.0) the coordinate system origin. */ private static final Point2D DEFAULT_CENTER = new Point2D.Double(0.0, 0.0); // origin
/** * A default Color to use when no other Color is specified - Color.BLACK. */ private static final Color DEFAULT_COLOR = Color.BLACK;
// instance fields
/** * The radius of this Circle. */ private double myRadius;
/** * The center of this Circle. */ private Point2D myCenter; // Note that java.awt.Point is mutable
/** * The color of this Circle. */ private Color myColor;
// constructors
/** * Constructs a Circle with the specified radius, location, and color. * *
Precondition: The parameters must not violate the class invariant. * That is, theRadius must be greater than zero * AND theCenter must not be null * AND theColor must not be null
* * @param theRadius the radius to assign to this Circle * @param theCenter the center point to assign to this Circle * @param theColor the color to assign to this Circle * @throws IllegalArgumentException if theRadius is less than or equal to zero * @throws NullPointerException if theCenter is null OR theColor is null */ public Circle(final double theRadius, final Point2D theCenter, final Color theColor) {if (theRadius <= 0) { throw new IllegalArgumentException("The radius must be a positive value!"); }
myRadius = theRadius; /* * Note that the Objects class and requireNonNull() were added to Java in version 7. * The method will throw an exception if the parameter passed to the method is null. * This simplifies the code by eliminating the need for an if / else test * and an explicit throws statement. */ myColor = Objects.requireNonNull(theColor); // We must make a defensive copy of the mutable Point parameter // to avoid an encapsulation violation. // So, we must NOT simply write myCenter = theCenter! // One way to make a defensive copy is to use a copy constructor if the class has one. // Unfortunately Point2D.Double does not have a copy constructor. // Another way is to use an overloaded constructor: myCenter = new Point2D.Double(theCenter.getX(), theCenter.getY()); // OR // We can use a no argument constructor and then use setter(s). //myCenter = new Point2D.Double(); // creates Point at (0, 0) //myCenter.setLocation(theCenter); // OR // We can use the clone() method if the class we want to copy implements Cloneable. // Point2D.Double does implement Cloneable, so this works also. //myCenter = (Point2D) Objects.requireNonNull(theCenter).clone(); }
/** * Constructs a black unit circle centered at the origin. */ public Circle() { this(DEFAULT_RADIUS, DEFAULT_CENTER, DEFAULT_COLOR); }
// instance methods // 'mutators', sometimes called 'commands', or sometimes called 'setters'
/** * Sets the radius of this Circle to the specified value. * *
Precondition: theRadius must be greater than zero
*Postcondition: this Circle will be assigned the specified radius
* * @param theRadius the radius value to assign to this Circle * @throws IllegalArgumentException if theRadius is less than or equal to zero */ public final void setRadius(final double theRadius) {if (theRadius <= 0) { throw new IllegalArgumentException(); } myRadius = theRadius; }
/** * Sets the location of the center of this Circle to the specified point. * *
Precondition: thePoint must not be null
*Postcondition: this Circle will be assigned the specified center Point
* * @param thePoint the center value to assign to this Circle * @throws NullPointerException if thePoint is null */ public final void setCenter(final Point2D thePoint) { // make a defensive copy of the mutable Point parameter // to avoid an encapsulation violation myCenter = (Point2D) Objects.requireNonNull(thePoint).clone(); }/** * Sets the Color of this Circle to the specified value. * *
Precondition: theColor must not be null
*Postcondition: this Circle will be assigned the specified Color
* * @param theColor the Color value to assign to this Circle * @throws NullPointerException if theColor is null */ public final void setColor(final Color theColor) {myColor = Objects.requireNonNull(theColor); }
// 'accessors', sometimes called 'queries', or sometimes called 'getters'
/** * Returns the radius of this Circle. * * @return the radius of this Circle */ public final double getRadius() { return myRadius; }
/** * Returns the center Point of this Circle. * * @return the center Point of this Circle */ public final Point2D getCenter() {
// return a defensive copy of the mutable Point field // to avoid an encapsulation violation return new Point2D.Double(myCenter.getX(), myCenter.getY()); // OR //return (Point2D) myCenter.clone(); }
/** * Returns the Color of this Circle. * * @return the Color of this Circle */ public final Color getColor() { return myColor; }
/** * Calculates and returns the diameter of this Circle. * * @return The diameter of this Circle */ public double calculateDiameter() { return 2 * myRadius; }
/** * Calculates and returns the circumference of this Circle. * * @return the circumference of this Circle */ public double calculateCircumference() { return Math.PI * calculateDiameter(); }
/** * Calculates and returns the area of this Circle. * * @return the area of this Circle */ public double calculateArea() { return 2 * myRadius * Math.PI; } // overridden methods from class Object
/** * {@inheritDoc} * * The String representation of this Circle will be formatted as follows: * Circle [radius=(current value), center=(current value), color=(current value)]. */ @Override public String toString() { final StringBuilder builder = new StringBuilder(128); // default initial size = 16 builder.append(getClass().getSimpleName()); // the class name without the package name builder.append(" [radius="); builder.append(String.format("%.2f", myRadius)); builder.append(", center="); builder.append(myCenter); builder.append(", color="); builder.append(myColor); builder.append(']'); return builder.toString(); }
}
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started