MELJUN CORTES Java Lecture Intro to TDD
Upcoming SlideShare
Loading in...5

MELJUN CORTES Java Lecture Intro to TDD



MELJUN CORTES Java lecture Intro to TDD

MELJUN CORTES Java lecture Intro to TDD



Total Views
Views on SlideShare
Embed Views



0 Embeds 0

No embeds



Upload Details

Uploaded via as Microsoft PowerPoint

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.

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
Post Comment
Edit your comment
  • Adding tests to an existing project is hard. <br /> The code did not have testing in mind. <br /> You might not know what each class does. <br /> You usually have very short deadlines to add a feature. No time to stop and just add tests to the whole system. <br />

MELJUN CORTES Java Lecture Intro to TDD MELJUN CORTES Java Lecture Intro to TDD Presentation Transcript

  • Intr oduction to Unit Testing & TestDriven Development MELJUN CORTES Java Fundamentals and Object-Oriented Programming The Complete Java Boot Camp MELJUN CORTES
  • What is unit testing?  Testing is often divided into categories such as: Unit testing  Testing a ‘unit’ of code, usually a class or method  Integration testing  Testing a module of code (e.g. a package)  Application testing  Testing the code as the user would see it (black box)  Types of Automated Tests  unit tests  acceptance tests 
  • Rationale  Fixing a bug is usually pretty quick… finding it is a nightmare.
  • Rationale  It is easier to find a needle in a haystack if you have a smaller haystack.
  • Rationale  A suite of tests is a powerful bug-detector that decapitates the time it takes to find bugs.
  • What is Junit?  JUnit is a unit testing framework written by Erich Gamma and Kent Beck  primary unit testing tool for java  Can integrated into IDE, run stand-alone, or part of scripted environments (e.g. ANT)  It is found at  It consists of classes that the developer can extend to write a test – notably junit.framework.TestCase - and related structure to run and report the tests
  • Writing a test • • Directions can be found in the Junit cookbook Sound bite summary • Subclass TestCase, call them <XXX>Test • Write methods which run your tests, calling them test<Foo> • Call a test runner with your test • When you want to check a value, call an assert method (e.g. assertTrue()) and pass a condition that is true if the test succeeds
  • Writing a test - example public void testAddingDifferentCurrencies() { // [12 CHF] + [14 CHF] + [28 USD] == {[26 CHF][28 USD]} Money f26CHF = new Money(26,”CHF”); Money f28USD = new Money(28,”USD”); Money f12CHF = new Money(12,”CHF”); Money f14CHF = new Money(14,”CHF”); Money bag[]= { f26CHF, f28USD }; MoneyBag expected= new MoneyBag(bag); MoneyBag result = f12CHF.add(f28USD.add(f14CHF)); assertEquals(expected,result); }
  • Test Fixture methods  setUp – does initialization common to all tests It is run each time a test is run (can’t store state in variables that are set in setUp)  tearDown – releases resources, e.g. database connections.  TestCase can also have other helper methods, just don’t name them test<anything> 
  • Assert methods  There are a variety of assert methods available, e.g. assertTrue, assertFalse, assertNull, assertSame, assertEquals, etc.  In general, the syntax is  assert<Foo>(<type> expected, <type> testVal)  assert<Foo>(String message, <type> expected, <type> testVal) 
  • Running tests  Call from IDE /Ant – no need for main class  Stand-alone: need to call a runner run method, e.g;  Example main class for running tests  // imports public class ATestSuite { public static TestSuite suite () { TestSuite suite = newTestSuite(“MyPackageTests”); suite.addTestSuite(“MyClassTests.class”); return suite; } public static void main(String args[]) {; } }
  • Project structure  One way to organize tests is to put them in a parallel directory tree (recommended):  E.g. src/ …. Has a parallel tree of test/ …  Alternative way is to put them in their own package:  E.g. Has tests in
  • Junit Demo  Lets try it out!  Test Money Class
  • Money Example – package com.onb.moneyexample; – public class Money { – – – – – – – – private int amount; private String currency; public Money(int amount, String currency) {  this.amount = amount;  this.currency = currency; } public int getAmount() {  return amount; } public String getCurrency() {  return currency; }
  • Money Example (2) – – – – – – public boolean equals(Object other){  if (!(other instanceof Money)){  return false;  }  Money m = (Money) other;  return (amount == m.amount) && (currency.equals(m.currency)); } public int hashCode(){  return amount * 7 * currency.hashCode(); } public String toString(){  return amount + " " + currency; }
  • Money Example (3)  public Money times(int multiplier) { – –  – } } return new Money(amount * multiplier, currency);
  • MoneyTest Example – package com.onb.moneyexample; – import junit.framework.TestCase; – public class MoneyTest extends TestCase {  public static void main(String[] args) { –;  }  public void testCreateMoney(){ – – assertEquals(5,fivepesos.getAmount()); – } assertNotNull(fivepesos); –  Money fivepesos = new Money(5,"PhP"); assertEquals("PhP", fivepesos.getCurrency());
  • MoneyTest Example (2)  public void testEquals(){ – – assertTrue(apeso.equals(anotherpeso)); – Money twopesos = new Money(2,"PhP"); – assertFalse(twopesos.equals(apeso)); – assertFalse(twopesos.equals("1 PhP")); – Money adollar = new Money(1,"USD"); – } Money anotherpeso = new Money(1,"PhP"); –  Money apeso = new Money(1,"PhP"); assertFalse(adollar.equals(apeso));
  • MoneyTest Example (3)  public void testHashCode(){ – – Money tendollars = new Money(10,"USD"); – assertFalse(tendollars.hashCode() == tenpesos.hashCode()); – Money ninepesos = new Money(9,"PhP"); – } assertEquals(7*10* "PhP".hashCode(), tenpesos.hashCode()); –  Money tenpesos = new Money(10,"PhP"); assertFalse(ninepesos.hashCode() == tenpesos.hashCode());
  • MoneyTest Example(4)  public void testToString(){ – Money fivepesos = new Money(5,"PhP"); – assertEquals("5 PhP", fivepesos.toString());  }  public void testAddMoney(){ – – – } assertEquals(new Money(15,"PhP"), fivepesos.times(3)); – } assertEquals(new Money(10,"PhP"), fivepesos.times(2)); –  Money fivepesos = new Money(5,"PhP"); assertEquals(new Money(5,"PhP"), fivepesos);
  • Test-Driven Development Java Fundamentals and Object-Oriented Programming The Complete Java Boot Camp
  • Definition  Software-development philosophy where the writing of automated tests is central.
  • Test-First  Tests are written before the code. Tests specify the behavior of the component.  Tests guide design    Programmers are forced to write decoupled classes. Programmers see the class from the point of view of the user of the class.
  • Programmer Tests  Unit Tests are written by the programmers who wrote the components being tested.  …not delegated to junior programmers or to “QA” programmers.
  • Test as You Code  Writing unit tests should not be done at the same time you write your component.  Rhythm of coding:  Code a little… Test a little… Code a little… Test a little… Code a little… Test a little…
  • Management Implications  If code has no automated test case written to prove that it works, it must be assumed not to work.   Team leaders may validly reject code submitted without unit tests. Unit tests are usually easier to read and QA, making code-management easier.
  • Other Implications  Software without automated test cases cannot be economically refactored.  Automated unit-level testing of Java classes is an essential ingredient to continuous integration.
  • Unit-Testing Best Practices Java Fundamentals and Object-Oriented Programming The Complete Java Boot Camp
  • Best Practices  Tests shouldn’t be dependent on other tests  Don’t test things that can’t break  Ex: simple getters and setters
  • Best Practices  Don’t rely on the ordering of test cases  Avoid side effects  Read test data from a relative path or the CLASSPATH  Avoid code duplication in test cases  TDD: test should fail first, to assure that the test is ok!
  • Best Practices  Separate production and test code  But typically in the same packages  Measure test coverage  Use automated tools to measure test-coverage
  • Best Practices Debugging w/ Tests  Martin Fowler: "Whenever you are tempted to type something into a print statement or a debugger expression, write it as a test instead.” 1. Use tests to reproduce the bug. 2. Fix the bug until your tests pass.
  • Best Practices  Once your tests are running, make sure they stay running.  If you start to allow your tests to fail, pretty soon your suite will be useless.
  • Best Practices  Optimize your test suite  Try to have a fast test suite so that all tests can be run for every change.  Fast machines will help.  If this can’t be done, group your tests into smaller suites that can be run appropriately when relevant portions are changed.   But make sure all tests are run at least once a day. Maybe you can have a dedicated machine that runs all your tests on new builds.
  • Le gacy Testing Adding Tests to an Existing Project
  • Legacy Testing  Some tests are better than no tests  Think in terms of cost-benefit analysis. Prioritize: 1. 2. 3. 4. 5. common case alternate cases error conditions boundary conditions extreme conditions
  • Legacy Testing  Add tests before fixing bugs.  Add tests before refactoring.