Presentation, Region Skåne 2002-06-10 - Callista...

40
Bitter TDD Jan Västernäs [email protected]

Transcript of Presentation, Region Skåne 2002-06-10 - Callista...

Page 1: Presentation, Region Skåne 2002-06-10 - Callista Enterprisecallistaenterprise.se/assets/presentationer/cadec-2008-bitter-tdd.pdf · boundries. –Easier –Faster ... – Extract

Bitter TDD

Jan Västernä[email protected]

Page 2: Presentation, Region Skåne 2002-06-10 - Callista Enterprisecallistaenterprise.se/assets/presentationer/cadec-2008-bitter-tdd.pdf · boundries. –Easier –Faster ... – Extract

Bitter TDD, Slide 2Copyright 2008, Callista Enterprise AB

Agenda

• TDD Concepts

• Project Setup

• Experiences

• Summary

Page 3: Presentation, Region Skåne 2002-06-10 - Callista Enterprisecallistaenterprise.se/assets/presentationer/cadec-2008-bitter-tdd.pdf · boundries. –Easier –Faster ... – Extract

Bitter TDD, Slide 3Copyright 2008, Callista Enterprise AB

Agenda

• TDD Concepts

• Project Setup

• Experiences

• Summary

Page 4: Presentation, Region Skåne 2002-06-10 - Callista Enterprisecallistaenterprise.se/assets/presentationer/cadec-2008-bitter-tdd.pdf · boundries. –Easier –Faster ... – Extract

Bitter TDD, Slide 4Copyright 2008, Callista Enterprise AB

Different kind of tests

• Unit test

– Mock dependencies

• Test external interface or

• Test internal state

• Integration Test

– Configuration(spring/java ee), Database, JMS, JCA etc

– Inside/outside application server (out-of-container)

• Larger Unit Integration Test

– More than one class

Page 5: Presentation, Region Skåne 2002-06-10 - Callista Enterprisecallistaenterprise.se/assets/presentationer/cadec-2008-bitter-tdd.pdf · boundries. –Easier –Faster ... – Extract

Bitter TDD, Slide 5Copyright 2008, Callista Enterprise AB

Unit test

Test Case

Unit under test

A mock Another mock And one more

Page 6: Presentation, Region Skåne 2002-06-10 - Callista Enterprisecallistaenterprise.se/assets/presentationer/cadec-2008-bitter-tdd.pdf · boundries. –Easier –Faster ... – Extract

Bitter TDD, Slide 6Copyright 2008, Callista Enterprise AB

Integration test

Test Case

Unit under test

Database

configuration

Page 7: Presentation, Region Skåne 2002-06-10 - Callista Enterprisecallistaenterprise.se/assets/presentationer/cadec-2008-bitter-tdd.pdf · boundries. –Easier –Faster ... – Extract

Bitter TDD, Slide 7Copyright 2008, Callista Enterprise AB

Integration Test – larger unit

Test Case

Unit under test

Another class

configuration

One more A third class

Database

Page 8: Presentation, Region Skåne 2002-06-10 - Callista Enterprisecallistaenterprise.se/assets/presentationer/cadec-2008-bitter-tdd.pdf · boundries. –Easier –Faster ... – Extract

Bitter TDD, Slide 8Copyright 2008, Callista Enterprise AB

Sample mock unit test using easymock

CustomerDao daoMock = createMock(CustomerDao.class);

List<Customer> list = new ArrayList<Customer>()

