Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
student:junit:v4 [2018/08/10 14:21] bernstdhstudent:junit:v4 [2018/08/14 11:00] (current) bernstdh
Line 1: Line 1:
  
  
-===== JUnit Basics =====+===== JUnit v4 Basics =====
  
  
Line 8: Line 8:
  
  
-JUnit is an open-source testing framework. It provides a way to write,   organize, and run repeatable test.+JUnit is an open-source testing framework. It provides a way to write,   organize, and run repeatable test. This page provides a brief introduction to v4. Information is also available about  
 +[[student:junit:v5 | version 5 (Jupiter) ]].
  
  
Line 14: Line 15:
  
  
-For each class you want to test, you must create a file named   //ClassName//Test.java where //ClassName// denotes the name   of the class being tested. So, for example, if you want to test the   class named   ''%%Atom%%'' you must create a file named ''%%AtomTest.java%%''.+For each class you want to test, you must create a file. It is common to use naming system //ClassName//Test.java where //ClassName// denotes the name   of the class being tested. So, for example, if you want to test the   class named   ''%%Atom%%'' you would create a file named ''%%AtomTest.java%%''.
  
  
Line 32: Line 33:
 So, continuing with the example above, ''%%AtomTest.java%%''   would initially contain the following: So, continuing with the example above, ''%%AtomTest.java%%''   would initially contain the following:
  
-<code>+<code java>
 import static org.junit.Assert.*; import static org.junit.Assert.*;
  
-import org.junit.Before; 
 import org.junit.Test; import org.junit.Test;
  
Line 46: Line 46:
 (Note: The ''%%import static%%'' allows you to refer to   static members in the ''%%org.junit.Assert%%'' package without having   to include the class name.) (Note: The ''%%import static%%'' allows you to refer to   static members in the ''%%org.junit.Assert%%'' package without having   to include the class name.)
    
-The file //ClassName//Test.java contains methods that can be   used to test the class defined in //ClassName//.java.  Each such   method is preceeded by an ''%%@Test%%'' annotation.  (Note: An   annotation provides information about a program but is not part of   the program. Annotations have no effect on the operation of the   program.  Instead, they are used to provide information to tools   that might use the program as input.)+The file //ClassName//Test.java contains methods that can be   used to test the class defined in //ClassName//.java.  Each such   method is preceded by an ''%%@Test%%'' annotation.  (Note: An   annotation provides information about a program but is not part of   the program. Annotations have no effect on the operation of the   program.  Instead, they are used to provide information to tools   that might use the program as input.)
  
 So, still continuing with the example   above, if the ''%%Atom%%'' class contains a ''%%public int   getAtomicNumber()%%'' method, then ''%%AtomTest.java%%''   might include the following method:  So, still continuing with the example   above, if the ''%%Atom%%'' class contains a ''%%public int   getAtomicNumber()%%'' method, then ''%%AtomTest.java%%''   might include the following method: 
  
