51
Test Units Containing Static Dependencies 2010-09-04 Wednesday, September 8, 2010

Test Units Containing Static Dependencies · Static Dependencies 2010-09-04 Wednesday, September 8, 2010. William Rowden Co-founded Agile Software company (Gray Hill Solutions, Inc.)

  • Upload
    others

  • View
    2

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Test Units Containing Static Dependencies · Static Dependencies 2010-09-04 Wednesday, September 8, 2010. William Rowden Co-founded Agile Software company (Gray Hill Solutions, Inc.)

Test Units Containing Static Dependencies

2010-09-04

Wednesday, September 8, 2010

Page 2: Test Units Containing Static Dependencies · Static Dependencies 2010-09-04 Wednesday, September 8, 2010. William Rowden Co-founded Agile Software company (Gray Hill Solutions, Inc.)

William Rowden

Co-founded Agile Software company (Gray Hill Solutions, Inc.) in 2001

Wednesday, September 8, 2010

Page 3: Test Units Containing Static Dependencies · Static Dependencies 2010-09-04 Wednesday, September 8, 2010. William Rowden Co-founded Agile Software company (Gray Hill Solutions, Inc.)

SolutionsIQWednesday, September 8, 2010

Page 4: Test Units Containing Static Dependencies · Static Dependencies 2010-09-04 Wednesday, September 8, 2010. William Rowden Co-founded Agile Software company (Gray Hill Solutions, Inc.)

SolutionsIQAgile Software Development

Agile Training

Agile Consulting

• Agile Coaching

• Agile Team Services

• Agile Enterprise Rollouts

Wednesday, September 8, 2010

Page 5: Test Units Containing Static Dependencies · Static Dependencies 2010-09-04 Wednesday, September 8, 2010. William Rowden Co-founded Agile Software company (Gray Hill Solutions, Inc.)

Hobbies

Love to travel

Hablo español(I speak Spanish,我会说西班牙语)

我会说一点儿普通话

Wednesday, September 8, 2010

Page 6: Test Units Containing Static Dependencies · Static Dependencies 2010-09-04 Wednesday, September 8, 2010. William Rowden Co-founded Agile Software company (Gray Hill Solutions, Inc.)

HistoryBASIC, QBasic, Visual Basic, VBA, Visual Basic.NET, VBScript

Pascal

S+, R

FORTRAN

make, bash

Wednesday, September 8, 2010

Page 7: Test Units Containing Static Dependencies · Static Dependencies 2010-09-04 Wednesday, September 8, 2010. William Rowden Co-founded Agile Software company (Gray Hill Solutions, Inc.)

LanguagesC++, C# 3.5 (with XAML)

Python

Perl (with HTML)

SQL

Java

Wednesday, September 8, 2010

Page 8: Test Units Containing Static Dependencies · Static Dependencies 2010-09-04 Wednesday, September 8, 2010. William Rowden Co-founded Agile Software company (Gray Hill Solutions, Inc.)

AgendaWednesday, September 8, 2010

Page 9: Test Units Containing Static Dependencies · Static Dependencies 2010-09-04 Wednesday, September 8, 2010. William Rowden Co-founded Agile Software company (Gray Hill Solutions, Inc.)

ProblemWednesday, September 8, 2010

Page 10: Test Units Containing Static Dependencies · Static Dependencies 2010-09-04 Wednesday, September 8, 2010. William Rowden Co-founded Agile Software company (Gray Hill Solutions, Inc.)

ProblemTest a system containing a

hidden dependency on a static method call

Wednesday, September 8, 2010

Page 11: Test Units Containing Static Dependencies · Static Dependencies 2010-09-04 Wednesday, September 8, 2010. William Rowden Co-founded Agile Software company (Gray Hill Solutions, Inc.)

Code Sample

package com.solutionsiq.wrowden;

public class SystemUnderTest { public ReturnValue methodWithDependecies() { ReturnValue returnValue = Library.staticMethod(); returnValue.doSomething(); return returnValue; }}

Library.staticMethod()

Wednesday, September 8, 2010

Page 12: Test Units Containing Static Dependencies · Static Dependencies 2010-09-04 Wednesday, September 8, 2010. William Rowden Co-founded Agile Software company (Gray Hill Solutions, Inc.)

Problem

package com.solutionsiq.wrowden;

import static org.junit.Assert.assertEquals;import org.junit.Test;

public class WhenSystemUnderTestHasStaticDependencies {

@Test public void shouldBreakDependency() { final ReturnValue testValue = new ReturnValue(); final SystemUnderTest systemUnderTest = new SystemUnderTest(); assertEquals ("Method gets value from environment.", testValue, systemUnderTest.methodWithDependencies()); }}

