Tuesday, August 26, 2008

FizzBuzz (JUnit + Eclipse)

Premise: Testing out JUnit's test case features on Eclipse.
Application: FizzBuzz
Description: Print out the numbers from 1-100 on each line. If a number is divisible by 3 then print out "Fizz", else if a number is divisible by 5 then print "Buzz", else if the number is divisible by both 3 and 5 then print "FizzBuzz", otherwise print the numeric value.

Why JUnit?
JUnit provides immediate feedback based on YOUR tests. It lets you have a taste of the pie rather than the whole thing all at once. JUnit provides safe and time saving software engineering practices for both small or large production software. And of course JUnit is FREE and included when you download Eclipse.

JUnit design procedures:
1. Create a JUnit Test Case in your current project folder. Your test case classes will extend from JUnit's TestCase object class. In here, you can utilize the following methods provided by TestCase: setUp() - to initialize test objects, tearDown() - to destroy test objects. Next, write your test case methods with their names prefixed with 'test'
2. Create a JUnit Test Suite in your existing project folder. Eclipse provides a convenient way to add test classes to your test suite upon creation. The test suite is intended to encapsulate all test classes provided in your project folder.
3. Implement the component/class for your project and test away! Remember that your program is validating itself with incremental test units, so start out with just a piece of your program and work your way up the chain.

---Source---
Test class: TestFizzBuzz.java
- Declare the object FizzBuzz to be tested and an integer as our test case input value.
- Create methods: setUp() initialize variables/objects & tearDown() destruction of variables/objects
- Implement test case method: testGetValue()
import junit.framework.TestCase;

public class TestFizzBuzz extends TestCase {
//OBJECT/PRIMATIVE DATA DECLARATIONS
private FizzBuzz fb; //object class being tested
private int num; //test value

//FIXTURES
protected void setUp() {
num = 3;
fb = new FizzBuzz();
fb.setNum(num);
}
protected void tearDown() {
num = 0;
}

//TEST CASES (prefix method names with 'test')
public void testGetValue() {
if (num==3) {
assertEquals("Fizz", fb.getValue());
} else if (num==5) {
assertEquals("Buzz", fb.getValue());
} else if (num==15) {
assertEquals("FizzBuzz", fb.getValue());
}
}
}


Test suite: AllTests.java
- Test all test case methods in class 'TestFizzBuzz'
import junit.framework.Test;
import junit.framework.TestSuite;

public class AllTests {

public static Test suite() {
TestSuite suite = new TestSuite("Test for default package");
//$JUnit-BEGIN$
suite.addTestSuite(TestFizzBuzz.class);
//$JUnit-END$
return suite;
}

public static void main(String[] args) {
junit.textui.TestRunner.run(suite());
}

}

Application: FizzBuzz.java
- Attempt to implement the getValue method
- Output the desired results
//FizzBuzz.class
public class FizzBuzz {
//PRIMATIVE DATA
private int num;

//DEFAULT CONSTRUCTORS
public FizzBuzz() {
}
public FizzBuzz(int n) {
num = n;
}

//GETTERS/SETTERS
public void setNum(int num) {
this.num = num;
}
public int getNum() {
return num;
}

//RETRIEVE CORRECT VALUE
public String getValue() {
if((num % 3 == 0) && (num % 5 == 0)) {
return "FizzBuzz";
} else if (num % 3 == 0){
return "Fizz";
} else if (num % 5 == 0) {
return "Buzz";
} else {
return Integer.toString(num);
}
}

//MAIN METHOD
public static void main(String[] args) {
FizzBuzz fb = new FizzBuzz();
for (int i=1; i<=100; i++) {
fb.setNum(i);
System.out.println(fb.getValue());
}
}
}

FizzBuzz app results:
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
16
17
Fizz
19
Buzz
Fizz
22
23
Fizz
Buzz
26
Fizz
28
29
FizzBuzz
31
32
Fizz
34
Buzz
Fizz
37
38
Fizz
Buzz
41
Fizz
43
44
FizzBuzz
46
47
Fizz
49
Buzz
Fizz
52
53
Fizz
Buzz
56
Fizz
58
59
FizzBuzz
61
62
Fizz
64
Buzz
Fizz
67
68
Fizz
Buzz
71
Fizz
73
74
FizzBuzz
76
77
Fizz
79
Buzz
Fizz
82
83
Fizz
Buzz
86
Fizz
88
89
FizzBuzz
91
92
Fizz
94
Buzz
Fizz
97
98
Fizz
Buzz


Conclusions:
The program took me about 15 minutes to accomplish. Having been equipped with the power of Eclipse and JUnit tool, I've been able to code with confidence. JUnit takes away the remedial debug breakpoints/backtrace of code (which requires that you make a mistake first), but rather helps you build from ground up with a solid assurance of functionality. It also helps prevent you from fixing a bug later down the line that may be too heavily nested in your code to find. In the essence of incremental programming, I would recommend further exploring the possibilities of JUnit in any aspect of development for Java.