List.add(new Customer(”Callista”, CustomerType.GOOD, ... );

expect(daoMock.getAll()).andReturn(list);

replay(daoMock);

CustomerEntityImpl customerEntity = new CustomerEntity();

customerEntity.setCustomerDao(daoMock);

List<Customer> list = customerEntity.getAllCustomers();

assertEquals(1, list.size());

verify(daoMock);

Page 9: Presentation, Region Skåne 2002-06-10 - Callista Enterprisecallistaenterprise.se/assets/presentationer/cadec-2008-bitter-tdd.pdf · boundries. –Easier –Faster ... – Extract

Bitter TDD, Slide 9Copyright 2008, Callista Enterprise AB

Sample unit test set/get internal state

WorkingCalendarAssembly cal = new WorkingCalendarAssembly();

cal.workingCycleList = new ArrayList<WorkingCycle>();

cal.workingCycleList.add(new WorkingCycle(1,2,1,800,1600));

cal.workingCycleList.add(new WorkingCycle(1,2,2,1600,2400));

……

cal.expand();

List<OpenInterval> intervals = cal.intervals;

assertEquals(36,intervals.size());

……….

Page 10: Presentation, Region Skåne 2002-06-10 - Callista Enterprisecallistaenterprise.se/assets/presentationer/cadec-2008-bitter-tdd.pdf · boundries. –Easier –Faster ... – Extract

Bitter TDD, Slide 10Copyright 2008, Callista Enterprise AB

Sample integration test using DBUNIT

String INTITAL_DATA = "<?xml version='1.0'?>“ +

“<CUSTOMER SID='1‘ NAME=‘Callista´ TYPE=‘GOOD’ ….”

“<CUSTOMER SID=‘2‘ NAME=‘Universal Software´ TYPE=‘UGLY’ …”

setup()

DatabaseOperation.CLEAN_INSERT …….. INITIAL_DATA

customerEntity = (CustomerEntityImpl) applicationContext.getBean(“customerEntity");

testMetod()

List<Customer> list = customerEntity.getAllCustomers();

assertEquals(2, list.size());

Page 11: Presentation, Region Skåne 2002-06-10 - Callista Enterprisecallistaenterprise.se/assets/presentationer/cadec-2008-bitter-tdd.pdf · boundries. –Easier –Faster ... – Extract

Bitter TDD, Slide 11Copyright 2008, Callista Enterprise AB

Agenda

• TDD Concepts

• Project Setup

• Experiences

• Summary

Page 12: Presentation, Region Skåne 2002-06-10 - Callista Enterprisecallistaenterprise.se/assets/presentationer/cadec-2008-bitter-tdd.pdf · boundries. –Easier –Faster ... – Extract

Bitter TDD, Slide 12Copyright 2008, Callista Enterprise AB

Project setup

• 2 Projects, 3 years

• Java SE 5, J2EE 1.4

• Spring-beans, web or mdb

• Layered, component-based architecture

• Struts/JSP

• Eclipse Rich Client Platform + spring remoting

• Test : JUnit, DbUnit, EasyMock

• Maven

• JDBC - Oracle

• Websphere Application Server (target platform), MQ

• Ambitious TDD combined with CI

• Custom libraries, documented best practice for test

Page 13: Presentation, Region Skåne 2002-06-10 - Callista Enterprisecallistaenterprise.se/assets/presentationer/cadec-2008-bitter-tdd.pdf · boundries. –Easier –Faster ... – Extract

Bitter TDD, Slide 13Copyright 2008, Callista Enterprise AB

Agenda

• TDD Concepts

• Project Setup

• Experiences

• Summary

Page 14: Presentation, Region Skåne 2002-06-10 - Callista Enterprisecallistaenterprise.se/assets/presentationer/cadec-2008-bitter-tdd.pdf · boundries. –Easier –Faster ... – Extract

Bitter TDD, Slide 14Copyright 2008, Callista Enterprise AB

Test experience in a nutshell

+ Good

- Expensive

Page 15: Presentation, Region Skåne 2002-06-10 - Callista Enterprisecallistaenterprise.se/assets/presentationer/cadec-2008-bitter-tdd.pdf · boundries. –Easier –Faster ... – Extract

Bitter TDD, Slide 15Copyright 2008, Callista Enterprise AB

Why is it good ?

• Drives interfaces, documents intended functionality

• Enables bit by bit unit testing rather than testing from system boundries.

– Easier

– Faster

• Refactoring

– Shows other needs for change

– Shows that the rest is OK

• Fast feedback after check in of changed code

• All phases

Page 16: Presentation, Region Skåne 2002-06-10 - Callista Enterprisecallistaenterprise.se/assets/presentationer/cadec-2008-bitter-tdd.pdf · boundries. –Easier –Faster ... – Extract

Bitter TDD, Slide 16Copyright 2008, Callista Enterprise AB

Why is it expensive ?

• Time to write

• Time to maintain

• Time to run

• Yet another set of frameworks

• Needs training, mentoring, reviews

• One-time investments, running cost

• On the other hand

– Saves development time

– Saves error/debugging time

Page 17: Presentation, Region Skåne 2002-06-10 - Callista Enterprisecallistaenterprise.se/assets/presentationer/cadec-2008-bitter-tdd.pdf · boundries. –Easier –Faster ... – Extract

Bitter TDD, Slide 17Copyright 2008, Callista Enterprise AB

Vital to maximize RoI

• Keep reasonable cost level

• Right-size number of tests

• Maximize value of each test

• How ? Our experience

Page 18: Presentation, Region Skåne 2002-06-10 - Callista Enterprisecallistaenterprise.se/assets/presentationer/cadec-2008-bitter-tdd.pdf · boundries. –Easier –Faster ... – Extract

Bitter TDD, Slide 18Copyright 2008, Callista Enterprise AB

Detailed Experience

• Test Driven

• Test Coverage

• Test all classes/methods

• Pure unit tests

• Integration test

• Test Data

• Database schemas

• Change implementation

• Out of container testing

• Bug fixes

Page 19: Presentation, Region Skåne 2002-06-10 - Callista Enterprisecallistaenterprise.se/assets/presentationer/cadec-2008-bitter-tdd.pdf · boundries. –Easier –Faster ... – Extract

Bitter TDD, Slide 19Copyright 2008, Callista Enterprise AB

Test Driven Development

A) Write all tests first, then write implementation

B) Write implementation first, then write test

