developer testing

38
Developer Testing Stephan J. Schmidt cintoo lead developer http://cintoo.org [email protected] Achieving a hundred percent test coverage for database and Swing applications

Upload: stephan-schmidt

Post on 11-May-2015

798 views

Category:

Technology


0 download

DESCRIPTION

Achieving 100% test coverage for database and Swing applications in Java with mocking, HSQL and Jenny

TRANSCRIPT

Page 1: Developer Testing

Developer Testing

Stephan J. Schmidt

cintoo lead developer

http://cintoo.org

[email protected]

Achieving a hundred percent test coverage for database and Swing applications

Page 2: Developer Testing

Stephan J. Schmidt, cintoo

Contents

• What is developer testing

• Why you should practice developer testing

• How you can do developer testing

• How to test nasty things

2

Page 3: Developer Testing

Stephan J. Schmidt, cintoo

What is Developer Testing

3

Testing done by developersSimple:

Page 4: Developer Testing

Stephan J. Schmidt, cintoo

Acceptance versus Developer Tests

4

Acceptence Testing

System against Requirements

Developer Testing

Code against DesignTests:

Page 5: Developer Testing

Stephan J. Schmidt, cintoo

Why?

• Improves the health of your system

• Gives you a good feeling

• Makes you more confident

• Developer testing makes you more effective

5

Page 6: Developer Testing

Stephan J. Schmidt, cintoo

Accountability

• Developer testing leads to accountability

• Developers should be accountable for their code

• Business people often think they are

• Offshoring/ Outsourcing might be due to lack of accountability

• Accountability needed for CMM5

6

Page 7: Developer Testing

Stephan J. Schmidt, cintoo

Save time

• Less gold plating

• Developers know when to stop

• Less thinking what to do next

• Tests result in cleaner, more atomic design which reduces time when introducing new features

• Regression testing finds new bugs fast

7

Page 8: Developer Testing

Stephan J. Schmidt, cintoo

Implementing Developer Testing

• Be pragmatic!

• It’s free

• Frameworks like TestNG or xUnit (JUnit, NUnit...)

• TestCases with methods (tests) which test your classes

• Run tests automatically and frequently

• Use automatic builds (Pulse, Cruise control, ..)

• Set goals (metric based)

8

Page 9: Developer Testing

Stephan J. Schmidt, cintoo

Example adding two numbers

9

public class Math { public static int add(int a, int b) { return a + b; }}

Page 10: Developer Testing

Stephan J. Schmidt, cintoo

Testing Math with an Unit Test

10

public class TestMath { @Test public void addTwoPositiveNumbers() { Asserts.assertEquals( "2 + 3 = 5", 5, Math.add(2,3)); }

@Test public void addZero() { Asserts.assertEquals( "1 + 0 = 1", 1, Math.add(1,0)); Asserts.assertEquals( "0 + 1 = 1", 1, Math.add(0,1)); }}

Page 11: Developer Testing

Stephan J. Schmidt, cintoo

Test tools

• Tests are run with a testing tool

• Tool displays non-working tests

11

Page 12: Developer Testing

Stephan J. Schmidt, cintoo

Build Server

• Runs tests automatically on check-in or time based

• Prevents non working tests in repository after check-ins

(though they might run locally)

12

Page 13: Developer Testing

Stephan J. Schmidt, cintoo

Example application SuperAdd

• Will replace Excel!

• Adding two numbers

• Graphical user interface for data entry

• Storing the calculations in a database

13

Page 14: Developer Testing

Stephan J. Schmidt, cintoo

Architecture

• Three tier application

• Different testing scenarios for every tier

14

GUI

Logic

Storage

Page 15: Developer Testing

Stephan J. Schmidt, cintoo

Architecture

15

SwingCalcView

CalcView

CalcEditor

Math CalcManager

CalcStorage

JDBCCalcStorage

DB

Buttons

Application BorderState

Application Border State

GUI

Logic

Storage

1

2

3

Page 16: Developer Testing

Stephan J. Schmidt, cintoo

Testing SuperAdd

• Test Logic (Math, CalcManager) easy

• Test Storage (JDBCCalcStorage) not so easy

• Test GUI (CalcView, CalcEditor) hmm. some thinking needed

16

Page 17: Developer Testing

Stephan J. Schmidt, cintoo

Testing Math is easy

• Already shown, lucky me :-)

• Test for negative numbers, overflow, ...

17

MathTest

calculate / ok

1

Page 18: Developer Testing

Stephan J. Schmidt, cintoo

Testing CalcManager

• CalcManager logs correct calculations to the storage

• Problem is the usage of a database

• Testing not in isolation

• Solution is usage of Mock objects for database storage

18

1

CalcManager

MockCalcStorage

Test

set / ok

ok

Page 19: Developer Testing

Stephan J. Schmidt, cintoo

Mock objects

• In-replacement for objects

• Mocks simulate the dependencies

• Testing in isolation

• Testing classes "from below"

19

Test

Class to Test

Dependenciesas Mocks

Page 20: Developer Testing

Stephan J. Schmidt, cintoo

GUI Testing

20

2

Page 21: Developer Testing

Stephan J. Schmidt, cintoo

Usually Java GUIs look like this

21

public class View { ... calculateButton.addActionListener( ... sumField.setText( Math.add( aField.getText(), bField.getText()); )); }} Hard to test, depends on

Swing. Logic not reusablein different GUI frameworks!

Page 22: Developer Testing

