The goal of this lab is to gain experience writing JUnit tests and using code coverage tools.
Suppose that JMU had the following severe weather cancellation policy (here's the real one):
JMU (FAKE) SEVERE WEATHER POLICYIf any of the following conditions are met, campus will be closed:
If none of the above conditions are met, the University may still issue a warning and encourage individuals to avoid non-essential outdoor activities. A warning will be issued if any of the following conditions are met:
|
The following Java class has been developed as part of a JMU Decision Support system:
The weatherAdvice
method provides an implementation
of the cancellation policy above. Your job is to develop a set of
JUnit tests to confirm that this method is implemented correctly.
Your testing must also confirm that the correct exception is thrown
when the method receives invalid input.
Once you have set up an Eclipse project containing WeatherUtils.java, create a stub JUnit test class:
import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.api.Test; /** * Tests the WeatherUtils class. * * @author Nathan Sprague * @version 02/01/2021 */ public class WeatherUtilsTest { @Test public void testWeatherAdvice() { fail("Not yet implemented"); } }
fail
method call with an assertion, for example:
assertEquals("CANCEL", WeatherUtils.weatherAdvice(70.1, 0.0));Rename
testWeatherAdvice
to something more informative, like testWeatherAdviceWindspeedOnlyAboveDangerThreshold
.
Dark
themes if the highlighting that
indicates your test coverage makes the file nearly illegible (for some of the dark themes).Complete WeatherUtilsTest.java by writing an appropriate set of test methods. You should be able to check your code coverage from within Eclipse. Keep working until your tests cover 100% of the method.
Once you are confident that your unit tests are sufficient, demonstrate them and your coverage to the instructor or TA. Your goal is to achieve 100% method, statement, and branch coverage.
Note: In order to cover the public class WeatherUtils
line, you will need to construct a (useless) WeatherUtils object.
The following example "covers" the default constructor.
Notice that there is nothing to assert.
/** * Tests the constructor (for 100% coverage). */ @Test public void testDefaultConstructor() { new WeatherUtils(); }
There are several ways to test for thrown exceptions in JUnit.
The easiest way is to use assertThrows
:
@Test public void testInvalidWindSpeed() { assertThrows(IllegalArgumentException.class, () -> { WeatherUtils.weatherAdvice(-1.0, 0.0); }); }
The ->
operator defines a lambda expression.
In programming, a "lambda" is a block of code that can be assigned to a variable.
Lambdas allow you to write unnamed methods on the fly and pass them as parameters to other methods.
In the above example, we define an unnamed method that takes no paramters ()
and that invokes weatherAdvice
.
WeatherUtils.weatherAdvice
to assertThrows
?WeatherUtilsTest.java
. Is it 100%? Why are we
not concerned about reaching 100% coverage of the testing
code?100% coverage doesn't necessarily mean that your tests are "good". High-quality tests should be able to uncover errors in the code that is being tested. The next step is to run your tests against an implementation that is known to contain errors. If your tests are effective, they should indicate that there is a problem with this code. For this part of the lab, you will run your tests against a pre-compiled .class file that we have intentionally coded to contain at least one error.
Upload your completed WeatherUtilsTest.java file to Autolab by the end of class (or by 11:00pm tomorrow if you need more time). The lab is worth 10 points: 2 points for correctness, and 8 points for coverage.