Wednesday, September 8, 2010

Page 13: Test Units Containing Static Dependencies · Static Dependencies 2010-09-04 Wednesday, September 8, 2010. William Rowden Co-founded Agile Software company (Gray Hill Solutions, Inc.)

Problem一个问题...

Wednesday, September 8, 2010

Page 14: Test Units Containing Static Dependencies · Static Dependencies 2010-09-04 Wednesday, September 8, 2010. William Rowden Co-founded Agile Software company (Gray Hill Solutions, Inc.)

Hidden Dependencies

Internally created objects

Static methods of other classes

Extension methods

Singletons

Static methods of other classes

Wednesday, September 8, 2010

Page 15: Test Units Containing Static Dependencies · Static Dependencies 2010-09-04 Wednesday, September 8, 2010. William Rowden Co-founded Agile Software company (Gray Hill Solutions, Inc.)

Hidden Dependencies - Potential Problems

early infrastructure choice

set up time

tight coupling

slow tests

Wednesday, September 8, 2010

Page 16: Test Units Containing Static Dependencies · Static Dependencies 2010-09-04 Wednesday, September 8, 2010. William Rowden Co-founded Agile Software company (Gray Hill Solutions, Inc.)

SolutionsWednesday, September 8, 2010

Page 17: Test Units Containing Static Dependencies · Static Dependencies 2010-09-04 Wednesday, September 8, 2010. William Rowden Co-founded Agile Software company (Gray Hill Solutions, Inc.)

Design SolutionsWednesday, September 8, 2010

Page 18: Test Units Containing Static Dependencies · Static Dependencies 2010-09-04 Wednesday, September 8, 2010. William Rowden Co-founded Agile Software company (Gray Hill Solutions, Inc.)

Extract & OverrideWednesday, September 8, 2010

Page 19: Test Units Containing Static Dependencies · Static Dependencies 2010-09-04 Wednesday, September 8, 2010. William Rowden Co-founded Agile Software company (Gray Hill Solutions, Inc.)

Working Effectively with Legacy

Code

Wednesday, September 8, 2010

Page 20: Test Units Containing Static Dependencies · Static Dependencies 2010-09-04 Wednesday, September 8, 2010. William Rowden Co-founded Agile Software company (Gray Hill Solutions, Inc.)

EclipseRefactor

Wednesday, September 8, 2010

Page 21: Test Units Containing Static Dependencies · Static Dependencies 2010-09-04 Wednesday, September 8, 2010. William Rowden Co-founded Agile Software company (Gray Hill Solutions, Inc.)

Extract & Override Call

package com.solutionsiq.wrowden;

public class SystemUnderTest { public ReturnValue methodWithDependencies() { final ReturnValue returnValue = extractedStaticMethod(); returnValue.doSomething(); return returnValue; } protected ReturnValue extractedStaticMethod() { return Library.staticMethod(); }}

Wednesday, September 8, 2010

Page 22: Test Units Containing Static Dependencies · Static Dependencies 2010-09-04 Wednesday, September 8, 2010. William Rowden Co-founded Agile Software company (Gray Hill Solutions, Inc.)

Eclipse SourceWednesday, September 8, 2010

Page 23: Test Units Containing Static Dependencies · Static Dependencies 2010-09-04 Wednesday, September 8, 2010. William Rowden Co-founded Agile Software company (Gray Hill Solutions, Inc.)

Extract & Override Callpackage com.solutionsiq.wrowden;

import static org.junit.Assert.assertEquals;import org.junit.Test;

public class WhenSystemUnderTestHasStaticDependencies {

@Test public void shouldBreakDependency() { final ReturnValue testValue = new ReturnValue(); final SystemUnderTest systemUnderTest = new SystemUnderTest() {

@Override protected ReturnValue extractedStaticMethod() { return testValue; } }; final ReturnValue actualValue = systemUnderTest.methodWithDependencies(); assertEquals("Method gets value from environment.", testValue, actualValue); }}

Wednesday, September 8, 2010

Page 24: Test Units Containing Static Dependencies · Static Dependencies 2010-09-04 Wednesday, September 8, 2010. William Rowden Co-founded Agile Software company (Gray Hill Solutions, Inc.)

Result 结果

Wednesday, September 8, 2010

Page 25: Test Units Containing Static Dependencies · Static Dependencies 2010-09-04 Wednesday, September 8, 2010. William Rowden Co-founded Agile Software company (Gray Hill Solutions, Inc.)

Extract & Override CallAdvantages:

+ clear

+ fast

+ wide application

Disadvantages:

- hidden bugs

- indirection performance

- multiple methods

- production code policy

好处 坏处

Wednesday, September 8, 2010

