Test Driven Lasse Koskela Chapter 4: Concepts and Patterns for TDD

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

Unit Testing Australian Development Centre Brisbane, Australia.
Testing Object Oriented Programs CSE 111 4/28/20151.
Test-Driven Development and Refactoring CPSC 315 – Programming Studio.
Integration Testing When testing a module in isolation –Called modules need to be replaced –Tested module needs to be called A D ′ E ′ main driver module.
API Design CPSC 315 – Programming Studio Fall 2008 Follows Kernighan and Pike, The Practice of Programming and Joshua Bloch’s Library-Centric Software.
Test-Driven Development and Refactoring Project 3 Lecture 1 CPSC 315 – Programming Studio Fall 2009.
1 Advanced Testing Concepts & TDD. 2 Testing vs. DBC DBC: Exhaustive correctness –Post conditions should work on all inputs –Often, highly complicated.
Test Driven development Tor Stålhane. What we will cover We will cover three aspects of testing Testing for green-field projects. This is TDD as it was.
Unit Testing Tips and Tricks: Database Interaction Louis Thomas.
Programmer Testing Testing all things Java using JUnit and extensions.
1 Some Patterns of Novice Programs Author : Eugene Wallingford ; Dan Steinberg ; Robert Duvall ; Ralph Johnson Source : PLoP 2004 Advisor : Ku-Yaw Chang.
JUnit The framework. Goal of the presentation showing the design and construction of JUnit, a piece of software with proven value.
Computer Science and Engineering College of Engineering The Ohio State University JUnit The credit for these slides goes to Professor Paul Sivilotti at.
Designing For Testability. Incorporate design features that facilitate testing Include features to: –Support test automation at all levels (unit, integration,
JUnit in Action SECOND EDITION PETAR TAHCHIEV FELIPE LEME VINCENT MASSOL GARY GREGORY ©2011 by Manning Publications Co. All rights reserved. Slides Prepared.
Capture-Replay Mocks Scandinavian Developer Conference 4 th April 2011 Geoff Bache.
CSC 211 Introduction to Design Patterns. Intro to the course Syllabus About the textbook – Read the introduction and Chapter 1 Good attendance is the.
Software Engineering 1 Object-oriented Analysis and Design Chap 21 Test-Driven Development and Refactoring.
Dependency Injection Technion – Institute of Technology Author: Gal Lalouche - Technion 2015 ©
Design Patterns Gang Qian Department of Computer Science University of Central Oklahoma.
(1) Unit Testing and Test Planning CS2110: SW Development Methods These slides design for use in lab. They supplement more complete slides used in lecture.
Using Mock Objects with Test Driven Development Justin Kohlhepp
SOEN 343 Software Design Section H Fall 2006 Dr Greg Butler
Introduction to JUnit 3.8 SEG 3203 Winter ‘07 Prepared By Samia Niamatullah.
Chapter 11, Testing: Unit Testing with JUnit 4
Unit Testing with JUnit and Clover Based on material from: Daniel Amyot JUnit Web site.
Refactoring & Testability. Testing in OOP programming No life in flexible methodologies and for refactoring- infected developers without SOME kind of.
Chapter 21 Test-Driven Development 1CS6359 Fall 2011 John Cole.
Refactoring 2. Admin Blackboard Quiz Acknowledgements Material in this presentation was drawn from Martin Fowler, Refactoring: Improving the Design of.
Mock objects.
Test-Driven Development Eduard Miric ă. The problem.
JUnit Automated Software Testing Framework Advanced Material Paul Ammann & Jeff Offutt
Design Patterns Software Engineering CS 561. Last Time Introduced design patterns Abstraction-Occurrence General Hierarchy Player-Role.
Copyright 2007 SpringSource. Copying, publishing or distributing without express written permission is prohibited. Testing Spring Applications Unit Testing.
S Ramakrishnan1 Systems V & V, Quality and Standards Dr Sita Ramakrishnan School CSSE Monash University.
SWE 4743 Abstract Data Types Richard Gesick. SWE Abstract Data Types Object-oriented design is based on the theory of abstract data types Domain.
Automated Testing in Sakai Testing applications and services in isolation and in context Josh Holtzman, UC Berkeley David Haines, University of Michigan.
Lecture IX: Testing Web Services with Mocking CS 4593 Cloud-Oriented Big Data and Software Engineering.
Dependency Injection with Guice Technion – Institute of Technology Author: Gal Lalouche - Technion 2016 ©
Test Isolation and Mocking Technion – Institute of Technology Author: Gal Lalouche © 1 Author: Gal Lalouche - Technion 2016 ©
Software Engineering 1 Object-oriented Analysis and Design Applying UML and Patterns An Introduction to Object-oriented Analysis and Design and Iterative.
TDD Unit tests from a slightly different point of view Katie Dwyer.
Lecture 5: Test-Driven Development Basics
Unit Testing - solid fundamentals
Developer Testing Tricks
Eddie Jaquith Alexis Jarvis
MPCS – Advanced java Programming
Designing For Testability
Putting Testing First CS 4501 / 6501 Software Testing
Unit testing Java programs Using JUnit
TDD Overview CS 4501/6501 Software Testing
Computer Science 209 Testing With JUnit.
Unit Testing in a Team Sparkhound Presents by Steve Schaneville
Test Driven Lasse Koskela Chapter 2: Beginning TDD
History, Characteristics and Frameworks
Mocking Your Objects with Impunity
SE-2811 Software Component Design
SOEN 343 Software Design Computer Science and Software Engineering Department Concordia University Fall 2004 Instructor: Patrice Chalin.
Test patterns.
Test Driven Lasse Koskela Chapter 2: Beginning TDD
Test Driven Lasse Koskela Chapter 9: Acceptance TDD Explained
Applying Use Cases (Chapters 25,26)
Applying Use Cases (Chapters 25,26)
Designing For Testability
Chapter 11: Integration- and System Testing
Computer Science 340 Software Design & Testing
Test-Driven Development
Test Driven Lasse Koskela Chapter 3: Refactoring in Small Steps
Junit Tests.
Presentation transcript:

Test Driven Lasse Koskela Chapter 4: Concepts and Patterns for TDD Paul Ammann http://cs.gmu.edu/~pammann/

Overview Lots of Stuff in This Chapter How to Write Tests and Make Them Pass Essential Testing Concepts Closer Look into Test Doubles Guidelines for Testable Designs Unit-Testing Patterns Working With Legacy Code Lots of Stuff in This Chapter 9/20/2018

How to Write Tests And Make Them Pass Test Selection Strategies Details-First vs. Big-Picture Details-First Offers Concrete Progress, but Big-Picture Fleshes Out Overall Design Judgment Call In Any Given Situation Uncertain vs. Familiar Attacking Uncertainty Can Reduce Risk Familiar Code May Have Large Payoff High Value vs. Low Hanging Fruit Usually, High Value is Better Happy Path vs. Error Situations Happy Path First – Mostly for Value Sometimes Error Situations Help Define Remainder as Happy Path Keep Your Options in Mind; Avoid a Rut 9/20/2018

How to Write Tests And Make Them Pass(2) Implementation Strategies Faking It Useful Strategy For Handling Big Steps Incurs Later Obligations To Squeeze Out Fakes Triangulation Strategy For Evolving Towards More General Implementation Use To Drive Out Hard Coded Solutions Obvious Implementation Sometimes The Correct Solution Really Is Simple Try It And See If Tests Fail, Back It Out Goal Is To Get To Green Fast 9/20/2018

How to Write Tests And Make Them Pass(3) Prime Guidelines for Test Driving Do. Not. Skip. Refactoring. The Design Cycle for TDD is Crucial Skipping This Step Leads to Code/Test Bloat Result Is Unmaintainable Software Get To Green Fast Write Code That Passes The Tests First Then Worry About Refactoring Slow Down After a Mistake Mistakes Indicate That Your Reach Exceeds Your Grasp Back Off and Try Smaller Steps The Tests Are The Oracle That Keeps You On Track The First Rule Is The Most Important 9/20/2018

Essential Testing Concepts Fixtures are the Context for Tests Holistic View of State Fixtures Remove Duplication Bloated Tests Are Hard to Read and Hard to Maintain Fixtures Allow For Focused Tests Test Doubles Stand In for Dependencies Example: java.sql.ResultSet Details Depend on Database Used More on Doubles in Later Slides Real-World JUnit Tests Can’t Avoid Some Complexities 9/20/2018

Essential Testing Concepts(2) State and Interaction-Based Testing State-Based Testing Idea Is To Look At Variable State To Verifying Result @Test public void notEmpty() { Collection<String> c = new ArrayList<String>(); assertTrue (c.isEmpty()); c.add(“Bob”); assertFalse(c.isEmpty()); } Testing For Interactions Goal: Did The Expected Methods Calls Happen In The Right Order? Usually Requires Some Sort of Double We lean on interaction-based testing to verify how an object talks to its collaborators; we lean on state-based testing to verify how well the object listens. 9/20/2018

Closer Look Into Test Doubles Replace Object with Double If Real Object is Too Slow It’s Not Available It Depends on Something That’s Not Available Its Too Difficult To Instantiate Or Configure For a Test Examples How to test exceptions, such as “Dead”code? An unplugged network cable? How to interact with something that’s nondeterministic? Doubles Are Key To Unit Testing 9/20/2018

Closer Look Into Test Doubles(2) Example of a Test Double Next Slide Stubs, Fakes, and Mocks Stub: Simplest Possible Implementation Fake: Still Hand Coded, But A Degree More Sophisticated Mock: Usually Generated By Tools Mock Objects in Action Next slide Checking Correct Behavior is Complicated! 9/20/2018

Test Double Example: State Testing 9/20/2018

Test Double Example: Interaction Testing 9/20/2018

Guidelines for Testable Designs Choose Composition Over Inheritance General Advice For Normal Coding And Testing More Verbose, But Worth It Avoid Static and Singleton These Are Hard To Double Static class names are hardcoded. How to replace at test time? This Can Conflict With Normal Coding Advice Consider Factories! Test Requirements Impact Code! 9/20/2018

Dependency Example: Static Method 4.4. Code smell: methods obtaining dependencies through static method calls Dependency Example: Static Method public class OrderProcessor { public void process(Order order) { PricingService service = PricingService.getInstance(); // use the PricingService object for processing the order } 9/20/2018

Exploiting a Seam 9/20/2018

Injecting Dependencies: Easy Test! public class OrderProcessorTest { @Test public void testOrderProcessorWithDependencyInjection() throws Exception { OrderProcessor p = new OrderProcessor(); p.setPricingService(new FakePricingService()); ... }} 9/20/2018

Unit Testing Patterns Assertion Patterns Resulting State Assertion Most Common Usage Guard Assertion Test Both Before and After The Action (precondition testing) Delta Assertion Verify Part of the State – Eg, List is One Bigger Than Before Custom Assertion Encodes Complex Verification Rules Interaction Assertion Verification For Interaction Tests Choose and Use Standard Patterns 9/20/2018

Example Interaction Assertion 9/20/2018

Fowler: Conventional JUnit Example 4.4. Code smell: methods obtaining dependencies through static method calls Fowler: Conventional JUnit Example public class OrderStateTester extends TestCase { private static String TALISKER = "Talisker"; private static String HIGHLAND_PARK = "Highland Park"; private Warehouse warehouse = new WarehouseImpl(); protected void setUp() throws Exception { warehouse.add(TALISKER, 50); warehouse.add(HIGHLAND_PARK, 25); } public void testOrderIsFilledIfEnoughInWarehouse() { Order order = new Order(TALISKER, 50); order.fill(warehouse); assertTrue(order.isFilled()); assertEquals(0, warehouse.getInventory(TALISKER)); public void testOrderDoesNotRemoveIfNotEnough() { Order order = new Order(TALISKER, 51); assertFalse(order.isFilled()); assertEquals(50, warehouse.getInventory(TALISKER)); 9/20/2018

4.4. Code smell: methods obtaining dependencies through static method calls Fowler: jMock Version public class OrderInteractionTester extends MockObjectTestCase { private static String TALISKER = “Talisker”; public void testFillingRemovesInventoryIfInStock() { //setup - data Order order = new Order(TALISKER, 50); Mock warehouseMock = new Mock(Warehouse.class); // constructor //setup - expectations warehouseMock.expects(once()).method("hasInventory") .with(eq(TALISKER),eq(50)) .will(returnValue(true)); warehouseMock.expects(once()).method("remove") .with(eq(TALISKER), eq(50)) .after("hasInventory"); //exercise order.fill((Warehouse) warehouseMock.proxy()); //verify warehouseMock.verify(); assertTrue(order.isFilled()); } public void testFillingDoesNotRemoveIfNotEnoughInStock() { Order order = new Order(TALISKER, 51); Mock warehouse = mock(Warehouse.class); // vs. mock call warehouse.expects(once()).method("hasInventory") .withAnyArguments() .will(returnValue(false)); order.fill((Warehouse) warehouse.proxy()); assertFalse(order.isFilled()); }} 9/20/2018

Fowler: EasyMock Example 4.4. Code smell: methods obtaining dependencies through static method calls Fowler: EasyMock Example public class OrderEasyTester extends TestCase { private static String TALISKER = "Talisker"; private MockControl warehouseControl; private Warehouse warehouseMock; public void setUp() { warehouseControl = MockControl.createControl(Warehouse.class); warehouseMock = (Warehouse) warehouseControl.getMock(); } public void testFillingRemovesInventoryIfInStock() { //setup - data Order order = new Order(TALISKER, 50); //setup - expectations warehouseMock.hasInventory(TALISKER, 50); warehouseControl.setReturnValue(true); warehouseMock.remove(TALISKER, 50); warehouseControl.replay(); //exercise order.fill(warehouseMock); //verify warehouseControl.verify(); assertTrue(order.isFilled()); 9/20/2018

Fowler/Meszaros “Double” Definitions A Test Double is anything that stands in for a real object Dummy Used to fill parameter lists Fake Actual working implementations, but take shortcuts Example: In Memory Database Stub Canned answers to calls made during tests, but useless elsewhere Mock Objects preprogrammed with expectations that form a specification of the calls they expect to receive Various Levels of Complexity 9/20/2018

Fowler: Stub Example public interface MailService { 4.4. Code smell: methods obtaining dependencies through static method calls Fowler: Stub Example public interface MailService { public void send (Message msg); } public class MailServiceStub implements MailService { private List<Message> messages = new ArrayList<Message>(); public void send (Message msg) { messages.add(msg); public int numberSent() { return messages.size(); } } // Usage class OrderStateTester... public void testOrderSendsMailIfUnfilled() { Order order = new Order(TALISKER, 51); MailServiceStub mailer = new MailServiceStub(); order.setMailer(mailer); order.fill(warehouse); assertEquals(1, mailer.numberSent()); 9/20/2018

Fowler: Mock Version class OrderInteractionTester... 4.4. Code smell: methods obtaining dependencies through static method calls Fowler: Mock Version class OrderInteractionTester... public void testOrderSendsMailIfUnfilled() { Order order = new Order(TALISKER, 51); Mock warehouse = mock(Warehouse.class); Mock mailer = mock(MailService.class); order.setMailer((MailService) mailer.proxy()); mailer.expects(once()).method("send"); warehouse.expects(once()).method("hasInventory") .withAnyArguments() .will(returnValue(false)); order.fill((Warehouse) warehouse.proxy()); } 9/20/2018

Unit Testing Patterns (2) Fixture Patterns Parameterized Creation Method Populating Complex Set Of Objects Object Mother Aggregate of Creation Methods Automated TearDown More Important For Integration Testing Than Unit Testing Fixtures Need Attention Too 9/20/2018

Unit Testing Patterns (3) Test Patterns Parameterized Test (see next slide) Self Shunt The Double Is The Test Class Intimate Inner Class Sharing Between Test Class and Test Double Classes Privileged Access Reflection-Based Injection Approaches For Legacy Code (Careful) Extra Constructor Compensates For Classes Not Designed For Testing Tests Need To Accommodate A Variety of Real Code 9/20/2018

Parameterized JUnit Example 9/20/2018

Working With Legacy Code Test-Driven Legacy Development Analyzing the Change Change Points and Inflection Points Change Code at Change Points See Effects At Inflection Points Hopefully, The Points Are Close Together… Preparing for the Change Install Tests To Capture Current Behavior of Inflection Point Test-Driving the Change Add Tests To Capture New Behavior, Also At Inflection Point Turning Legacy Code Into TDD Code 9/20/2018