Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » scout » Unit Tests and BlockingCondition
Unit Tests and BlockingCondition [message #829338] Mon, 26 March 2012 02:53 Go to next message
Adrian Moser
Messages: 67
Registered: March 2011
Member
Is it possible to write Unit Tests when a Scout BlockingCondition is involved?
Since there is no user interaction, the BlockingCondition seems never to be resolved.
This happens especially when testing a menu which starts a form.

Any ideas?
Re: Unit Tests and BlockingCondition [message #829348 is a reply to message #829338] Mon, 26 March 2012 03:09 Go to previous messageGo to next message
Ivan Motsch is currently offline Ivan Motsch
Messages: 100
Registered: March 2010
Senior Member
Yes, you can either schedule a ClientAysncJob that - after a delay - schedules another ClientSyncJob to resolve the lock by invoking the ui facade methods of the message box.

Or you can - for testing reasons - create a custom IExceptionHandlerService instance with @Priority(1000) and register it using TestingUtilty. That way you can even use error handling info in your plugin unit tests.
Re: Unit Tests and BlockingCondition [message #829359 is a reply to message #829348] Mon, 26 March 2012 03:29 Go to previous messageGo to next message
kid liang is currently offline kid liang
Messages: 7
Registered: March 2012
Junior Member
I have a question ,but I don't known how to ask others in this forums.My English is poor,what should I do ?
Re: Unit Tests and BlockingCondition [message #829363 is a reply to message #829359] Mon, 26 March 2012 03:34 Go to previous messageGo to next message
kid liang is currently offline kid liang
Messages: 7
Registered: March 2012
Junior Member
唉 The screen is full of English...I do not known most of the words...what should I do ?
Re: Unit Tests and BlockingCondition [message #829402 is a reply to message #829363] Mon, 26 March 2012 04:33 Go to previous messageGo to next message
Andi Bur is currently offline Andi Bur
Messages: 4
Registered: March 2010
Junior Member
If you are using Scout's JUnit based testing support by annotating your unit tests with @RunWith(ScoutClientTestRunner.class) on client side and @RunWith(ScoutServerTestRunner.class) on server side, you are already running within a scout job. Typically, it is not required to start any other jobs. Here is an overview of Scout's testing support: www.eclipse.org/forums/index.php/t/262115/
Could you give us more details if you have another use case?

The IExceptionHandlerService referenced by ivan.motsch is already registered by Scout's testing support. The SctouClientTestRunner and the ScoutServerTestRunner are both dynamically registering an IExceptionHanlderService with priority 1000. It wraps ProcessingExceptions into RuntimeExceptions which are unwrapped and rethrew later on so that the JUnit test fails.

@kid liang, which language do you prefer -- we try to help.
Re: Unit Tests and BlockingCondition [message #829518 is a reply to message #829402] Mon, 26 March 2012 07:57 Go to previous messageGo to next message
Adrian Moser
Messages: 67
Registered: March 2011
Member
Yes, I'm using Scout JUnit support.

My test looks as follows (assuming there is at least one row in the table):
  @Test
  public void testEditMenu() throws Exception {
    MyTablePage page = new MyTablePage();
    page.loadChildren();

    page.getTable().selectFirstRow();
    boolean run = page.getTable().runMenu(EditMenu.class);
    Assert.assertTrue(run);
  }


where EditMenu calls the following code

MyForm form = new MyForm();
form.setMyNr(getMyNrColumn().getSelectedValue());
form.startModify();
form.waitFor();


Now the test simply blocks, it does not finish.
Re: Unit Tests and BlockingCondition [message #829711 is a reply to message #829518] Mon, 26 March 2012 13:26 Go to previous messageGo to next message
Adrian Moser
Messages: 67
Registered: March 2011
Member
At least I found a solution to a related problem, testing a button that opens a file chooser.

I have a button that executes the following code:
FileChooser fileChooser = new FileChooser();
fileChooser.setTypeLoad(true);
File[] files = fileChooser.startChooser();


This also goes into a BlockingCondition.
The test code adds a desktop listener and sets the file during testing:

  @Test
  public void testMyButton() throws Exception {
    final File file = new File("some path...");

    DesktopListener listener = new DesktopListener() {
      @Override
      public void desktopChanged(DesktopEvent e) {
        if (e.getType() == DesktopEvent.TYPE_FILE_CHOOSER_ADDED) {
          IFileChooser chooser = e.getFileChooser();
          chooser.setFiles(new File[]{file});
        }
      }
    };
    ClientSession.get().getDesktop().addDesktopListener(listener);

    MyForm form = getForm();
    form.getMyButton().doClick();

    ClientSession.get().getDesktop().removeDesktopListener(listener);
  }


I will try to find a similar solution for forms.
Any suggestions?
Re: Unit Tests and BlockingCondition [message #832143 is a reply to message #829711] Thu, 29 March 2012 16:41 Go to previous messageGo to next message
Claudio Guglielmo is currently offline Claudio Guglielmo
Messages: 126
Registered: March 2010
Senior Member
Hi Adrian

Possible deadlocks when running the tests is a known issue and very annoying. Unfortunately the scout testing framework does not provide a solution for this problem yet. Until there is one you can use the following helper functions resp. create similar ones for your specific case. Basically you need to register a ChangeListenerEx and release the waitFor by closing the form when it gets blocked.

Hope that helps.
Claudio

/**
   * If clicking a button leads to a lock because execClickAction contains waitFor() no code can be executed until the
   * lock is released.
   * With this function it is possible to execute code just before the lock is installed.
   * <p>
   * The caller must ensure that the lock gets released (f.e. by canceling the form at the and of the runnable).
   * </p>
   * 
   * @param button
   * @param runnableAfterButtonClick
   * @throws ProcessingException
   */
  public static void clickBlockingButton(IButton button, Runnable runnableAfterButtonClick) throws ProcessingException {
    TestingExceptionHandlerService exceptionHandler = new TestingExceptionHandlerService();
    List<ServiceRegistration> regs = TestingUtility.registerServices(Activator.getDefault().getBundle(), 1000, exceptionHandler);

    WaitForListener waitForListener = new WaitForListener(runnableAfterButtonClick);
    ClientJob currentJob = (ClientJob) ClientJob.getJobManager().currentJob();
    currentJob.addJobChangeListenerEx(waitForListener);
    try {
      //click button which opens the form and blocks with waitFor()
      button.doClick();
      exceptionHandler.assertNoException();
      exceptionHandler.clear();
    }
    finally {
      currentJob.removeJobChangeListenerEx(waitForListener);
      TestingUtility.unregisterServices(regs);
    }

  }

  public static <T extends IForm> T findLastAddedForm(Class<T> formType) {
    T[] forms = ClientSession.get().getDesktop().findForms(formType);
    if (forms == null || forms.length == 0) {
      return null;
    }

    return forms[forms.length - 1];
  }

  private static class WaitForListener extends JobChangeAdapterEx {
    private Runnable runnable;

    public WaitForListener(Runnable runnable) {
      this.runnable = runnable;
    }

    @Override
    public void blockingConditionStart(IJobChangeEvent event) {
      try {
        runnable.run();
      }
      catch (Throwable t) {
        //Exception would be catched by the listener so it is necessary to use the exception service in order to make the test fail.
        SERVICES.getService(TestingExceptionHandlerService.class).handleException(new ProcessingException("", t));
      }
    }

  }

Re: Unit Tests and BlockingCondition [message #834997 is a reply to message #829338] Mon, 02 April 2012 13:00 Go to previous messageGo to next message
Adrian Moser
Messages: 67
Registered: March 2011
Member
Hi Claudio

Thanks for your sample, that looks promising. Can you give me a hint (or some code Razz ) how your TestingExceptionHandlerService looks like?

Adrian
Re: Unit Tests and BlockingCondition [message #835127 is a reply to message #834997] Mon, 02 April 2012 16:48 Go to previous message
Claudio Guglielmo is currently offline Claudio Guglielmo
Messages: 126
Registered: March 2010
Senior Member
Hi Adrian

There you go.

Claudio

/**
 * Use this custom exception handler service to catch all exceptions (message boxes) and check for specific events
 */
public class TestingExceptionHandlerService extends AbstractService implements IExceptionHandlerService {
  private ProcessingException m_lastException;

  @Override
  public void handleException(ProcessingException t) {
    if (t != null) {
      String message = t.getStatus().getMessage().replaceAll("\\s+", " ").trim();
      System.out.println("consuming: " + message);
    }
    m_lastException = t;
  }

  public void assertNoException() {
    if (m_lastException == null) {
      return;
    }

    if (m_lastException.getCause() instanceof AssertionError) {
      throw (AssertionError) m_lastException.getCause();
    }

    throw new RuntimeException(m_lastException);
  }

  /**
   * similar means all whitespace is replaced by one space and all text is lower case for compare
   */
  public void assertLastExceptionIsSimilarTo(Class<?> type, String message) {
    Assert.assertNotNull(m_lastException);
    Assert.assertEquals(type, m_lastException.getClass());
    String expected = m_lastException.getStatus().getMessage().toLowerCase().replaceAll("\\s+", " ").trim();
    String actual = message.toLowerCase().replaceAll("\\s+", " ").trim();
    Assert.assertEquals(expected, actual);
  }

  public void clear() {
    m_lastException = null;
  }
}
Previous Topic:TEXTS: having a strict service
Next Topic:NLS-Support in Scout
Goto Forum:
  


Current Time: Sat Jul 26 09:16:44 EDT 2014

Powered by FUDForum. Page generated in 0.17095 seconds