C) Test a little/write a little

D) All of the above

OK, depends on

E) Write implementation

– Often not OK, A) and C) minimizes risk of E)

Page 20: Presentation, Region Skåne 2002-06-10 - Callista Enterprisecallistaenterprise.se/assets/presentationer/cadec-2008-bitter-tdd.pdf · boundries. –Easier –Faster ... – Extract

Bitter TDD, Slide 20Copyright 2008, Callista Enterprise AB

Why Test Coverage is a blunt instrument

• Team leader: “We need 93 % coverage”

• Unnecessary or expensive tests

• To easy to get

• May result in a test

– new myClass().callVeryComplicatedMethod(null,0,” ”);

• Or a little better

– assertNotNull(uut.method());

• Or in worst case

– if ( parameter == null ) {return null;}

• Fine-grained goals

• Quality vs quantity

Page 21: Presentation, Region Skåne 2002-06-10 - Callista Enterprisecallistaenterprise.se/assets/presentationer/cadec-2008-bitter-tdd.pdf · boundries. –Easier –Faster ... – Extract

Bitter TDD, Slide 21Copyright 2008, Callista Enterprise AB

Fine-grained coverage approach

Component A Component B

Basic Data

Component B

Integration

Component B

Calculation

Presentation/MDB

0 0 80 0

Façade 20 20 - -

Service 20 60 100 100

Entity 20 40 100 80

Dao 0 40 60 80

Page 22: Presentation, Region Skåne 2002-06-10 - Callista Enterprisecallistaenterprise.se/assets/presentationer/cadec-2008-bitter-tdd.pdf · boundries. –Easier –Faster ... – Extract

Bitter TDD, Slide 22Copyright 2008, Callista Enterprise AB

Tests for all classes ?

• Default answer: Yes

• Combine with minimum coverage

• Good for inexperienced TDD-ers

• Different in a test-mature organization

• ”Too simple to test”

• Complex algorithms etc

Page 23: Presentation, Region Skåne 2002-06-10 - Callista Enterprisecallistaenterprise.se/assets/presentationer/cadec-2008-bitter-tdd.pdf · boundries. –Easier –Faster ... – Extract

Bitter TDD, Slide 23Copyright 2008, Callista Enterprise AB

Avoid overlapping tests

• Simple delegation

Page 24: Presentation, Region Skåne 2002-06-10 - Callista Enterprisecallistaenterprise.se/assets/presentationer/cadec-2008-bitter-tdd.pdf · boundries. –Easier –Faster ... – Extract

Bitter TDD, Slide 24Copyright 2008, Callista Enterprise AB

Unit test risk: copy of implementation

• Many calls to other classes

• Set up transfer-object

• Implementation changes ?

