Time for action – waiting for a condition

Typically an action may require some result to happen in the user interface before testing can continue. Since the SWTBot can run much faster than a human can, waiting for the result of an action may be necessary. To demonstrate this, create a Java project with a single source file and then use the conditions to wait until the class file is compiled.

  1. Create a new method in the UITest class called createJavaProject.
  2. Use the bot to create a new Java project by copying the createProject method as a template.
  3. Add the org.eclipse.core.resources as a dependency to the plug-in.
  4. Add a method getProject, which takes a projectName and returns an IProject from ResourcesPlugin.getWorkspace().getRoot().getProject().
  5. At the end of the createJavaProject method, use the getProject method with the test project to get the folder src.
  6. If the folder does not exist, create it.
  7. Get the file from src called Test.java.
  8. Create it with the contents from class Test{} bytes as a ByteArrayInputStream.
  9. Look for a dialog with the title Open Associated Perspective? and if it exists, click on the Yes button.
  10. Use the bot.waitUntil method to pass in a new anonymous subclass of DefaultCondition.
  11. In the test method of the condition, return if the project's folder bin has a file called Test.class.
  12. In the getFailureMessage of the condition, return a suitable message.
  13. The code looks like:
    @Test
    public void createJavaProject() throws Exception {
      String projectName = "SWTBot Java Project";
      bot.menu("File").menu("Project...").click();
      SWTBotShell shell = bot.shell("New Project");
      shell.activate();
      bot.tree().expandNode("Java").select("Java Project");
      bot.button("Next >").click();
      bot.textWithLabel("Project name:").setText(projectName);
      bot.button("Finish").click();
      final IProject project = getProject(projectName);
      assertTrue(project.exists());
      final IFolder src = project.getFolder("src");
      final IFolder bin = project.getFolder("bin");
      if (!src.exists()) {
        src.create(true, true, null);
      }
      IFile test = src.getFile("Test.java");
      test.create(new ByteArrayInputStream(
        "class Test{}".getBytes()), true, null);
      try {
        SWTBotShell dialog = 
         bot.shell("Open Associated Perspective?");
        bot.button("Yes").click();
      } catch (WidgetNotFoundException e) {
        // ignore
      }
      bot.waitUntil(new DefaultCondition() {
        @Override
        public boolean test() throws Exception {
          return bin.getFile("Test.class").exists();
        }
        public String getFailureMessage() {
          return "File bin/Test.class was not created";
        }
      });
      assertTrue(bin.getFile("Test.class").exists());
    }
  14. Run the test and verify that it passes OK.
  15. Comment out the waitUntil call and verify that the test fails.

What just happened?

When the Test.java file is created in the project, an event is fired which runs the Java compiler. This in turn results in the creation of both the bin folder as well as the Test.class file that is being tested. However both of these operations occur on different threads, and so whilst the test is running, if it needs to act on the generated file it must wait until that file exists.

Although this example could have been implemented outside of SWTBot, it provides a simple way to block the execution until a particular condition occurs. This can be useful if the user interface is running some kind of long-running action and the code needs to wait until a certain dialog message is shown, or something that can be determined programmatically (such as the file's existence in this case).

Other types of conditionals and tests are possible; as well as the bot's waitUntil method, there is also a waitWhile method which has the opposite behavior.

Note that when the wait condition is commented out, the test fails, because the test execution thread will hit the assertion before the Java compiler has been able to run.

One advantage of using the wait code in SWTBot is that if the condition doesn't occur within a given timeout, then an exception is generated and the test will fail. Since the same wait condition is used elsewhere in SWTBot, the delay is configurable and can be changed externally.

Have a go hero – driving the new class wizard

Instead of using the creation of a source file as a text file, use SWTBot to execute the File | New Class wizard. Pass in the name of the project, the package, and the class, and both the source and the class file should be created in the background. This is how integration tests that show the application working from a user's perspective can be implemented, instead of having a set of tests that just shows the underlying libraries working as expected.

Pop quiz – understanding swtbot

Q1. What is the name of the JUnit test runner that is required for SWTBot?

Q2. How are views shown with SWTBot?

Q3. How do you get the text value of a field in a dialog?

Q4. What is a Matcher and when would it be used?

Q5. How can values from the UI trivially be returned to the user without having to worry about thread interaction?

Q6. When some asynchronous events are happening in the background, how can the test wait until a particular condition occurs without blocking the test?

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.218.70.93