Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [swtbot-dev] Cucumber running SWT tests

On 9/16/10 12:17 AM, Daniel Lucraft wrote:
Hi all,

I have two questions about testing SWT that I hope you can help me with.

I'm not actually using SwtBot yet, though I'd like to. This is because we already have quite a lot of tests written using the current system and when I tried to drop in Swtbot just to handle some widget operations there were some conflicts. That's something I'd like to return to.

Currently we have:

  * a separate thread containing a Cucumber test runner
  * Cucumber is patched so that each step (every operation and assertion) is wrapped in a syncExec call

This is working pretty well so far. We have a lot of tests (like this:
http://github.com/redcar/redcar/raw/master/plugins/edit_view/features/undo_and_redo.feature

Each step (each given/when/then) is executed by Cucumber in a syncExec block, and the implementation of the step is manipulating widgets in the background and/or making assertions.

(Our step library is a bit adhoc, which is why I'm interested in using swtbot, but that's for another day)

I've seen a few of your tests, you seem to grab a handle to the widget you want to test and do operations on it. One option might be to wrap the swt widget in an swtbot widget and do the operations to simplify things :)

So the first question is: does this jump out at you as being a bad idea in any way?

Having a syncExec call for *everything* might become a problem in certain cases. See http://goo.gl/zpF6 for an explanation on why.

SWTBot takes a slightly different approach to doing this:

* All operations(click, close, typeText) happen in asynExec(for the same reason mentioned in the FAQ), and there are synch points to detect when this asyncExec has finished execution. * All inspection operations(getText, isEnabled, isVisible) happen in syncExec -- this is because the call has to return a value from the UI thread. * Also there are cases when sending just one event might confuse SWT on certain platforms. An example is sending a mouse-down without a corresponding mouse-up, and all the events that are triggered in between (mouse-in, mouse-hover, selection etc.)

Second question:

We have one test I'm writing now (testing Macro functionality) that looks something like this:

   When I start recording a macro
   And I do X
   And I do Y (*)
   And I stop recording a macro
   And I run the macro (**)
   Then the output is correct

Because this is a macro, step (**) does X and Y again. In fact, the implementation of, say, X in steps (*) and (**) is making *exactly the same method calls* on the same widgets.

However the operation X works fine in (*) but doesn't work right in (**). So the tests fail. This is implemented correctly, manual tests in the editor work fine.

Remember that each *line* of that test is wrapped in a syncExec. So X and Y are in two separate syncExec blocks when they are listed separately, but they are in the same syncExec block when they are run in the macro in (**).

A couple more observations before I leave you with my question (thanks for reading this far!):

  * X is a method on StyledText. I notice that the method works by creating an Event and sending the event to itself. This clued me in that there is something 'eventy' going on<- this is my rough level of understanding :)
  * Step (**) usually fails. However, it will always succeed *if I constantly move the mouse over the window* while it runs !!!

I imagine that I need to somehow have the event queue flushed after every step, but nothing I tried works.

Do you have any idea what's going on?

Yup, took me a long while to figure out!

The event queue needs to be flushed and or synched for some reason. See http://goo.gl/DAWc for one possible implementation that's been working well for swtbot for a long time now.

--
Ketan
http://ketan.padegaonkar.name | http://eclipse.org/swtbot


Back to the top