Developer Testing

Post on 11-May-2015

795 Views

Category:

Technology

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

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

Transcript

Developer Testing

Stephan J. Schmidt

cintoo lead developer

http://cintoo.org

stephan@cintoo.org

Achieving a hundred percent test coverage for database and Swing applications

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

Stephan J. Schmidt, cintoo

What is Developer Testing

3

Testing done by developersSimple:

Stephan J. Schmidt, cintoo

Acceptance versus Developer Tests

4

Acceptence Testing

System against Requirements

Developer Testing

Code against DesignTests:

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

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

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

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

Stephan J. Schmidt, cintoo

Example adding two numbers

9

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

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)); }}

Stephan J. Schmidt, cintoo

Test tools

• Tests are run with a testing tool

• Tool displays non-working tests

11

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

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

Stephan J. Schmidt, cintoo

Architecture

• Three tier application

• Different testing scenarios for every tier

14

GUI

Logic

Storage

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

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

Stephan J. Schmidt, cintoo

Testing Math is easy

• Already shown, lucky me :-)

• Test for negative numbers, overflow, ...

17

MathTest

calculate / ok

1

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

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

Stephan J. Schmidt, cintoo

GUI Testing

20

2

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!

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

Stephan J. Schmidt, cintoo

View

23

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

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

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();}

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

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

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

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()

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

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"));

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");

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

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

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

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

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

Stephan J. Schmidt

cintoo lead developerhttp://cintoo.orgstephan@cintoo.org

top related