JUnitTest Infected: Programmers Love Writing Tests A little test, a little code, a little test, a little code…

Slides:



Advertisements
Similar presentations
JUnit Tutorial Hong Qing Yu Nov JUnit Tutorial The testing problems The framework of JUnit A case study JUnit tool Practices.
Advertisements

1 Unit Testing with JUnit CS 3331 Fall 2009 Kent Beck and Eric Gamma. Test Infected: Programmers Love Writing Tests, Java Report, 3(7):37-50, Available.
J-Unit Framework.
Singleton vs utility class  at first glance, the singleton pattern does not seem to offer any advantages to using a utility class  i.e., a utility class.
Objectives: Test Options JUnit Testing Framework TestRunners Test Cases and Test Suites Test Fixtures JUnit.
Approach of Unit testing with the help of JUnit Satish Mishra
3. A Testing Framework. © O. Nierstrasz P2 — A Testing Framework 3.2 A Testing Framework Overview  What is a framework?  What is an Annotation?  JUnit.
JUnit. What is unit testing? A unit is the smallest testable part of an application. A unit test automatically verifies the correctness of the unit. There.
1 Software Testing and Quality Assurance Lecture 23 – JUnit Tutorial.
JUnit, Revisited 17-Apr-17.
3. A Testing Framework. © O. Nierstrasz P2 — A Testing Framework 3.2 A Testing Framework Overview  What is a framework?  JUnit — a simple testing framework.
3. A Testing Framework. © O. Nierstrasz P2 — A Testing Framework 3.2 A Testing Framework Sources  JUnit documentation (from
JUnit Introduction and Advanced Features. Topics Covered  Junit Introduction  Fixtures  Test Suites  Currency Example.
Exemplo de desenvolvimento com testes Prof. Dr. Alfredo Goldman Departamento de Ciência da Computação IME / USP 3 de Abril de 2003 VI Semana da Computação.
Writing a Unit test Using JUnit At the top of the file include: import junit.framework.TestCase; The main class of the file must be: public Must extend.
3. A Testing Framework. © O. Nierstrasz P2 — A Testing Framework 3.2 A Testing Framework Sources  JUnit 4.0 documentation (from
© S. Demeyer, S. Ducasse, O. Nierstrasz Chapter.1 Unit Testing Explained How to support changes? How to support basic but synchronized documentation?
1 CSC/ECE 517 Fall 2010 Lec. 2 Overview of Eclipse Lectures 1.Overview 2.Installing and Running 3.Building and Running Java Classes 4.Debugging 5.Testing.
Presentation Outline What is JUnit? Why Use JUnit? JUnit Features Design of JUnit Downloading JUnit Writing Tests – TestCase – TestSuite Organizing The.
Inheritance Part II. Lecture Objectives To learn about inheritance To understand how to inherit and override superclass methods To be able to invoke superclass.
George Blank University Lecturer. JUnit for Test Driven Development By Vivek Bhagat, George Blank.
A Unit Testing Framework: JUnit COMP 302 Software Engineering Koc University, Istanbul.
Programmer Testing Testing all things Java using JUnit and extensions.
The Design of JUnit Yonglei Tao. Test-First Development  An essential element in eXtreme Programming (XP)  Test is written before the code  As an executable.
Learning JUnit for Unit Testing JUnit Tutorial Dr. Robert L. Probert S.I.T.E., University of Ottawa Sept
JUnit The framework. Goal of the presentation showing the design and construction of JUnit, a piece of software with proven value.
1 Code Quality, Maintainability, Reusability, Debugging, Testing SIF8080, Sep. 27th 2001 Customer-driven project Carl-Fredrik Sørensen
Unit Testing Bartosz Walter Software Engineering Lecture XXX.
1 Testing With The JUnit Framwork Carl-Fredrik Sørensen, PhD Fellow
Programming in Java Unit 2. Class and variable declaration A class is best thought of as a template from which objects are created. You can create many.
Unit testing Unit testing TDD with JUnit. Unit Testing Unit testing with JUnit 2 Testing concepts Unit testing Testing tools JUnit Practical use of tools.
Software Engineering 1 Object-oriented Analysis and Design Chap 21 Test-Driven Development and Refactoring.
CSC 216/001 Lecture 4. Unit Testing  Why is it called “unit” testing?  When should tests be written?  Before the code for a class is written.  After.
Software Testing, Debugging and JUnit Ananda Gunawardena Hao Cen.
JUnit test and Project 3 simulation. 2 JUnit The testing problems The framework of JUnit A case study Acknowledgement: using some materials from JUNIT.
Introduction to JUnit 3.8 SEG 3203 Winter ‘07 Prepared By Samia Niamatullah.
JUnit Dwight Deugo Nesa Matic
Chapter 11, Testing: Unit Testing with JUnit 4
Unit Testing with JUnit and Clover Based on material from: Daniel Amyot JUnit Web site.
CSC 480 Software Engineering Lecture 15 Oct 21, 2002.
JUnit Dwight Deugo Nesa Matic
A tool for test-driven development
Testing and Build JUnit and Ant. JUnit Testing is not closely integrated with development. This prevents you from measuring the progress of development-
Inheritance (Part 5) Odds and ends 1. Static Methods and Inheritance  there is a significant difference between calling a static method and calling a.
Program Testing, Debugging and JUnit. Program Development Process A simplified process –User requirement  Development  Delivery A simplified process.
EMBEDDED REAL-TIME, INC. December 8, 2015 Java Unit Mark Mosher Rochester Java Users Group.
JUnit Don Braffitt Updated: 10-Jun-2011.
JUnit Eclipse, Java and introduction to Junit. Topics Covered  Using Eclipse IDE  Example Java Programs  Junit Introduction.
JUnit A framework which provides hooks for easy testing of your Java code, as it's built Note: The examples from these slides can be found in ~kschmidt/public_html/CS265/Labs/Java/Junit.
Using UML, Patterns, and Java Object-Oriented Software Engineering Chapter 11, Testing.
S Ramakrishnan1 Systems V & V, Quality and Standards Dr Sita Ramakrishnan School CSSE Monash University.
Unit Testing CSSE 514 Programming Methods 4/19/01.
Unit, Regression, and Behavioral Testing Based On: Unit Testing with JUnit and CUnit by Beth Kirby Dec 13, 2002 Jules.
OOSC – Lab 1. Welcome Object Oriented programming is first and foremost a method for software construction, whose goal is to build high-quality software.
(c) University of Washington06-1 CSC 143 Java Inheritance Tidbits.
1 JUnit. 2 Unit Testing with JUnit If code has no automated test case written for it to prove that it works, it must be assumed not to work. An API that.
Topic: Junit Presenters: Govindaramanujam, Sama & Jansen, Erwin.
Getting Started with JUnit Getting Started with JUnit The benefits and ease of writing and running JUnit test cases and test suites. The benefits and ease.
Software Construction Lab 10 Unit Testing with JUnit
JAVA MULTIPLE CHOICE QUESTION.
Unit testing Java programs Using JUnit
Computer Science 209 Testing With JUnit.
Overview of Eclipse Lectures
Chapter 11, Testing.
Introduction to JUnit IT323 – Software Engineering II
Unit testing with JUnit
Learning JUnit for Unit Testing
Joel Adams and Jeremy Frens Calvin College
JUnit Dwight Deugo Nesa Matic Portions of the notes for this lecture include excerpts from the Eclipse 3.0 and.
JUnit Tutorial Hong Qing Yu Nov 2005.
Presentation transcript:

JUnitTest Infected: Programmers Love Writing Tests A little test, a little code, a little test, a little code…

Problem statement Representing arithmetic with multiple currencies You cannot just convert one currency into another for doing arithmetic since there is no single conversion rate you may need to compare the value of a portfolio at yesterday's rate and today's rate

class Money { private int fAmount; //ISO three letter abbreviation (USD, CHF, etc.). private String fCurrency; public Money(int amount, String currency){ fAmount= amount; fCurrency= currency; } public int amount() { return fAmount; } public String currency() { return fCurrency; } public Money add(Money m) { return new Money(amount()+m.amount(),currency()); } }

When you add two Moneys of the same currency, the resulting Money has as its amount the sum of the other two amounts public class MoneyTest extends TestCase { //… public void testSimpleAdd() { Money m12CHF= new Money(12, "CHF"); // (1) Money m14CHF= new Money(14, "CHF"); Money expected= new Money(26, "CHF"); Money result= m12CHF.add(m14CHF); // (2) assert(expected.equals(result)); // (3) } 1.Code which creates the objects we will interact with during the test. This testing context is commonly referred to as a test's fixture.Code 2.Code which exercises the objects in the fixture.Code 3.Code which verifies the result.Code

Two Monies are considered equal if they have the same currency and value public void testEquals() { Money m12CHF= new Money(12, "CHF"); Money m14CHF= new Money(14, "CHF"); assert(!m12CHF.equals(null)); assertEquals(m12CHF, m12CHF); assertEquals(m12CHF, new Money(12, "CHF")); // (1) assert(!m12CHF.equals(m14CHF)); } assert triggers a failure that is logged by JUnit when the argument isn't true. assertEquals testing for equality with equals, logs the printed value of the two objects in the case they differ.

equals in class Money public boolean equals(Object anObject) { if (anObject instanceof Money){ Money aMoney= (Money)anObject; return aMoney.currency().equals(currency()) && amount() == aMoney.amount(); } return false; }

Common fixture some code duplication for setting-up the tests. the setUp method to reuse some of this test set-up code. With JUnit you can do so by storing the fixture's objects in instance variables of your TestCase class initialize them by overridding the setUp method. the tearDown method the symmetric operation to setUp override to clean up the test fixture at the end of a test. Each test runs in its own fixture JUnit calls setUp and tearDown for each test there can be no side effects among test runs

Rewriting of tests – removing duplicate code public class MoneyTest extends TestCase { private Money f12CHF; private Money f14CHF; protected void setUp() { f12CHF= new Money(12, "CHF"); f14CHF= new Money(14, "CHF"); } public void testEquals() { assert(!f12CHF.equals(null)); assertEquals(f12CHF, f12CHF); assertEquals(f12CHF, new Money(12, "CHF")); assert(!f12CHF.equals(f14CHF)); } public void testSimpleAdd() { Money expected= new Money(26, "CHF"); Money result= f12CHF.add(f14CHF); assert(expected.equals(result)); } protected void tearDown() { f12CHF= null; f14CHF= null; }

Running single tests Static override the runTest method inherited from TestCase call the desired test case TestCase test= new MoneyTest("simple add"){ public void runTest( { testSimpleAdd(); } }; Dynamic uses reflection to implement runTest TestCase test= new MoneyTest("testSimpleAdd");

Test suite TestSuite is a Composite (Design Pattern) A TestSuite can run a collection of tests. TestSuite and TestCase both implement an interface called Test which defines the methods to run a test. This enables the creation of test suites by composing arbitrary TestCases and TestSuites. public static Test suite() { TestSuite suite= new TestSuite(); suite.addTest(new MoneyTest("testEquals")); suite.addTest(new MoneyTest("testSimpleAdd")); return suite; }

Static test suite public static Test suite() { TestSuite suite= new TestSuite(); suite.addTest(new MoneyTest("money equals") { protected void runTest() { testEquals(); } } ); suite.addTest( new MoneyTest("simple add") { protected void runTest() { testSimpleAdd(); } } ); return suite; }

Dynamic test suite only pass the class with the tests to a TestSuite it extracts the test methods automatically public static Test suite() { return new TestSuite(MoneyTest.class); }

Mixed currency arithmetic there isn't a single exchange rate. To avoid this problem we introduce a MoneyBag which defers exchange rate conversions. class MoneyBag { private Vector fMonies= new Vector(); MoneyBag(Money m1, Money m2) { appendMoney(m1); appendMoney(m2); } MoneyBag(Money bag[]) { for (int i= 0; i < bag.length; i++) appendMoney(bag[i]); } appendMoney adds a Money to the list of Money s takes care of consolidating Monies with the same currency.

Testing MoneyBag protected void setUp() { f12CHF= new Money(12, "CHF"); f14CHF= new Money(14, "CHF"); f7USD= new Money( 7, "USD"); f21USD= new Money(21, "USD"); fMB1= new MoneyBag(f12CHF, f7USD); fMB2= new MoneyBag(f14CHF, f21USD); } public void testBagEquals() { assert(!fMB1.equals(null)); assertEquals(fMB1, fMB1); assert(!fMB1.equals(f12CHF)); assert(!f12CHF.equals(fMB1)); assert(!fMB1.equals(fMB2)); }

public Money add(Money m) { if (m.currency().equals(currency()) ) return new Money(amount()+m.amount(), currency()); return new MoneyBag(this, m); } now two representations for Moneys : Money and MoneyBag we would like to hide them from the client code. To do so we introduce an interface IMoney that both representations implement. interface IMoney { public abstract IMoney add(IMoney aMoney); //… }

Tests for the addition of Monies public void testMixedSimpleAdd() { // [12 CHF] + [7 USD] == {[12 CHF][7 USD]} Money bag[]= { f12CHF, f7USD }; MoneyBag expected= new MoneyBag(bag); assertEquals(expected, f12CHF.add(f7USD)); } The other tests follow the same pattern: testBagSimpleAdd - to add a MoneyBag to a simple Money testSimpleBagAdd - to add a simple Money to a MoneyBag testBagBagAdd - to add two MoneyBags

Test suite for MoneyBag public static Test suite() { TestSuite suite= new TestSuite(); suite.addTest(new MoneyTest("testMoneyEquals")); suite.addTest(new MoneyTest("testBagEquals")); suite.addTest(new MoneyTest("testSimpleAdd")); suite.addTest(new MoneyTest("testMixedSimpleAdd")); suite.addTest(new MoneyTest("testBagSimpleAdd")); suite.addTest(new MoneyTest("testSimpleBagAdd")); suite.addTest(new MoneyTest("testBagBagAdd")); return suite; }

Implementation of addition The implementation challenge here is dealing with all the different combinations of Money with MoneyBag. Double dispatch is an elegant way to solve this problem (Visitor DP). The idea behind double dispatch is to use an additional call to discover the kind of argument we are dealing with. We call a method on the argument with the name of the original method followed by the class name of the receiver. class Money implements IMoney { public IMoney add(IMoney m) { return m.addMoney(this); } //… } class MoneyBag implements IMoney { public IMoney add(IMoney m) { return m.addMoneyBag(this); } //… }

Implementation of double dispatch in Money class Money implements IMoney { public IMoney add(IMoney m) { return m.addMoney(this); } public IMoney addMoney(Money m) { if (m.currency().equals(currency()) ) return new Money( amount()+m.amount(), currency()); return new MoneyBag(this, m); } public IMoney addMoneyBag(MoneyBag s) { return s.addMoney(this); }

Implementation of double dispatch in MoneyBag class MoneyBag implements IMoney { public IMoney add(IMoney m) { return m.addMoneyBag(this); } public IMoney addMoney(Money m) { return new MoneyBag(m, this); } public IMoney addMoneyBag(MoneyBag s) { return new MoneyBag(s, this); }

Test for simplification of MoneyBag public void testSimplify() { // {[12 CHF][7 USD]} + [-12 CHF] == [7 USD] Money expected= new Money(7, "USD"); assertEquals( expected, fMS1.add(new Money(-12, "CHF"))); } // … Test fails

Implementation of simplification in MoneyBag class MoneyBag implements IMoney { public IMoney add(IMoney m) { return m.addMoneyBag(this); } public IMoney addMoney(Money m) { return new MoneyBag(m, this).simplify(); } public IMoney addMoneyBag(MoneyBag s) { return new MoneyBag(s, this).simplify(); } private IMoney simplify() { if (fMonies.size() == 1) return (IMoney)fMonies.firstElement(); return this; }

Conclusion A little test, a little code, a little test, a little code… Capture your thoughts in a test Test code is just like model code in working best if it is factored well. Keeping old tests running is just as important as making new ones run. Whenever you are tempted to type something into a print statement or a debugger expression, write it as a test instead A style of testing that with a remarkably small investment will make you a faster, more productive, more predictable, and less stressed developer. You will be able to refactor much more aggressively once you have the tests.

The common interface for simple Monies and MoneyBags interface IMoney { public abstract IMoney add(IMoney m); /** * implementing double dispatch */ IMoney addMoney(Money m); IMoney addMoneyBag(MoneyBag s); public abstract boolean isNull(); public abstract IMoney multiply(int factor); public abstract IMoney negate(); public abstract IMoney subtract(IMoney m); }

References Erich Gamma and Kent Beck, JUnitTest Infected: Programmers Love Writing Tests, Java Report, July 1998, Volume 3, Number 7 ng.htm