Page 26: Test Units Containing Static Dependencies · Static Dependencies 2010-09-04 Wednesday, September 8, 2010. William Rowden Co-founded Agile Software company (Gray Hill Solutions, Inc.)

VerificationState:

ReturnValue

Behavior:

Library.staticMethod

Wednesday, September 8, 2010

Page 27: Test Units Containing Static Dependencies · Static Dependencies 2010-09-04 Wednesday, September 8, 2010. William Rowden Co-founded Agile Software company (Gray Hill Solutions, Inc.)

Mock ObjectWednesday, September 8, 2010

Page 28: Test Units Containing Static Dependencies · Static Dependencies 2010-09-04 Wednesday, September 8, 2010. William Rowden Co-founded Agile Software company (Gray Hill Solutions, Inc.)

ChihuahuaIn Mexico I discussed how to turn a class into an object.

Wednesday, September 8, 2010

Page 29: Test Units Containing Static Dependencies · Static Dependencies 2010-09-04 Wednesday, September 8, 2010. William Rowden Co-founded Agile Software company (Gray Hill Solutions, Inc.)

Design Patterns:

Elements of Reusable Object-

Oriented Software

Wednesday, September 8, 2010

Page 30: Test Units Containing Static Dependencies · Static Dependencies 2010-09-04 Wednesday, September 8, 2010. William Rowden Co-founded Agile Software company (Gray Hill Solutions, Inc.)

Interface

“Program to an interface, not an implementation.”

--Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides; Design Patterns: Elements of Reusable Object-Oriented Software

Wednesday, September 8, 2010

Page 31: Test Units Containing Static Dependencies · Static Dependencies 2010-09-04 Wednesday, September 8, 2010. William Rowden Co-founded Agile Software company (Gray Hill Solutions, Inc.)

Adapter Pattern

“Clients call operations on an Adapter instance. In turn, the adapter calls Adaptee operations that carry out the request.”

Wednesday, September 8, 2010

Page 32: Test Units Containing Static Dependencies · Static Dependencies 2010-09-04 Wednesday, September 8, 2010. William Rowden Co-founded Agile Software company (Gray Hill Solutions, Inc.)

The Art of Unit Testing

Wednesday, September 8, 2010

Page 33: Test Units Containing Static Dependencies · Static Dependencies 2010-09-04 Wednesday, September 8, 2010. William Rowden Co-founded Agile Software company (Gray Hill Solutions, Inc.)

Mock Library

Wednesday, September 8, 2010

Page 34: Test Units Containing Static Dependencies · Static Dependencies 2010-09-04 Wednesday, September 8, 2010. William Rowden Co-founded Agile Software company (Gray Hill Solutions, Inc.)

Interface

package com.solutionsiq.wrowden;

public interface AdaptableLibrary {

ReturnValue staticMethod();

}

Wednesday, September 8, 2010

Page 35: Test Units Containing Static Dependencies · Static Dependencies 2010-09-04 Wednesday, September 8, 2010. William Rowden Co-founded Agile Software company (Gray Hill Solutions, Inc.)

EasyMock

import static org.easymock.EasyMock.createMock;import static org.easymock.EasyMock.expect;import static org.easymock.EasyMock.replay;import static org.easymock.EasyMock.verify;

Wednesday, September 8, 2010

Page 36: Test Units Containing Static Dependencies · Static Dependencies 2010-09-04 Wednesday, September 8, 2010. William Rowden Co-founded Agile Software company (Gray Hill Solutions, Inc.)

Test-Driven Development

Fix failing test by calling mock Library

Real system calls Library adapter

Wednesday, September 8, 2010

Page 37: Test Units Containing Static Dependencies · Static Dependencies 2010-09-04 Wednesday, September 8, 2010. William Rowden Co-founded Agile Software company (Gray Hill Solutions, Inc.)

Dependency Injection

package com.solutionsiq.wrowden;

public class SystemUnderTest { public ReturnValue methodWithDependencies(AdaptableLibrary library) { final ReturnValue returnValue = library.staticMethod(); returnValue.doSomething(); return returnValue; }}

Wednesday, September 8, 2010

Page 38: Test Units Containing Static Dependencies · Static Dependencies 2010-09-04 Wednesday, September 8, 2010. William Rowden Co-founded Agile Software company (Gray Hill Solutions, Inc.)

Adapter Pattern

package com.solutionsiq.wrowden;

public class LibraryAdapter implements AdaptableLibrary {

@Override public ReturnValue staticMethod() { return Library.staticMethod(); }}

Wednesday, September 8, 2010

Page 39: Test Units Containing Static Dependencies · Static Dependencies 2010-09-04 Wednesday, September 8, 2010. William Rowden Co-founded Agile Software company (Gray Hill Solutions, Inc.)

