## Data Driven Testing for Unit Testing

Since most of the testing scenarios data are in the form of table, a Data Driven testing approach can be employed for carrying out unit testing using TestNg/Junit. For Example, Consider the example of testing a simple integer division method.

`   1:      Class Divide{`
`   2:        public static int divide(int a, int b) {`
`   3:          if (b == 0) {`
`   4:              throw new ArithmeticException();`
`   5:          } else`
`   6:              return a / b;`
`   7:      }`
`   8:  }`

For testing this simple method itself properly, we need to test the following scenarios.

#### Expected Result

Zero/Zero 0 0 ArithmeticException
Zero/positive 0 2 0
Zero/negative 0 -2 0
Positive/zero 5 0 ArithmeticException
Negative/zero -2 0 ArithmeticException
Positive/positive 5 2 2
Positive/negative 5 -2 -2
Negative/positive -5 2 -2
Negative/negative -5 -2 2
No/same number 5 5 1

To test the above scenarios we have to call the same method with different arguments (something like below) or need to have different method for testing each scenario.

`   1:  public class TestDivide {`
`   2:   `
`   3:      @Test`
`   4:      public void testDivide() throws Exception {`
`   5:          // Zero/Zero 0 0 ArithmeticException`
`   6:          testDivideByZero(0, 0);`
`   7:          // Zero/positive 0 2 0`
`   8:          assertEquals(0, Divide.divide(0, 2));`
`   9:          // Zero/negative 0 -2 0`
`  10:          assertEquals(0, Divide.divide(0, -2));`
`  11:          // Positive/zero 5 0 ArithmeticException`
`  12:          testDivideByZero(5, 0);`
`  13:          // Negative/zero -2 0 ArithmeticException`
`  14:          testDivideByZero(-2, 0);`
`  15:          // Positive/positive 5 2 2`
`  16:          assertEquals(2, Divide.divide(5, 2));`
`  17:          // Positive/negative 5 -2 -2`
`  18:          assertEquals(-2, Divide.divide(5, -2));`
`  19:          // Negative/positive -5 2 -2`
`  20:          assertEquals(-2, Divide.divide(-5, 2));`
`  21:          // Negative/negative -5 -2 2`
`  22:          assertEquals(2, Divide.divide(-5, -2));`
`  23:          // No/same number 5 5 1`
`  24:          assertEquals(1, Divide.divide(5, 5));`
`  25:      }`
`  26:   `
`  27:      private void testDivideByZero(int a, int b) throws Exception {`
`  28:          try {`
`  29:              Divide.divide(a, b);`
`  30:              fail("My method didn't throw when I expected it to");`
`  31:          } catch (ArithmeticException e) {`
`  32:          } catch (Exception e) {`
`  33:              fail("My method throws different Exception when I expect ArithmeticException");`
`  34:          }`
`  35:      }`
`  36:  }`
The above approach makes the Test class cumbersome and difficult for other developers to understand the test scenarios. To avoid this, We can load the test data from an Excel/CSV/WIKI and validate the output instead of running the same TestNg/Junit test method with different inputs. And also this helps in the Documentation of the test cases that we have already identified and tested.

Proposed Method :

`   1:  @RunWith(Parameterized.class)`
`   2:  public class DataDrivenTestsWithSpreadsheetTest { `
`   3:   `
`   4:      private int a;`
`   5:      private int b;`
`   6:      private int aDivideB;`
`   7:     `
`   8:      @Parameters`
`   9:      public static Collection<Object[]> spreadsheetData() throws IOException {`
`  10:          InputStream spreadsheet = new FileInputStream("src/test/resources/aDivideB.xls");`
`  11:          return new SpreadsheetData(spreadsheet).getData();`
`  12:      }`
`  13:   `
`  14:      public DataDrivenTestsWithSpreadsheetTest(int a, int b, int aDivideB) {`
`  15:          super();`
`  16:          this.a = a;`
`  17:          this.b = b;`
`  18:          this.aDivideB = aDivideB;`
`  19:      }`
`  20:      `
`  21:      private void testDivideByZero(int a, int b) throws Exception {`
`  22:          try {`
`  23:              Divide.divide(a, b);`
`  24:              fail("My method didn't throw when I expected it to");`
`  25:          } catch (ArithmeticException e) {`
`  26:          } catch (Exception e) {`
`  27:              fail("My method throws different Exception when I expect ArithmeticException");`
`  28:          }`
`  29:      }`
`  30:   `
`  31:      @Test`
`  32:      public void shouldCalculateADivideB() {`
`  33:        if(b==0){`
`  34:            testDivideByZero(a, b);`
`  35:        }`
`  36:        else`
`  37:            assertEquals(aDivideB, Divide.divide(a, b));`
`  38:      }`
`  39:  }`

Advantages:
1.  Adding new Test scenarios is easy as it requires just adding a new row in the excel/csv/wiki.
2. Helps in the documentation of the test cases that we have identified and tested.