• Hard to understand

• Often needed but declining in my mind

Page 25: Presentation, Region Skåne 2002-06-10 - Callista Enterprisecallistaenterprise.se/assets/presentationer/cadec-2008-bitter-tdd.pdf · boundries. –Easier –Faster ... – Extract

Bitter TDD, Slide 25Copyright 2008, Callista Enterprise AB

Easymock

• Simple to use

• No need to write mocks

• Support for classes

• ”Program to an interface not an implementation” revisited

• Default - equals

– Base class for all transfer objects

– Equals compares all attributes with reflection

– Timestamps ?

Page 26: Presentation, Region Skåne 2002-06-10 - Callista Enterprisecallistaenterprise.se/assets/presentationer/cadec-2008-bitter-tdd.pdf · boundries. –Easier –Faster ... – Extract

Bitter TDD, Slide 26Copyright 2008, Callista Enterprise AB

Data base integration test risk: Schema changes

• NEW_ATTRIBUTE VARCHAR(10) NOT NULL

• String jadajada = ” VERSION=’1’ CHANGED_BY=’robban” CHA...

• ”<CUSTOMER ID=’1’ NAME=Callista’ ” + jadajada + ” />

• Avoid mixing java and DbUnit

”<CUSTOMER ID=’” + getId(customerMetaData) + “’ VERSION=‘“ + i++

Page 27: Presentation, Region Skåne 2002-06-10 - Callista Enterprisecallistaenterprise.se/assets/presentationer/cadec-2008-bitter-tdd.pdf · boundries. –Easier –Faster ... – Extract

Bitter TDD, Slide 27Copyright 2008, Callista Enterprise AB

DbUnit

• Efficient

• Simple

Page 28: Presentation, Region Skåne 2002-06-10 - Callista Enterprisecallistaenterprise.se/assets/presentationer/cadec-2008-bitter-tdd.pdf · boundries. –Easier –Faster ... – Extract

Bitter TDD, Slide 28Copyright 2008, Callista Enterprise AB

Fixed test data ?

• Data model develops

• Changes cost and introduce risk

• Introduces dependencies

• Better to let all tests setup their own

• Well-documented exceptions

Page 29: Presentation, Region Skåne 2002-06-10 - Callista Enterprisecallistaenterprise.se/assets/presentationer/cadec-2008-bitter-tdd.pdf · boundries. –Easier –Faster ... – Extract

Bitter TDD, Slide 29Copyright 2008, Callista Enterprise AB

Schemas

• Original DB-provider / different light-weight ?

• We choose Oracle

– Syntax, tooling

• Build schema

• Personal schema

• Other schemas

• Different load scripts

– Minimum - 3 tables (required for tests)

– Medium - data setup by installation

– Full/Demo - business-data in all tables

• Need to control schema access at all times

Page 30: Presentation, Region Skåne 2002-06-10 - Callista Enterprisecallistaenterprise.se/assets/presentationer/cadec-2008-bitter-tdd.pdf · boundries. –Easier –Faster ... – Extract

Bitter TDD, Slide 30Copyright 2008, Callista Enterprise AB

When to run tests ?

• Project rebuild in Eclipse

– Too often

• Just build – forget about the tests

– Checkout

– Small change component A, test component B

– Command file mvnn

Page 31: Presentation, Region Skåne 2002-06-10 - Callista Enterprisecallistaenterprise.se/assets/presentationer/cadec-2008-bitter-tdd.pdf · boundries. –Easier –Faster ... – Extract

Bitter TDD, Slide 31Copyright 2008, Callista Enterprise AB

Code changes to simplify/enable testing

• YES

• Refactor private methods

– Extract logic to test

– Isolate things that are hard to mock

– Should private methods be tested ?

• Package visibility ( test in same package )

– Methods – to be able to call

– Attributes – to be able to set/get

Page 32: Presentation, Region Skåne 2002-06-10 - Callista Enterprisecallistaenterprise.se/assets/presentationer/cadec-2008-bitter-tdd.pdf · boundries. –Easier –Faster ... – Extract

Bitter TDD, Slide 32Copyright 2008, Callista Enterprise AB

Out of container testing

• Invaluable