Stephan J. Schmidt, cintoo

GUI splitting

• View/Editor pattern, split GUI in view and editor

• Remove ALL logic from the view

• Editor contains the logic

22

Editor

View

GUI

Page 23: Developer Testing

Stephan J. Schmidt, cintoo

View

23

public class View { ... calculateButton.addActionListener( ... editor.calculate() )); } public void setSum(int sum) { sumField.setText(sum); }}

Page 24: Developer Testing

Stephan J. Schmidt, cintoo

Editor

24

public class Editor { public void calculate() { int a = view.getAValue(); int b = view.getBValue(); view.setSum(Math.add(a,b)); }}

Logic

Page 25: Developer Testing

Stephan J. Schmidt, cintoo

Editor Test

25

@Testpublic void calculate() { Mock mockCalcView = mock(CalcView.class); mockCalcView.expects(once()) .method("getAValue").will(returnValue(2)); ... Mock mockCalcManager = mock(CalcManager.class); mockCalcManager.expects(once()) .method("logCalc").with(eq(2), eq(3), eq(5));

CalcEditor editor = new CalcEditor( (CalcView) mockCalcView.proxy(), (CalcManager) mockCalcManager.proxy()); editor.calculate();}

Page 26: Developer Testing

Stephan J. Schmidt, cintoo

GUI Testing

• Record/ Playback: Actions are recorded and after that a tester replays the recorded actions

• Click tests: Testers click buttons in a GUI according to a test plan

• Programmatic: Developer writes GUI tests with framework

• Record is simple, but breaks easily with GUI changes

• Click tests are simple, but annoying. A lot of documentation changes are needed after GUI changes

• Programmatic approach needs developers to define tests, but is much more robust against changes

26

2

Page 27: Developer Testing

Stephan J. Schmidt, cintoo

Testing with Jemmy

• Jemmy is a windows driver

• Provides operators like JButtonOperator

• Test: Find component then drive component through operator then check for result/ state

27

Jemmy

SwingView

MockEditor

Test

click /ok

ok

Page 28: Developer Testing

Stephan J. Schmidt, cintoo

Testing the Swing view

28

Mock mockEditor = mock(CalcEditor.class);mockEditor.expects(once()).method("calculate");...JTextFieldOperator aField = new JTextFieldOperator(main, name("a"));...JButtonOperator calculateButton = new JButtonOperator(main);

aField.enterText("2");bField.enterText("3");

calculateButton.doClick();

assertEquals(sumField.getText(), 5);

Findcomponent

Drivecomponent

Checkresults

Page 29: Developer Testing

Stephan J. Schmidt, cintoo

Database layer

• Store all calculations

• Relational database management system

29

a b sum

Calculations

a b sum

2 3 5

Calculations

3

add()

Page 30: Developer Testing

Stephan J. Schmidt, cintoo

Testing the database layer

• Use in-memory database

• Free utilities exist to check results in database

30

JDBCCalcStorage

Test

set / ok

ok InMemory

Page 31: Developer Testing

Stephan J. Schmidt, cintoo

Writing and checking data

• write data to database then check data in database

• use helper methods like rowCount

31

CalcStorage storage = new JdbcCalcStorage(config);

storage.store(2, 3, 5);

assertEquals( "One row has been added", 1, rowCount("Calculations"));

assertEquals("Correct data has been written", 1, rowCount("Calculations", "a=2 AND b=3 AND sum=5"));

Page 32: Developer Testing

Stephan J. Schmidt, cintoo

In-Memory Database configuration with HSQL

• HSQL in memory database,

automatically knows “sa” user

• automatically creates database

• hsql.jar with driver, all inclusive

• Create and drop tables in setUp and tearDown

32

Config config = new Config( "sa", "", "jdbc:hsqldb:mem:testdb", "org.hsqldb.jdbcDriver");

Page 33: Developer Testing

Stephan J. Schmidt, cintoo

Also test O/R Mappers

• Even with Hibernate, ... use unit tests

• Are you sure your configuration does cascading delete correctly?

• Do the queries return the correct objects?

• Are all those foreign key relationships managed?

• For big project probably only test important key parts

33

Page 34: Developer Testing

Stephan J. Schmidt, cintoo

Coverage

• Code is instrumented by coverage tool

• Find code which is not executed during tests

• Statements, methods, conditionals

• Help QA to understand your tests

34

Page 35: Developer Testing

Stephan J. Schmidt, cintoo

100% Test Coverage

• Not faked :-)

• Filter main and Exceptions away (not your own!)

• Possible but usually not needed

• May distract developers from real goals

35

Page 36: Developer Testing

Stephan J. Schmidt, cintoo

Credits

• Thanks to Zutubi for Pulse integration server

• Thanks to cenqua for Clover code coverage

• Thanks to Cedric for TestNG, Kent and Martin for JUnit

• Thanks to the creators of the other tools

• Tools used: IDEA, jMock, Pulse, Clover, Jemmy, TestNG/ JUnit, HSQL

36

Page 37: Developer Testing

Stephan J. Schmidt, cintoo

References

• Kent Beck, “The Future of Developer Testing”, SDForum 2004

• David Astels, “test-driven development - A Practical Guide”, 2003

• Steve Freeman, Nat Pryce, Tim Mackinnon, Joe Walnes, “Mock Roles, not Objects”

37

Page 38: Developer Testing

Stephan J. Schmidt

cintoo lead developerhttp://[email protected]