• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Data-Driven Unit Testing for Java
 

Data-Driven Unit Testing for Java

on

  • 7,174 views

An overview of the mainstream data-driven test frameworks for Java, including pros/cons and code samples.

An overview of the mainstream data-driven test frameworks for Java, including pros/cons and code samples.

Statistics

Views

Total Views
7,174
Views on SlideShare
7,088
Embed Views
86

Actions

Likes
3
Downloads
0
Comments
0

13 Embeds 86

http://sourcepatch.blogspot.com 34
http://www.slideshare.net 28
http://sourcepatch.blogspot.in 6
https://www.calgbapps.org 4
http://sourcepatch.blogspot.jp 3
http://sourcepatch.blogspot.com.br 2
http://www.linkedin.com 2
http://sourcepatch.blogspot.de 2
http://sourcepatch.blogspot.se 1
http://webcache.googleusercontent.com 1
http://sourcepatch.blogspot.fr 1
http://sourcepatch.blogspot.hu 1
http://sourcepatch.blogspot.it 1
More...

Accessibility

Upload Details

Uploaded via as OpenOffice

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Data-Driven Unit Testing for Java Data-Driven Unit Testing for Java Presentation Transcript

    • Advanced Unit Testing for Java By Denilson Nastacio Data-Driven Unit Testing
    • Your Host
      • Denilson Nastacio
      • 14 years in software development
      • Quality Enthusiast
      • Rational Unified Process practitioner
      • RTP Scrolls ( http://rtpscrolls.blogspot.com )
      • SourcePatch ( http://sourcepatch.blogspot.com )
      • LinkedIn ( http://www.linkedin.com/in/nastacio )
    • Introduction
      • Example
      • Your guessed right, a bank account :-)
      • Conventional unit testing
      • Adequate…sometimes
      • When coverage is not everything
      • Multiple combinations of input values
      • Multiple internal states
      • Complex behavior
      • The Contenders
      • JUnit 3.8
      • JUnit 4.x
      • TestNG
      • DDTUnit
    • Checking Account
      • public class Account {
      • private float balance;
      • private float lineOfCredit;
      • public Account( float balance, float lineOfCredit) {
      • super ();
      • this .balance = balance;
      • this .lineOfCredit = lineOfCredit;
      • }
      • public void deposit( float value) {
      • if (value < = 0) {
      • throw new IllegalArgumentException( “ Deposit value (“ + value + “) is not grater than 0 &quot; );
      • }
      • balance += value;
      • }
      • public float getBalance() {
      • return balance;
      • }
    • Junit 3.8
      • public void test Valid Deposit() {
      • Account acc = new Account(0f , 0f);
      • acc.deposit(50f);
      • assertEquals (50f, acc.getBalance(), 0f);
      • }
      • public void test Zero Deposit() {
      • Account acc = new Account(0f , 0f);
      • try {
      • acc.deposit(0f);
      • fail( &quot;Deposit should fail&quot; );
      • } catch (IllegalArgumentException e) {
      • // expected
      • }
      • }
      • public void test Negative Deposit() {
      • Account acc = new Account(0f , 0f);
      • try {
      • acc.deposit(-50f);
      • fail( &quot;Deposit should fail&quot; );
      • } catch (IllegalArgumentException e) {
      • // expected
      • }
      • }
    • JUnit 3.8 – Pros and Cons
      • Pros
      • Short learning curve
      • Trivial to write
      • Cons
      • Tedious to write
      • Long files
      • Input data mixed with source code: difficult to glean all input combinations
    • JUnit 4.x – Using parameterized tests
      • @RunWith (Parameterized. class )
      • public class AccountTest extends TestCase {
      • private float lineOfCredit;
      • private float deposit;
      • private Object result;
      • @Parameters
      • public static Collection data() {
      • return Arrays. asList ( new Object[][] {
      • { 0f, 50f, 50f },
      • { 0f, 0f, new IllegalArgumentException() },
      • { 0f, -5 0f, new IllegalArgumentException() } });
      • }
      • public AccountTest( float lineOfCredit, float deposit,
      • Object result) {
      • this .lineOfCredit = lineOfCredit;
      • this .deposit = deposit;
      • this .result = result;
      • }
      • @Test
      • public void deposit() {
      • Account acc = new Account(0.0f, lineOfCredit);
      • boolean expectError = false ;
      • if (result instanceof IllegalArgumentException) {
      • expectError = true ;
      • }
      • try {
      • acc.deposit(deposit);
      • if (expectError) {
      • fail( &quot;Deposit should fail&quot; );
      • } else {
      • assertEquals(acc.getBalance(),
      • ((Float) result).floatValue(), 0f);
      • }
      • } catch (IllegalArgumentException e) {
      • if (!expectError) {
      • throw e;
      • }
      • }
      • }
    • JUnit 4.x – Pros and Cons
      • Pros
      • Built-in separation of data and logic
      • Good integration with Eclipse
      • Cons
      • One class per collection of input parameters
      • Difficult to handle collections of input parameters for verification of successful runs versus exception handling.
      • No labels for parameter sets
    • TestNG
      • <!DOCTYPE suite SYSTEM &quot;http://testng.org/testng-1.0.dtd&quot;>
      • <suite name=&quot;banking-test&quot;>
      • <test name=&quot;testValidDeposit&quot;>
      • <parameter name=&quot;lineOfCredit&quot; value=&quot;0f&quot;/>
      • <parameter name=&quot;deposit&quot; value=&quot;50f&quot;/>
      • <parameter name=&quot;result&quot; value=&quot;50f&quot;/>
      • <classes>
      • <class name=&quot; com.ibm.qse.banking.AccountTestNgTest &quot;>
      • <methods>
      • <include name=&quot; testDeposit &quot;/>
      • </methods>
      • </class>
      • </classes>
      • </test>
      • <test name=&quot;testZeroDeposit&quot;>
      • <parameter name=&quot;lineOfCredit&quot; value=&quot;0f&quot;/>
      • <parameter name=&quot;deposit&quot; value=&quot;0f&quot;/>
      • <parameter name=&quot;result&quot; value=&quot;IllegalArgumentException&quot;/>
      • <classes>
      • <class name=&quot; com.ibm.qse.banking.AccountTestNgTest &quot;>
      • ...
      • </class>
      • </classes>
      • </test>
      • <test name=&quot;testNegativeDeposit&quot;>
      • <parameter name=&quot;lineOfCredit&quot; value=&quot;0f&quot;/>
      • <parameter name=&quot;deposit&quot; value=&quot;-50f&quot;/>
      • <parameter name=&quot;result&quot; value=&quot;IllegalArgumentException&quot;/>
      • <classes>
      • <class name=&quot; com.ibm.qse.banking.AccountTestNgTest &quot;>
      • ...
      • </class>
      • </classes>
      • </test>
      • </suite>
      Selected methods must be specified in each “test”element
    • TestNG – Parameterized tests – Java source
      • public class AccountTestNgTest {
      • @Test
      • @Parameters( { &quot;lineOfCredit&quot;, &quot;deposit&quot;, &quot;result&quot; })
      • public void testDeposit( float lineOfCredit, float deposit, String result) {
      • Account acc = new Account(0f, lineOfCredit);
      • float expectedBalance = 0f;
      • try {
      • expectedBalance = Float. parseFloat (result);
      • acc.deposit(deposit);
      • assertEquals (expectedBalance, acc.getBalance());
      • } catch (NumberFormatException e) {
      • try {
      • acc.deposit(deposit);
      • fail ( &quot;Deposit should fail&quot; );
      • } catch (IllegalArgumentException e1) {
      • // expected
      • }
      • }
      • }
      TestNG does not support complex Java objects
    • TestNG – Pros & Cons
      • Pros
      • Complete separation of data and logic; separate files
      • Allows named parameter sets
      • Good support for grouping tests
      • Good integration with Eclipse
      • Cons
      • No support for complex Java types in the testng.xml file (that is a big one)
      • Tests in the xml file grouped by parameters instead of class-methods, must map each input sets to a method every time
      • JUnit competitor (increased learning curve)
      • Additional Eclipse plug-in required
    • DDTUnit – XML file (DDT-AccountTest.xml)
      • <?xml version=&quot;1.0&quot; encoding=&quot;ISO-8859-1&quot;?>
      • <ddtunit xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
      • xsi:noNamespaceSchemaLocation=&quot;ddtunit.xsd&quot;>
      • <cluster id=&quot; AccountTest &quot;>
      • <group id=&quot; testDeposit &quot;>
      • <test id=&quot;valid&quot;>
      • <objs>
      • <obj id= &quot;lineOfCredit&quot; type=&quot;float&quot;>50</obj>
      • <obj id= &quot;deposit&quot; type=&quot;float&quot;>50</obj>
      • </objs>
      • <asserts>
      • <assert id= &quot;balance&quot; type=&quot;float&quot; action=&quot;isEqual&quot;>50.0f</assert>
      • </asserts>
      • </test>
      • <test id=&quot;zero&quot;>
      • <objs>
      • <obj id=&quot;lineOfCredit&quot; type=&quot;float&quot;>50</obj>
      • <obj id=&quot;deposit&quot; type=&quot;float&quot;>0</obj>
      • </objs>
      • <asserts>
      • <exception id=&quot;expectedException&quot; type=&quot;java.lang.IllegalArgumentException&quot;
      • action=&quot;isSimilar&quot;>0</exception>
      • </asserts>
      • </test>
      • <test id=&quot;negative&quot;>
      • <objs>
      • <obj id=&quot;lineOfCredit&quot; type=&quot;float&quot;>50</obj>
      • <obj id=&quot;deposit&quot; type=&quot;float&quot;>-50</obj>
      • </objs>
      • <asserts>
      • <exception id=&quot;expectedException“ type=&quot;java.lang.IllegalArgumentException&quot;
      • action=&quot;isSimilar&quot;>-50</exception>
      • </asserts>
      • </test>
      • </group>
      • </cluster>
      • </ddtunit>
      Class name Method name
    • DDTUnit – Java source
      • public class AccountDDTUnitTest extends DDTTestCase {
      • public void testDeposit() {
      • float lineOfCredit = ((Float)getObject( &quot;lineOfCredit&quot; )).floatValue();
      • float deposit = ((Float)getObject( &quot;deposit&quot; )).floatValue();
      • Account acc = new Account(0f,lineOfCredit);
      • acc.deposit(deposit);
      • addObjectToAssert( &quot;balance&quot; , new Float(acc.getBalance()));
      • }
      • protected void initContext() {
      • initTestData( &quot;AccountTest&quot; );
      • }
      • }
      Inherits from junit.framework.TestCase DDTUnit definition file: DDT-AccountTest.xml
    • DDTUnit – Pros & Cons
      • Pros
      • Complete separation of data and logic; separate files
      • Allows the cleanest Java source code
      • Support for complex Java types
      • Support for verification of exceptions
      • Supports global test data
      • Based on JUnit
      • Good support for grouping tests
      • Cons
      • XML syntax can be a language on its own when dealing with complex structures
      • Poor integration with Eclipse, programmer must rely on console outputs as well
    • DDTUnit – A closer look http://www.flickr.com/photos/xfrf/2260850105/ by xfrf
    • DDTUnit Example: Complex object with a string constructor
      • Class constructor
      • public ObjectName(String name) { ... }
      • Inside DDT-<namekey>.xml file
      • <obj id=&quot; jmxId &quot; type=&quot;javax.management.ObjectName&quot;>
      • <item>WebSphere:type=cellManager</item>
      • </obj>
      • Inside TestCase java file
      • javax.management.ObjectName jmxId =
      • (javax.management.ObjectName)getObject(&quot; jmxId &quot; );
    • DDTUnit Example: Complex object with a complex constructor
      • Class constructor
      • public Attribute(String name, String value) {... }
      • Inside DDT-<namekey>.xml file
      • < obj id= &quot; jmxAttr &quot; type=&quot;javax.management.Attribute&quot; hint=&quot;call&quot;
      • method=&quot;constructor&quot;>
      • <item type=&quot;string&quot;>fileName</item>
      • <item type=&quot;string&quot;> directory< /item>
      • </item>
      • Inside TestCase java file
      • javax.management. Attribute jmxId =
      • (javax.management. Attribute )getObject(&quot; jmxAttr &quot; );
    • DDTUnit Example Defining a java.util.ArrayList
      • Inside DDT-<namekey>.xml file
      • <obj id= “ profileLocations &quot; type=&quot;java.util. ArrayList &quot; hint=&quot;collection&quot; valuetype=&quot;string&quot;>
      • <item>/opt/IBM/WebSphere/AppServer/profiles/s1</item>
      • <item>/opt/IBM/WebSphere/AppServer/profiles/s 2 </item>
      • <item>/opt/IBM/WebSphere/AppServer/profiles/s 3 </item>
      • </obj>
      • Inside TestCase java file
      • ArrayList <String> profileLocations =
      • ( ArrayList <String>)getObject(&quot; profileLocations &quot; );
    • DDTUnit Example Array of complex objects
      • Inside DDT-<namekey>.xml file
      • <obj id=&quot; arrayId &quot; type=“ java.util .A rray List&quot; hint=&quot;collection&quot;>
      • <item type=&quot;javax.management.Attribute&quot; hint=&quot;call&quot; method=&quot;constructor&quot;>
      • <item type=&quot;string&quot;>fileName</item>
      • <item type=&quot;string&quot;>${SERVER_ROOT}/trace.log</item>
      • </item>
      • </obj>
      • Inside TestCase java file
      • ArrayList<Attribute > profileLocations =
      • ( ArrayList < Attribute >)getObject(&quot; arrayId &quot; );
    • DDTUnit and Eclipse Snippets http://sourcepatch.blogspot.com/2009/08/ddtunit-and-eclipse-snippets.html
    • Other noteworthy frameworks
      • JTestCase
        • Similar to DDTUnit but lacks a test runner
        • Requires testcase to extract data from XML file and pass it to fixtures
      • Fit
        • High-level data definition using MS-Word and MS-Excel
        • Inadequate for unit testing, support for strings and basic numeric types
      • Jetif
        • Full replacement for JUnit + JTestCase
        • Lost me on “full replacement”
    • Resources
      • JUnit ( http:// www.junit.org / )
      • DDTUnit ( http://sourceforge.net/projects/ddtunit )
      • TestNG ( http://testng.org/doc/ )
      • JTestCase ( http://jtestcase.sourceforge.net/ )
      • Jetif ( http:// jetif.sourceforge.net )
      • FIT ( http://fit.c2.com/ )
      • My del.icio.us bookmarks for this presentation (tag: qse-ddt)
        • http://delicious.com/nastacio/qse-ddt