– Datasource and transaction handling pluggable with alternate spring-config and spring-config-factory

• Even for GUI when using Java EE independent technology

Page 33: Presentation, Region Skåne 2002-06-10 - Callista Enterprisecallistaenterprise.se/assets/presentationer/cadec-2008-bitter-tdd.pdf · boundries. –Easier –Faster ... – Extract

Bitter TDD, Slide 33Copyright 2008, Callista Enterprise AB

Bug fixing strategy

• Recreate with test ( red )

• Fix implementation

• Check that test is green

Page 34: Presentation, Region Skåne 2002-06-10 - Callista Enterprisecallistaenterprise.se/assets/presentationer/cadec-2008-bitter-tdd.pdf · boundries. –Easier –Faster ... – Extract

Bitter TDD, Slide 34Copyright 2008, Callista Enterprise AB

Smells of a less valuable test

List<CompositeTO> result = uut.theVeryComplicatedMethod();

System.out.println(result);

4 kilometer console output

If ( x.equals(null) ){

throw new NullPointerException();

}

public void test() {

. . . .

}

“OK -- enhetstesterna var kanske inte riktigt heltäckande …..”

Page 35: Presentation, Region Skåne 2002-06-10 - Callista Enterprisecallistaenterprise.se/assets/presentationer/cadec-2008-bitter-tdd.pdf · boundries. –Easier –Faster ... – Extract

Bitter TDD, Slide 35Copyright 2008, Callista Enterprise AB

Signs of a valuable test ?

assertEquals(expected, actual);

expect(getAllCustomers()).andReturn(customerList);

public void testMyFirstMethod_manyCustomersPerCountry()

public void testMyFirstMethod_oneCustomersPerCountry()

public void testMyFirstMethod_noCustomersForCountry()

public void testMyFirstMethod_daoThrowsPKNFException()

public void testSmoke()

Page 36: Presentation, Region Skåne 2002-06-10 - Callista Enterprisecallistaenterprise.se/assets/presentationer/cadec-2008-bitter-tdd.pdf · boundries. –Easier –Faster ... – Extract

Bitter TDD, Slide 36Copyright 2008, Callista Enterprise AB

How to become a certified tester ?

Page 37: Presentation, Region Skåne 2002-06-10 - Callista Enterprisecallistaenterprise.se/assets/presentationer/cadec-2008-bitter-tdd.pdf · boundries. –Easier –Faster ... – Extract

Bitter TDD, Slide 37Copyright 2008, Callista Enterprise AB

Technical Certification Requirements

• Compile your application code. Note: Getting the latest version of any recent code changes from other developers is purely optional and not a requirement for certification.

• Launch the application that has just been compiled.

• Cause one code-path in the code you're checking in to be executed. Note: the preferable way to do this is with very ad-hoc manual testing of the simplest case for the feature in question. The Stovell Institute for Application Assurancesuggests that it is possible to omit this step if the code change was less than five lines, or if (in the developer's professional opinion) the code change could not possibly result in an error.

• Check the code changes into your version control system.

Page 38: Presentation, Region Skåne 2002-06-10 - Callista Enterprisecallistaenterprise.se/assets/presentationer/cadec-2008-bitter-tdd.pdf · boundries. –Easier –Faster ... – Extract

Bitter TDD, Slide 38Copyright 2008, Callista Enterprise AB

Agenda

• TDD Concepts

• Project Setup

• Experiences

• Summary

Page 39: Presentation, Region Skåne 2002-06-10 - Callista Enterprisecallistaenterprise.se/assets/presentationer/cadec-2008-bitter-tdd.pdf · boundries. –Easier –Faster ... – Extract

Bitter TDD, Slide 39Copyright 2008, Callista Enterprise AB

Conclusion

• How did we survive in the pre-TDD era ?

– Great improvement, right on spot

• Focus test effort on complicated implementations !

• Quality before quantity

• RoI ? Hard to prove, but still.

Page 40: Presentation, Region Skåne 2002-06-10 - Callista Enterprisecallistaenterprise.se/assets/presentationer/cadec-2008-bitter-tdd.pdf · boundries. –Easier –Faster ... – Extract

Bitter TDD, Slide 40Copyright 2008, Callista Enterprise AB

Questions ?