At first glance this may seem impossible because it is hard to imagine how you can test one "piece" if the other "pieces" that it uses have not yet been developed (and vice versa). The way around this conundrum is to use stubs and drivers.
Though it is possible to define stubs and drivers at some length, that's not necessary for our purposes here. Instead, we will use the following definitions:
Stub | A piece of code that simulates the activity of missing components. |
Driver | A piece of code that passes test cases to another piece of code. |
We start by "stubbing-out" the UnitConverter
class. This "stubbed-out" class contains comments that
describe the class and all of the methods that we expect it to
have (appropriately commented). All of the non-void
methods return an appropriate default so that the class can
be compiled.
/** * Converts from one unit to another (e.g., inches to feet) * * @author Prof. David Bernstein, James Madison University * @version 0.1 (Stub) */ public class UnitConverter { /** * Default Constructor */ public UnitConverter() { } /** * Perform a conversion * * @param value The number to convert * @param from The units for value (e.g., "inches") * @param to The units to convert to (e.g., "feet") * @return The converted value */ public double convert(double value, String from, String to) { return 0.0; } /** * Get the multiplier needed for a conversion * * @param from The units to convert from (e.g., "inches") * @param to The units to convert to (e.g., "feet") * @return What "from" needs to be multiplied by to get "to" */ public double getMultiplier(String from, String to) { return 0.0; } }
We next write a preliminary driver that can be used to perform
preliminary tests of the UnitConverter
class.
In this version the method calls to the UnitConverter
are all "hard-coded".
/** * A driver for testing the UnitConverter class * * @author Prof. David Bernstein, James Madison University * @version 1.0 */ public class Driver { /** * The entry point of the application * * @param args The command-line arguments */ public static void main(String[] args) { double converted, original; String from, to; UnitConverter calculator; calculator = new UnitConverter(); from = "inches"; to = "feet"; original = 10.0; converted = calculator.convert(original, from, to); System.out.println(original+" "+from+" = "+converted+" "+to); } }
Note that these two classes can be compiled and executed.
The next version of the UnitConverter
contains
a complete implementation of the convert
method but
still contains a stub of the getMultiplier
method
(which has been changed slightly to make it more useful).
This enables us to test the convert
method (using the
driver) independently from the other methods.
/** * Converts from one unit to another (e.g., inches to feet) * * @author Prof. David Bernstein, James Madison University * @version 0.2 (Implemented convert) */ public class UnitConverter { /** * Default Constructor */ public UnitConverter() { } /** * Perform a conversion * * @param value The number to convert * @param from The units for value (e.g., "inches") * @param to The units to convert to (e.g., "feet") * @return The converted value */ public double convert(double value, String from, String to) { double result; result = value * getMultiplier(from, to); return result; } /** * Get the multiplier needed for a conversion * * @param from The units to convert from (e.g., "inches") * @param to The units to convert to (e.g., "feet") * @return What "from" needs to be multiplied by to get "to" */ public double getMultiplier(String from, String to) { return 1.0 / 12.0; } }
The next version of the UnitConverter
contains an
implementation (though not a very good one) of the
getMultiplier
method.
/** * Converts from one unit to another (e.g., inches to feet) * * @author Prof. David Bernstein, James Madison University * @version 1.0 (Implemented getMultiplier) */ public class UnitConverter { /** * Default Constructor */ public UnitConverter() { } /** * Perform a conversion * * @param value The number to convert * @param from The units for value (e.g., "inches") * @param to The units to convert to (e.g., "feet") * @return The converted value */ public double convert(double value, String from, String to) { double result; result = value * getMultiplier(from, to); return result; } /** * Get the multiplier needed for a conversion * * @param from The units to convert from (e.g., "inches") * @param to The units to convert to (e.g., "feet") * @return What "from" needs to be multiplied by to get "to" */ public double getMultiplier(String from, String to) { double multiplier; multiplier = 1.0; if (from.equals("inches")) { if (to.equals("feet")) multiplier = 1.0/12.0; else if (to.equals("yards")) multiplier = 1.0/12.0/3.0; else if (to.equals("miles")) multiplier = 1.0/12.0/3.0/1760.0; } else if (from.equals("feet")) { if (to.equals("inches")) multiplier = 12.0; else if (to.equals("yards")) multiplier = 1.0/3.0; else if (to.equals("miles")) multiplier = 1.0/3.0/1760.0; } else if (from.equals("yards")) { if (to.equals("inches")) multiplier = 3.0*12.0; else if (to.equals("feet")) multiplier = 3.0; else if (to.equals("miles")) multiplier = 1.0/1760.0; } else if (from.equals("miles")) { if (to.equals("inches")) multiplier = 12.0*3.0*1760.0; else if (to.equals("yards")) multiplier = 1760.0; else if (to.equals("feet")) multiplier = 3.0*1760.0; } return multiplier; } }
To test this version of the UnitConverter
we need to
modify the driver so that it generates more test cases. In this
case we use "white-box (or glass-box) testing" (i.e., we look at the
UnitConverter
class to identify important test cases)
and write a driver that tests all supported inputs.
/** * A driver for testing the UnitConverter class * * @author Prof. David Bernstein, James Madison University * @version 2.0 */ public class Driver { /** * The entry point of the application * * @param args The command-line arguments */ public static void main(String[] args) { double converted, original; int i, j; String from, to; String[] units = {"inches","feet","yards","miles"}; UnitConverter calculator; calculator = new UnitConverter(); original = 10.0; for (i=0; i < units.length; i++) { for (j=0; j < units.length; j++) { from = units[i]; // This could be outside the inner loop to = units[j]; converted = calculator.convert(original, from, to); System.out.println(original+" "+from+" = "+converted+" "+to); } } } }
This process continues until a satisfactory version of the
UnitConverter
is completed.
Copyright 2021