081107 sammy eclipse summit2

22
Enabling Test-First Development for Eclipse UI Matthias Kempka Innoopract Informationssysteme GmbH

Upload: mkempka

Post on 27-May-2015

949 views

Category:

Technology


1 download

DESCRIPTION

Testing Eclipse GUIs still is an elaborate and extensive task. There are two ways to get the task done: Record-and-play and programming by hand. Test-first programmers usually prefer to program their tests by hand instead of using record-and-play tools, which are typically used by test departments that construct large functional test suites. When programming UI tests by hand, the programmer is let alone mainly with SWT Robots. While they are great tools to find and use widgets, they naturally can't find their controllers like the the JFace Viewers and the Workbench ViewParts. In test-first development this becomes a problem because the programming level for test and productive code is at a different abstraction level. Matthias Kempka has found a way to implement a JFace/Workbench Robot. It finds JFace Viewers for SWT elements and eases the testing with views and editors. Declarative UI Elements become accessible for programmed tests. In his talk Matthias Kempka shows how he uses the JFace/Workbench Robot to develop GUI components in Eclipse test-driven and gives an introduction to the key ideas that make the Robot work.

TRANSCRIPT

Page 1: 081107   Sammy   Eclipse Summit2

Enabling Test-First Development for Eclipse UI

Matthias KempkaInnoopract Informationssysteme GmbH

Page 2: 081107   Sammy   Eclipse Summit2

OutlineOutline

Problem description Components for testing UI programmatically Test Case with JFace/Workbench Robot Sammy

Page 3: 081107   Sammy   Eclipse Summit2

Creating code test-drivenCreating code test-driven

Piece of Code

Unit Tests

TDD creates little pieces of code Readable Simple Flexible Regression tests already there Great, uh?

Page 4: 081107   Sammy   Eclipse Summit2

Where should I put it?Where should I put it?

Piece of Code

A framework has many hooks Did I hook up my PoC in the right spot? Did I hook it up at all?

Eclipse Framework

Page 5: 081107   Sammy   Eclipse Summit2

„„Testing“ by handTesting“ by hand

Developer

Easiest approach: Try it. Regression tests?

Piece of Code

Eclipse Framework

use

*click*

Page 6: 081107   Sammy   Eclipse Summit2

PDE TestsPDE Tests

PDE Unit Tests

Let's write regression tests PDE tests can start our test code with a workbench Some Eclipse functionality is hard to reach programmatically

Piece of Code

Eclipse Framework

Page 7: 081107   Sammy   Eclipse Summit2

Functional Tests with SWT RobotsFunctional Tests with SWT Robots

Piece of Code

Eclipse Framework

PDE Unit Tests SWT Robot

use

use

*click*

SWT Robots can simulate User interaction Is it easier to find a ViewAction button on the screen than in the Workbench

API?

Page 8: 081107   Sammy   Eclipse Summit2

Are SWT Robots the solution?Are SWT Robots the solution?

Can find SWT widgets in the widget hierarchy Provides convenience methods to use the widgets Can read feedback from the UI

Composite

Shell

Label Text

Display

Page 9: 081107   Sammy   Eclipse Summit2

What's not in the Widget Hierarchy?What's not in the Widget Hierarchy?

Basically all objects an Eclipse programmer touches are not in the widget hierarchy

Association with IDs from plugin.xml is lost

Composite

Shell

Label Text

Display IViewPart

IEditorPart

TableViewer

TreeViewer

IActionDelegate

IHandler

...

IMarker

Page 10: 081107   Sammy   Eclipse Summit2

Functional Tests with RobotsFunctional Tests with Robots

Piece of Code

Eclipse Framework

SWT Robot

JFace/WorkbenchRobot

A JFace/Workbench Robot eases access to the interesting parts of the UI. Provides access to JFace controllers

PDE Unit Tests

use

*click*

Page 11: 081107   Sammy   Eclipse Summit2

Make common things easy, make difficult things possible

I need to set up test data for the TableViewer behind this SWT Table on the screen? How can I reach it?

I'm writing a view. How can I test that all the listeners are attached correctly? I'm writing a contribution to a view (i.e. a ViewAction) – How can I test that

my entries in plugin.xml works? Does my LabelProvider return the right image?

Sammy: The MissionSammy: The Mission

Page 12: 081107   Sammy   Eclipse Summit2

Writing a test with JFace/Workbench Robot Writing a test with JFace/Workbench Robot SammySammy

Write a test case: Set up: Prepare a view for the actual test

– open the view Tear down:

– Clean up allocated resources: Close the view Actual test

– Find the TableViewer in that view and set a test-specific input– Check that a view action is not enabled– Select an item in the table– Check that the view action is enabled