Result 结果

Wednesday, September 8, 2010

Page 40: Test Units Containing Static Dependencies · Static Dependencies 2010-09-04 Wednesday, September 8, 2010. William Rowden Co-founded Agile Software company (Gray Hill Solutions, Inc.)

MockingAdvantages:

+ easy

+ readable

Disadvantages:

- less readable setup

- could require many mocks

- changed static method

好处 坏处

Wednesday, September 8, 2010

Page 41: Test Units Containing Static Dependencies · Static Dependencies 2010-09-04 Wednesday, September 8, 2010. William Rowden Co-founded Agile Software company (Gray Hill Solutions, Inc.)

Test SolutionsWednesday, September 8, 2010

Page 42: Test Units Containing Static Dependencies · Static Dependencies 2010-09-04 Wednesday, September 8, 2010. William Rowden Co-founded Agile Software company (Gray Hill Solutions, Inc.)

西安钟楼In China I discussed test

strategies.

Wednesday, September 8, 2010

Page 43: Test Units Containing Static Dependencies · Static Dependencies 2010-09-04 Wednesday, September 8, 2010. William Rowden Co-founded Agile Software company (Gray Hill Solutions, Inc.)

Test Techniques

if (testableCode = goodCode) {

// try dependency injection

// try mocking

}

testableCode = goodCode

Wednesday, September 8, 2010

Page 44: Test Units Containing Static Dependencies · Static Dependencies 2010-09-04 Wednesday, September 8, 2010. William Rowden Co-founded Agile Software company (Gray Hill Solutions, Inc.)

Test Techniques

if (goodCode != testableCode) {

// try class loader

// try Aspect-Oriented Programming

}

goodCode = testableCode!

Wednesday, September 8, 2010

Page 45: Test Units Containing Static Dependencies · Static Dependencies 2010-09-04 Wednesday, September 8, 2010. William Rowden Co-founded Agile Software company (Gray Hill Solutions, Inc.)

Class LoaderWednesday, September 8, 2010

Page 46: Test Units Containing Static Dependencies · Static Dependencies 2010-09-04 Wednesday, September 8, 2010. William Rowden Co-founded Agile Software company (Gray Hill Solutions, Inc.)

package com.solutionsiq.wrowden;

import static org.junit.Assert.assertEquals;

@RunWith(PowerMockRunner.class)@PrepareForTest(Library.class)public class WhenSystemUnderTestHasStaticDependencies {

@Test public void shouldBreakDependency() { final ReturnValue testValue = new ReturnValue(); final SystemUnderTest systemUnderTest = new SystemUnderTest(); PowerMock.mockStatic(Library.class); EasyMock.expect(Library.staticMethod()).andReturn(testValue); PowerMock.replay(Library.class); assertEquals("Method gets value from environment.", testValue, systemUnderTest.methodWithDependencies()); PowerMock.verify(Library.class); }}

PowerMock

Wednesday, September 8, 2010

Page 47: Test Units Containing Static Dependencies · Static Dependencies 2010-09-04 Wednesday, September 8, 2010. William Rowden Co-founded Agile Software company (Gray Hill Solutions, Inc.)

Result 结果

Wednesday, September 8, 2010

Page 48: Test Units Containing Static Dependencies · Static Dependencies 2010-09-04 Wednesday, September 8, 2010. William Rowden Co-founded Agile Software company (Gray Hill Solutions, Inc.)

Class LoadersAdvantages:

+ removes external dependency

+ tests code using a third-party API

Disadvantages:

- doesn’t improve code design

- inhibits useful feedback

好处 坏处

Wednesday, September 8, 2010

Page 49: Test Units Containing Static Dependencies · Static Dependencies 2010-09-04 Wednesday, September 8, 2010. William Rowden Co-founded Agile Software company (Gray Hill Solutions, Inc.)

Aspect-Oriented Programming

Wednesday, September 8, 2010

Page 50: Test Units Containing Static Dependencies · Static Dependencies 2010-09-04 Wednesday, September 8, 2010. William Rowden Co-founded Agile Software company (Gray Hill Solutions, Inc.)

Deciding WhichAre there bad smells in the code?

Can you improve the design of the existing code?

How many hidden dependencies are there?

Is performance a problem?

Is the call too simple to break? Or would overriding hide bugs?

Wednesday, September 8, 2010

Page 51: Test Units Containing Static Dependencies · Static Dependencies 2010-09-04 Wednesday, September 8, 2010. William Rowden Co-founded Agile Software company (Gray Hill Solutions, Inc.)

Questions?

Wednesday, September 8, 2010