Does my program work?
I don't know, let's test it and see.

Testing Object-Oriented Programs (TODO: finish this document)


Contents


Introduction (TODO)

Testing is a critical part of all software development. Too often it is left for the last step in the process. This lesson attempts to help you change that order and show you how to make unit testing your code an integral and intial part of your development process.  

Once you get the hang of it check out even more sophisticated testing options like JUnit tests, classes, and suites.

Test Output is as varied as all output.  We will focus on writing tests that report only failures and thus we assume no output is "No News" which is "Good News".

The possibilities for program testing are quite extensive and we only present the tip of the iceberg of those available to modern program developers.  See TDD and ? ? ? for more testing ideas and test writing philosophies.

Unit Testing (TODO)

Unit testing is when you write code that is designed to fully test a discrete unit of your programming project.  The unit could be a single expression, a method, a class, a module, a library, etc.  Our unit testing will focus on testing individual methods.  Since our test code will be external to the class that contains the methods being tested, we will need to consider what will we need to have to call our method.  These represent dependencies.  Our method depends upon the class, instance, input paramenters, etc.  Pro tip: Identify, build, and test those pieces first.

Testing static methods

To call static methods as part of a test, use the class name itself.  ClassName.staticMethodName()

Testing instance (non-static) methods

To test instance methods, you will need an instance of that class. 

Input Parameters

You must also consider the input parameters to the method you wish to test.  What does the method require as input values to be able to complete its work or compute its return value?   If the parameters are primitives, you can simply enter those as literal values.  Eventually, you will want such input values to be variables so that the same test method can test different conditions.  If the method you are testing requires, instance of other objects, you will need to create those instances first so you can pass them as arguments to the method being tested.

Test Class

A single class can be used to run many unit tests.   Depending upon your needs you can have a custom setup within each test method, or you can have a more global setup (using static fields) that all test methods can use.  To write one test class for each class of your project, or a single Test class that contains tests for all classes and methods of your program?  That is the question.

As with many object-oriented design decisions you will make, the best answer is typically, "It depends".   Do you want to run one Test program to find all problems, or run many Test programs and be able to focus on a subset of the tests at each case.   The final    Test an individual unit of your program, such as one method. Java, does not allow methods to exists outside of class structures, so create a class that will contain your unit tests. 

public class P0_Tests {

}

for ( int i = 0; i < 10 ; i++ )
   System.out.println("The cube i^3 of " + i + " is " + (int)(Math.pow(i,2)) );

The console window is the window panel that is automatically brought to the focus when you run a program that displays output from within Eclipse.  Most programming languages have the ability to display a string of characters to this window on the screen or to some other standard display device. 

for ( int i = 0; i < 10 ; i++ )
   System.out.println("The cube i^3 of " + i + " is " + (int)(Math.pow(i,2)) );

Another common use for console output is to display a prompt the user for input.  Leave a space after the prompt if you chose to have the user enter their answer on the same line as the prompt (as this example demonstrate).  Here is an example of prompting the user. The next section will describe user input options.

   // Prompt the user for some type of information
   System.out.print( "What is your name? " );

   // code to read (scan and save) user input would be here

For example, if the following variables are defined,

    int x = 3;
    double rate = 5.5;
    boolean playing = true;
    String phrase = "The winner is ";

they can all be displayed to the console using print or println as follows:

    System.out.print( "x = " + x + " rate = " );
    System.out.println( rate );
    System.out.println( "playing = " + playing );
    System.out.println( phrase + "Deb" );
    /**
     *  Returns a string representing this instance of the Wanderer class.
     *  Example: Wilma is at (3,4) 
     */
    public String toString()
    {
        String coords = "(" + myLoc.getX() + ","
                            + myLoc.getY() + ")";

        return myName + " is at " + coords;
    }

Now, when the print or println method is used to print a Wanderer object, the new version of the toString method will be called instead of the version defined in the Object class.  The String that is printed by the System.out.println(wanderer) method call will look something like this:

 

Black Box Testing (TODO)

Programs that require the user to input information while the program is running, must prompt the user for that information in some manner. Note: The user will only know what information to type, if the program prompts (asks for) and describes the information that is required.  (See Console Output for more information on output and an example user prompt.)

After the prompt is displayed, the program will wait for the user to finish typing and press Enter. When a program is waiting for input at the console, there is sometimes a blinking cursor in the console window indicating that the user should type some information. But, this is not always the case. Console input is string of characters that are entered by typing on the keyboard while the program is running and waiting for user input. Whatever the user typed is saved in an input stream and is available to the program by request in the form of a String object.  We may also learn and use specialized methods to parse (interpret) the string of characters as an int or a double value.

Would you like to see some code?  I thought so.  Here it is:

    // In a method somewhere...
    // 1. Create an class member in your main program class
    Scanner stdin = new Scanner( System.in );

    // 2. Prompt the user
    System.out.print( "What is your name? " );

    // 3. Use the Scanner to get a line of text from the user.
    String name = stdin.nextLine();

    // 4. Now, you can do anything with the input string that you need to.
    // Like, output it to the user.
    System.out.println( "Hi " + name + "! Welcome to my Super Duper Program" );
    // 5. Once, you are done reading ALL input, close the Scanner
    stdin.close();

I added the above code to my main method and I get compiler errors!

Did you import the java.util.Scanner class?  The Scanner (and other I/O classes) is not in the standard java.lang package.  You must import Scanner from the java.util package.

    import java.util.*;  // needed for Scanner, Random, ArrayList, etc

    /** A Java program that demonstrates console based input and output. */
    public class MyConsoleIO 
    {
        // Create a single shared Scanner for keyboard input
        private static Scanner stdin = new Scanner( System.in );

        // Program execution starts here
        public static void main ( String [] args ) {

            // Prompt the user
            System.out.print( "What is your name? " );

            // Read a line of text from the user.
            String line = stdin.nextLine();

            // Display the input back to the user.
            System.out.println( "Hello " + name );

        } // end main method

    } // end MyConsoleIO class

 

White Box Testing (TODO)

Test knowing and with access to the internal structure.  Write a test for each possible path through the code.

The Integer class contains conversion methods for changing String data into int values and vice versa.  The Integer class is one of several wrapper classes that are defined in the standard Java API.  Wrapper classes have class methods for parsing and are also used when you need to store a primitive value as an object. 

Integrated Testing (TODO)

TODO: draft this section