Page 13: 081107   Sammy   Eclipse Summit2

Set up: Open a viewSet up: Open a view

Views could be opened using IWorkbenchPage.showView( id )– Too cumbersome for such a common use case – No immediate feedback on errors

Sammy.openView( id ) eases setting up test cases– easy accessible API– Show errors in red test case instead of UI– Remembers the view for cleaning up

public void setup() throws Exception { sammy = new Sammy(); sammy.openView( ViewUnderTest.ID );}

Page 14: 081107   Sammy   Eclipse Summit2

Tear downTear down

Instances of Sammy (and SammyIDE) remember the resources they allocated and can release (close or delete) them– IViewPart– IEditorPart– IResource

public void teardown() throws Exception { sammy.cleanup();}

Page 15: 081107   Sammy   Eclipse Summit2

Test: Finding the viewTest: Finding the view

Every supported JFace/Workbench Element has an Operator:– IViewPart – ViewOperator– IEditorPart – EditorOperator– TableViewer – TableViewerOperator– …

The Operator gives access to the described JFace/Workbench element– Convenience methods for common use cases

Operator constructor – takes parameters that describe the JFace/Workbench element– returns without Exception only if the described element was found– waits a time for the element to appear

public void testViewAction() throws Exception { ViewOperator vo = new ViewOperator( “View Title” );}

Page 16: 081107   Sammy   Eclipse Summit2

Test: Finding the TableViewerTest: Finding the TableViewer

Operators for workbench parts know their parent composite– Given in IWorkbenchPart.createPartControl( Composite )

Operators for JFace elements – take a parent of the SWT element or the SWT element itself– can associate the SWT element with the JFace abstraction

public void testViewAction() throws Exception { ViewOperator vo = new ViewOperator( “View Title” ); TableViewerOperator tvo = new TableViewerOperator( vo.getParentComposite() );}

Page 17: 081107   Sammy   Eclipse Summit2

Test: Setting the InputTest: Setting the Input

Setting up Test Data often includes setting a special input on a viewer Having the TableViewer already available eases this remarkably *Operator.getSource()returns the actual JFace/Workbench element

public void testViewAction() throws Exception { ViewOperator vo = new ViewOperator( “View Title” ); TableViewerOperator tvo = new TableViewerOperator( vo.getParentComposite() ); tvo.getSource().setInput( new String[] { “a” } );}

Page 18: 081107   Sammy   Eclipse Summit2

Test: Checking ViewerOperator enablementTest: Checking ViewerOperator enablement

A ViewActionDelegate only is instanciated once the user selects the ViewAction

The ViewActionOperator knows the Proxy by the workbench as well as the delegate

public void testViewAction() throws Exception { ViewOperator vo = new ViewOperator( “View Title” ); TableViewerOperator tvo = new TableViewerOperator( vo.getParentComposite() ); tvo.getSource().setInput( new String[] { “a” } ); ViewActionOperator vao = new ViewActionOperator( vo, MyViewAction.ID ); assertFalse( vao.isEnabled() );}

Page 19: 081107   Sammy   Eclipse Summit2

Test: Checking ViewerOperator enablementTest: Checking ViewerOperator enablement

Now all the elements are in place to make this test useful– The View shows up (layout is not tested)– XML Code in plugin.xml is tested– Makes sure that the TableViewer is a SelectionProvider

public void testViewAction() throws Exception { ViewOperator vo = new ViewOperator( “View Title” ); TableViewerOperator tvo = new TableViewerOperator( vo.getParentComposite() ); tvo.getSource().setInput( new String[] { “a” } ); ViewActionOperator vao = new ViewActionOperator( vo, MyViewAction.ID ); assertFalse( vao.isEnabled() ); tvo.getSource().setSelection( new StructuredSelection(“a”)); assertTrue( vao.isEnabled() );}

Page 20: 081107   Sammy   Eclipse Summit2

Sammy InternalsSammy Internals

Widget Viewer

For many things, Sammy relies on mapping from widgets to JFace/Workbench elements– And vice versa

Some widgets are nowhere accessible in the workbench– Where necessary aspects are used to trap widget instances

For some things, Sammy has to access internals– i.e. the View that shows an error holds it in a private field– This leads to compatibility layers, but at least it's in one place

Page 21: 081107   Sammy   Eclipse Summit2

Sammy FutureSammy Future

More than proof of concept, less than beta A good state to start collecting requirements http://www.innoopract.com/en/developers/mkempka/sammy

Page 22: 081107   Sammy   Eclipse Summit2

The End

http://www.innoopract.com/en/developers/mkempka/sammy