Loading…

Flash Player 9 (or above) is needed to view presentations.
We have detected that you do not have it on your computer. To install it, go here.

Like this presentation? Why not share!

Eclipse Summit Europe '10 - Test UI Aspects of Plug-ins

on

  • 2,850 views

Testing the UI of an Eclipse plug-in is usually considered rather difficult and something that is best left for specialized tools. Also, the test is often considered very fragile and is expected to be ...

Testing the UI of an Eclipse plug-in is usually considered rather difficult and something that is best left for specialized tools. Also, the test is often considered very fragile and is expected to be updated whenever you make even the smallest change to your UI.
But that need not be so. By using a few rather simple tools and a few just as rules, you can test all the UI parts of an application...

This presentation was made for Eclipse Summit Europe 2010.

Statistics

Views

Total Views
2,850
Views on SlideShare
1,951
Embed Views
899

Actions

Likes
1
Downloads
17
Comments
0

44 Embeds 899

http://tonnymadsen.blogspot.dk 259
http://blog.rcp-company.com 225
http://tonnymadsen.blogspot.com 179
http://tonnymadsen.blogspot.de 37
http://www.eclipsecon.org 26
http://tonnymadsen.blogspot.co.uk 24
http://tonnymadsen.blogspot.in 23
http://tonnymadsen.blogspot.fr 15
http://tonnymadsen.blogspot.cz 11
http://tonnymadsen.blogspot.se 9
http://tonnymadsen.blogspot.co.at 8
http://tonnymadsen.blogspot.ca 6
http://tonnymadsen.blogspot.com.es 6
http://www.techgig.com 6
http://tonnymadsen.blogspot.jp 5
http://tonnymadsen.blogspot.ru 5
http://webcache.googleusercontent.com 4
http://tonnymadsen.blogspot.com.au 4
http://tonnymadsen.blogspot.ch 4
http://translate.googleusercontent.com 3
http://tonnymadsen.blogspot.fi 3
http://tonnymadsen.blogspot.ro 3
http://tonnymadsenblogspot.freeppt.me 3
http://tonnymadsen.blogspot.it 3
https://tonnymadsen.blogspot.com 3
http://tonnymadsen.blogspot.co.il 2
http://tonnymadsen.blogspot.nl 2
http://tonnymadsen.blogspot.kr 2
http://tonnymadsen.blogspot.ie 2
http://tonnymadsen.blogspot.tw 2
http://tonnymadsen.blogspot.co.nz 2
http://taurus.intra.compart.net:8080 1
http://tonnymadsen.blogspot.hu 1
http://115.112.206.131 1
https://www.eclipsecon.org 1
http://tonnymadsen.blogspot.com.br 1
http://tonnymadsen.blogspot.com.ar 1
http://tonnymadsen.blogspot.pt 1
http://tonnymadsen.blogspot.be 1
http://tonnymadsen.blogspot.sk 1
http://tonnymadsen.blogspot.no 1
http://www.google.com 1
http://www.google.com 1
http://tonnymadsen.blogspot.sg 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

CC Attribution License

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • Fir information about the actual parameters to the different commands, check the extensions of org.eclipse.ui .
  • The exact format of the serialized command format is specified in ParameterizedCommand.serialize() : The syntax of the returned String is as follows: serialization = commandId [ '(' parameters ')' ] parameters = parameter [ ',' parameters ] parameter = parameterId [ '=' parameterValue ] In the syntax above, sections inside square-brackets are optional. The characters in single quotes ((, ), , and =) indicate literal characters. commandId represents the command id encoded with separator characters escaped. parameterId and parameterValue represent the parameter ids and values encoded with separator characters escaped. The separator characters (, ), , and = are escaped by prepending a %. This requires % to be escaped, which is also done by prepending a %. The order of the parameters is not defined (and not important). A missing parameterValue indicates that the value of the parameter is null. For example, the string shown below represents a serialized parameterized command that can be used to show the Resource perspective: org.eclipse.ui.perspectives.showPerspective(org.eclipse.ui.perspectives.showPerspective.perspectiveId=org.eclipse.ui.resourcePerspective) This example shows the more general form with multiple parameters, null value parameters, and escaped = in the third parameter value. command.id(param1.id=value1,param2.id,param3.id=esc%=val3)