-<code>+<code java>
     /**     /**
      * Unit tests for the getAtomicNumber() method      * Unit tests for the getAtomicNumber() method
Line 59: Line 59:
     }     }
 </code> </code>
 +
 +Note that the name of this method is completely arbitrary, but, as always, descriptive names are always a good
 +idea. Some people simply use the name of the method being tested (as above), while others add a prefix or suffix that includes some form of the word "test" (e.g., ''%%testGetAtomicNumber()%%'', ''%%getAtomicNumber_Test()%%'',
 +etc...).
  
 The body of the methods in the //ClassName//Test.java must contain   the test cases for the corresponding methods in the //ClassName//   class.  These test cases often involve some "setup" code and a call to   the ''%%Assert.assertEquals()%%'' method. So, for example, the   ''%%getAtomicNumber%%'' method in the ''%%Atom%%'' class is   supposed to return the atomic number of the calling ''%%Atom%%''   object. To partially test this method one might implement the   ''%%testGetAtomicNumber()%%'' method in the   ''%%AtomTest%%'' class as follows: The body of the methods in the //ClassName//Test.java must contain   the test cases for the corresponding methods in the //ClassName//   class.  These test cases often involve some "setup" code and a call to   the ''%%Assert.assertEquals()%%'' method. So, for example, the   ''%%getAtomicNumber%%'' method in the ''%%Atom%%'' class is   supposed to return the atomic number of the calling ''%%Atom%%''   object. To partially test this method one might implement the   ''%%testGetAtomicNumber()%%'' method in the   ''%%AtomTest%%'' class as follows:
  
-<code>+<code java>
     /**     /**
      * Unit tests for the getAtomicNumber() method      * Unit tests for the getAtomicNumber() method
Line 80: Line 84:
 </code> </code>
    
-In the "setup" portion, this method creates an ''%%Atom%%''   objects (for oxygen). It then calls the   ''%%Assert.assertEquals()%%'' method to tell jUnit to do some testing.   This particular version of the ''%%Assert.assertEquals()%%'' method is   passed three parameters and has the following syntax:+In the "setup" portion, this method creates an ''%%Atom%%''   objects (for oxygen). It then calls the   ''%%Assert.assertEquals()%%'' method to tell JUnit to do some testing.   This particular version of the ''%%Assert.assertEquals()%%'' method is   passed three parameters and has the following syntax:
  
-  Assert.assertEquals(//Description//, //ExpectedValue//, //ActualValue//);+''Assert.assertEquals(//Description//, //ExpectedValue//, //ActualValue//);''
    
 The //Description// is a human-readable ''%%String%%''   that provides information that enables the tester to understand the   test in the event that the code fails the test. (Note that the   tester will also be provided with the name of the test method so it   isn't necessary to include information about the method being tested   in the description if the   test method is named well.) The //ExpectedValue//   contains the correct value (i.e., the value that the tester expects   if the method named //MethodName// in //ClassName// is working   correctly.  The //ActualValue// contains the value that was   actually generated by the method named //MethodName// in   //ClassName//. The //Description// is a human-readable ''%%String%%''   that provides information that enables the tester to understand the   test in the event that the code fails the test. (Note that the   tester will also be provided with the name of the test method so it   isn't necessary to include information about the method being tested   in the description if the   test method is named well.) The //ExpectedValue//   contains the correct value (i.e., the value that the tester expects   if the method named //MethodName// in //ClassName// is working   correctly.  The //ActualValue// contains the value that was   actually generated by the method named //MethodName// in   //ClassName//.
Line 90: Line 94:
 As another example, suppose the ''%%Atom%%'' class contains a   ''%%public boolean equals(Atom other)%%'' method, then   ''%%AtomTest.java%%'' might implement the   following method: As another example, suppose the ''%%Atom%%'' class contains a   ''%%public boolean equals(Atom other)%%'' method, then   ''%%AtomTest.java%%'' might implement the   following method:
  
-<code>+<code java>
     /**     /**
      * Unit tests for the equals(Atom) method      * Unit tests for the equals(Atom) method
Line 104: Line 108:
 The ''%%equals()%%''   method in the ''%%Atom%%'' class is supposed to compare the   calling ''%%Atom%%'' object with the given ''%%Atom%%'' object   and return ''%%true%%'' if the two have the same attributes and   ''%%false%%'' otherwise.  To partially test the  ''%%equals()%%''   method, one might implement the ''%%testEquals()%%'' method in the   ''%%AtomTest%%'' class as follows: The ''%%equals()%%''   method in the ''%%Atom%%'' class is supposed to compare the   calling ''%%Atom%%'' object with the given ''%%Atom%%'' object   and return ''%%true%%'' if the two have the same attributes and   ''%%false%%'' otherwise.  To partially test the  ''%%equals()%%''   method, one might implement the ''%%testEquals()%%'' method in the   ''%%AtomTest%%'' class as follows:
  
-<code>+<code java>
     /**     /**
      * Unit tests for the equals(Atom) method      * Unit tests for the equals(Atom) method
Line 111: Line 115:
     public void testEquals()     public void testEquals()
     {     {
-        Atom    h, o;+        Atom    h, hh, o;
      
         h  = new Atom("H", 1, 1);         h  = new Atom("H", 1, 1);
Line 135: Line 139:
 When using ''%%Assert.assertEquals()%%'' to compare floating   point numbers (e.g., ''%%double%%'' values), one must remember   that the ''%%==%%'' operator must be used with care   because of the less-than-perfect precision of operations   on ''%%double%%'' values.  In JUnit, the implication of this is   that one should check to see if ''%%double%%'' values are   within a tolerance value of each other.  Hence, when   comparing ''%%double%%'' values one should use the following: When using ''%%Assert.assertEquals()%%'' to compare floating   point numbers (e.g., ''%%double%%'' values), one must remember   that the ''%%==%%'' operator must be used with care   because of the less-than-perfect precision of operations   on ''%%double%%'' values.  In JUnit, the implication of this is   that one should check to see if ''%%double%%'' values are   within a tolerance value of each other.  Hence, when   comparing ''%%double%%'' values one should use the following:
  
-Assert.assertEquals(//Description//, //ExpectedValue//, //ActualValue//, //tolerance//);+''Assert.assertEquals(//Description//, //ExpectedValue//, //ActualValue//, //tolerance//);''
  
  
Line 144: Line 148:
  
  
-<code>+<code java>
   @Test(expected = IllegalArgumentException.class)   @Test(expected = IllegalArgumentException.class)
   public void testConstructor_IllegalArguments()   public void testConstructor_IllegalArguments()
Line 169: Line 173:
 Using these methods, it would be better to write the test of the   ''%%equals()%%'' method above as follows. Using these methods, it would be better to write the test of the   ''%%equals()%%'' method above as follows.
  
-<code>+<code java>
     /**     /**
      * Unit tests for the equals(Atom) method      * Unit tests for the equals(Atom) method
Line 226: Line 230:
 You can set the ''%%CLASSPATH%%'' as follows: You can set the ''%%CLASSPATH%%'' as follows:
  
 +<code bash>
 export CLASSPATH=.://directory//junit.jar://directory//hamcrest-core.jar:$CLASSPATH export CLASSPATH=.://directory//junit.jar://directory//hamcrest-core.jar:$CLASSPATH
 +</code>
  
 where //directory// denotes the name of the directory/folder that contains the files ''%%junit.jar%%'' and ''%%hamcrest-core.jar%%''. where //directory// denotes the name of the directory/folder that contains the files ''%%junit.jar%%'' and ''%%hamcrest-core.jar%%''.
Line 233: Line 238:
 For example, assuming that the two ''%%.jar%%'' fiels are in the current working directory, you can set the ''%%CLASSPATH%%'' as follows: For example, assuming that the two ''%%.jar%%'' fiels are in the current working directory, you can set the ''%%CLASSPATH%%'' as follows:
  
 +<code bash>
 export CLASSPATH=.:junit.jar:hamcrest-core.jar:$CLASSPATH export CLASSPATH=.:junit.jar:hamcrest-core.jar:$CLASSPATH
 +</code>
  
 After you have set the ''%%CLASSPATH%%'' you can compile your classes (including the test classes) and the usual way, and run a JUnit test as follows: After you have set the ''%%CLASSPATH%%'' you can compile your classes (including the test classes) and the usual way, and run a JUnit test as follows:
  
 +<code bash>
 java org.junit.runner.JUnitCore //ClassName//Test java org.junit.runner.JUnitCore //ClassName//Test
- +</code>  
 where //ClassName// is the name of the class being tested. For example, to run ''%%AtomTest%%'': where //ClassName// is the name of the class being tested. For example, to run ''%%AtomTest%%'':
  
Line 255: Line 264:
 To compile: To compile:
  
-javac -cp .:junit.jar //ClassName//Test.java+''javac -cp .:junit.jar //ClassName//Test.java''
  
 where //Name// represents tha name of the class being tested (and can contain wildcards like *). where //Name// represents tha name of the class being tested (and can contain wildcards like *).
Line 261: Line 270:
 To run: To run:
  
-java -cp .:junit.jar:hamcrest-core.jarorg.junit.runner.JUnitCore //ClassName//Test+''java -cp .:junit.jar:hamcrest-core.jarorg.junit.runner.JUnitCore //ClassName//Test''
  
 where //Name// represents the name of the class being tested. where //Name// represents the name of the class being tested.
Line 267: Line 276:
 For example, to compile and run ''%%AtomTest%%'': For example, to compile and run ''%%AtomTest%%'':
  
-<code>+<code bash>
 javac -cp .:junit.jar AtomTest.java javac -cp .:junit.jar AtomTest.java
 java -cp .:junit.jar hamcrest-core.jarorg.junit.runner.JUnitCore AtomTest java -cp .:junit.jar hamcrest-core.jarorg.junit.runner.JUnitCore AtomTest
Line 279: Line 288:
  
  
-=== Using JUnit with the CMD Shell === +=== Using JUnit with the MS-Windows CMD Shell ===
  
  
Line 294: Line 302:
 You can set the ''%%CLASSPATH%%'' as follows: You can set the ''%%CLASSPATH%%'' as follows:
  
- +''set CLASSPATH=.;//directory//junit.jar;//directory//hamcrest.jar;%CLASSPATH%''
-set CLASSPATH=.;//directory//junit.jar;//directory//hamcrest.jar;%CLASSPATH%+
  
 where //directory// denotes the name of the directory/folder that contains the files ''%%junit.jar%%'' and ''%%hamcrest-core.jar%%''. where //directory// denotes the name of the directory/folder that contains the files ''%%junit.jar%%'' and ''%%hamcrest-core.jar%%''.
Line 324: Line 331:
 To compile: To compile:
  
-javac -cp .;junit.jar //ClassName//Test.java+''javac -cp .;junit.jar //ClassName//Test.java''
  
 where //Name// represents tha name of the class being tested (and can contain wildcards like *). where //Name// represents tha name of the class being tested (and can contain wildcards like *).
Line 337: Line 344:
  
 <code> <code>
-javac -cp .;junit.jar;hamcrest-core.jar AtomTest.java+javac -cp .;junit.jar AtomTest.java
 java -cp .;junit.jar;hamcrest-core.jarorg.junit.runner.JUnitCore AtomTest java -cp .;junit.jar;hamcrest-core.jarorg.junit.runner.JUnitCore AtomTest
 </code> </code>