Eclipse Summit Europe '10 - Test UI Aspects of Plug-ins Eclipse Summit Europe '10 - Test UI Aspects of Plug-ins Presentation Transcript

  • Test UI Aspects of Plug-ins Testing the UI of an Eclipse plug-in is usually considered rather difficult and something that is best left for specialized tools. Also, the test is often considered very fragile and is expected to be updated whenever you make even the smallest change to your UI. But that need not be so. By using a few rather simple tools and a few just as rules, you can test all the UI parts of an application... This presentation was made for Eclipse Summit Europe 2010.
  • About Me
    • Tonny Madsen, Founder and Owner of The RCP Company
    • 20 years of experience in system development in major companies
    • 9 years experience as the Systems Architect of an 20+ MLoC project
    • 8 years of experience with Eclipse and Eclipse RCP
    • Solutions Member of the Eclipse Foundation
    • Chairman of Eclipse.dk
    • Extern Lecturer at IT-University on Model Driven Development and Domain Specific Languages
    • Regular speaker at EclipseCon, Eclipse Summit, etc
  • Downloads
    • This presentation makes some use of a library of low-level test methods.
    • These can be downloaded from
      • http://rcp-company.com/uploads/materials/ESE-2010/TestPlugins-2010-11-01.zip
    • These slides are also available as
      • http://rcp-company.com/uploads/materials/ESE-2010/PR0031 - Eclipse Summit Europe '10 - Test UI Aspects of Plug- ins.pdf
  • JUnit Support in Eclipse
    • Both JUnit 3 and 4 are supported in Eclipse 3.4
    • Alternatively use TPTP Testing framework
    • Special Launch types for “JUnit” and “JUnit Plug-in Test”
    • Special JUnit view
      • Can create new Mylyn tasks from failures
    • It is possible to add plug-ins in Eclipse IDE that will be notified of JUnit runs and results
      • Can be used to ensure that tests all run before commits
  • Where to put Tests
    • Tests of plug-ins can be put several places each with separate pros and cons
    • Inline in the application plug-ins
      • Pros: Easy to manage, access to everything
      • Cons: In the final product
    • In separate plug-ins
      • Pros: Separate from the product
      • Cons: Only access to the exported interface
    • In attached fragments
      • Pros: Access to everything, separate from the product
      • Cons: A different “thing” from plug-ins, difficult to test via PDEbuild
  • What can be Tested using JUnit
    • Almost everything!
      • Functional APIs
      • Behavior of UI elements
      • Performance
    • It is primary the look of the UI that cannot be tested
      • To do this, use special UI testing tools
      • Known SWT aware tools
        • QF-Test
        • GUIdancer
        • WindowTester
      • But remember SWT is mostly just a thin layer on top of the native widget set, so normally the native UI testers can be used as well
    • A few Eclipse elements can be very difficult to test and will require extra co-operation from the tested code
      • Dialogs
      • Wizards
      • Basically everything that creates a new event loop
  • Testing with JUnit 4
    • Create a new plug-in or fragment
    • Add dependency on “ org.junit4 ”
    • Create a test class
      • Alternatively use JUnit Test Case wizard
    • Annotate test methods with @Test
    • Annotate common setup and clean-up code with
      • @Before and @After : Will be executed for each test in class
      • @Before Class and @After Class : Will be executed once per class
    public class ManagerSizesTest { private Manager m; @Before public void setup() { m = Manager.getManager(); } @Test public void testAttributeProviders() { assertEquals(true, m.isReady()); } }
  • Testing Perspectives, Views and Editors
    • Perspectives
      • IWorkbenchWindow.openPage(String perspectiveId, IAdaptable input)
      • Command org.eclipse.ui.perspectives.showPerspective
    • Editors
      • IDE.openEditor(IWorkbenchPage page , IFile file )
        • One of a large number of methods
      • IWorkbenchPage.findEditor(IFile file )
      • No specific command
    • Views
      • IWorkbenchPage. show View(String id )
        • Will open the view in the site according to the perspective definition
      • Command org.eclipse.ui.views.showView
  • Testing Interaction
    • UI tests often have to interact with the application in a manner that is identical or at least similar to the interaction by a user
    • Several way to interact
      • Directly via generated events – especially mouse and key related events
      • Indirectly via manipulation of SWT widgets
      • Indirectly via commands
      • Indirectly via handlers
    • Which way to use often depends on the level of knowledge of the application implementation permitted by the tester
    • In all cases you also need to handle the event loop as tests often runs in the event thread
  • Test Interaction – Mouse and Key
    • A subset of generated mouse and key events can be handled via Display.post ( Event )
      • KeyDown , KeyUp
        • Key down and up must be paired
        • Modifiers must be “pressed” separately
        • Textual descriptions of key strokes can be converted to key codes via KeyStroke.getInstance(stroke)
      • MouseDown , MouseUp
      • MouseMove
        • Mouse must be moved before “pressed”
        • Double-click is handled by clicking twice
      • MouseWheel
  • Test Interaction – Mouse and Key public static void postMouse(Control c, Point p) { final Point pt = c.getDisplay().map(c, null, p); final Event e = new Event(); e.type = SWT.MouseMove; e.x = pt.x; e.y = pt.y; assertTrue(c.getDisplay().post(e)); yield(); e.type = SWT.MouseDown; e.button = 1; e.count = 1 ; assertTrue(c.getDisplay().post(e)); yield(); e.type = SWT.MouseUp; e.button = 1; e.count = 1 ; assertTrue(c.getDisplay().post(e)); yield(); }
  • Test Interaction – The Event Thread
    • If the test runs in the event thread, event dispatching can be needed.
    • Required after use of Display.post ( Event )
    • To dispatch all events in the event queue use (often known as yield )
    • To dispatch all paint requests for a control – possible children
    • To wait a certain period while dispatching events use
    while (display.readAndDispatch()) { } cont = false; display.timerExec(msec, new Runnable() { @Override public void run() { cont = true; } }); while (!cont) { if (!display.readAndDispatch()) { display.sleep(); } } control.update();
  • Test Interaction – Direct Manipulation of Widgets
    • A lot of testing can be done by manipulating widgets directly
      • Cons: it requires an intimate knowledge of the application
      • Pros: it is very robust to many types of changes in the application
    public class TestView extends ViewPart { public Text myText; @Override public void createPartControl(Composite parent) { Composite top = new Composite(parent, SWT.NONE); top.setLayout(new GridLayout(1, false)); myText = new Text(top, SWT.SINGLE | SWT.LEAD | SWT.BORDER); myText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); myText.setText(""); } @Override public void setFocus() { } }
  • Test Interaction – Direct Manipulation of Widgets public class TestViewTest { private TestView myView; @Before public void before() { try { IWorkbenchPage page = PlatformUI.getWorkbench(). getActiveWorkbenchWindow().getActivePage(); myView = (TestView) page.showView("com.rcpcompany.appl.views.TestView"); assertNotNull(myView); } catch (final Exception ex) { fail(ex.getMessage()); } } @Test public void testText() { myView.myText.setText("hello"); // Testing the result… } }
  • Test Interaction – Direct Manipulation of Widgets
    • Some often used cases
      • Entering characters into a t ext widget: Text.setText(str)
      • Selecting item in c ombo box: Combo.setText(str) or Combo.select(i)
      • Ticking check boxes and radio buttons : Button.setSelection(b)
        • But not push buttons!
      • Moving scrollbars, sliders, and scales: ScrollBar.setSelection(i)
      • Changing a tab in a tab folder: TabFolder.setSelection(i)
        • Though no selection event is posted
  • Test Interaction – Executing Simple Commands
    • A simple command has no parameters
    IHandlerService hs = …; hs.executeCommand(&quot;<command-id>&quot;, null);
  • Test Interaction – Executing Parameterized Commands
    • A parameterized command has one or more parameters and can be created in one of two ways:
    IHandlerService hs = …; ICommandService commandService = …; Command c = commandService.getCommand(&quot;<command-id>&quot;); IParameter param = c.getParameter(&quot;<parameter-id>&quot;); Parameterization[] parms = new Parameterization[] { new Parameterization(param, &quot;<value>&quot;) }; ParameterizedCommand pc = new ParameterizedCommand(c, parms); hs.executeCommand(pc, null); IHandlerService hs = …; ICommandService commandService = …; ParameterizedCommand pc = commandService.deserialize(”<cmd-id>(<p-id>=<value>)&quot;); hs.executeCommand(pc, null); ParameterizedCommand pc = commandService.deserialize(”org.eclipse.ui.views.showView(“ + “ org.eclipse.ui.views.showView.viewId=org.eclipse.ui.views.ContentOutline)&quot;);
  • Testing Tables
    • Tables can be a little more difficult to manage
    • Finding the bounds of a specific cell: Table.getItem(row).getBounds(column)
    • Finding the bounds of a specific header:
      • Adjust y to 0 and height to Table.getHeaderHeight()
    • If sorting a table, sleep for at least 5-600ms
    • The row element for a specific row in a viewer: Table.getItem(row).getData()
  • Parameterized Tests
    • It can be very beneficial to parameterize UI tests
      • Test data can even be generated
    @RunWith(Parameterized.class) public class UIAttributeFactoryTest<T extends Widget> extends BaseUIAttributeFactoryTest<T> { @Parameters public static Collection<Object[]> data() { return Arrays.asList(new Object[][] { { Button.class, SWT.PUSH, &quot;&quot;, String.class, &quot;text&quot; }, { Button.class, SWT.PUSH, &quot;text&quot;, String.class, &quot;text&quot; }, { Button.class, SWT.PUSH, &quot;background&quot;, Color.class, &quot;background&quot; }, … }); } public UIAttributeFactoryTest(Class<T> widgetType, int style, final String attribute, final Class<?> expectedValueType, String property) { ... } @Test public void test() { … } }
  • Testing no Error Messages are Logged
    • Most parts of the Eclipse RCP framework log errors using the log interface of plug-ins
    • To test that no error messages are logged hook into the Platform log listener interface
    public static void assertNoLog(Runnable run) { final NoLogListener ll = new NoLogListener(); Platform.addLogListener(ll); try { run.run(); } catch (final Exception ex) { fail(&quot;Exception occured: &quot; + ex.getClass() + &quot;: &quot; + ex.getMessage()); } Platform.removeLogListener(ll); assertTrue(&quot;Log message: &quot; + ll.lastMessage, ll.called == 0); } private static class NoLogListener implements ILogListener { public int called = 0; public String lastMessage; public void logging(IStatus status, String plugin) { if (status.getSeverity() != IStatus.ERROR) return; called++; lastMessage = status.getMessage(); } }
  • If You Want to Know More about Testing
    • “ JUnit 4 in 60 Seconds”
      • http://www.cavdar.net/2008/07/21/junit-4-in-60-seconds/
        • Short but very concise and with focus on the important stuff
    • “ JUnit.org”
      • http://www.junit.org/
        • Home of all the xUnit technologies
    • “ List of GUI testing tools”
      • http:// en.wikipedia.org/wiki/List_of_GUI_testing_tools