Best Practices

When using AIQ to run Eclipse Java-based tests, it is necessary to consider the following considerations to minimize the problems that might arise during the integration process:

  1. Remove System.exit(0) commands.

    System.exit() commands will cause Java Virtual machine to be killed so this will effectively kill the running of an AIQ scenario. So these lines must be deleted from your java project.

  2. Verify all Dependencies are present

    Add all dependencies in AIQ resources, including those used from the IDE configured environment (for example used maven dependencies).

    Appvance scenario should have all the necessary dependencies so the test can be run outside the IDE environment. In Eclipse you can see all .jar files as in figure 1.

    In the AIQ scenario, you need to add all the required .jar files as Java type resources, as seen below

    There are dependencies that might be used by the IDE project that is provided by the IDE configuration environment, for example, those present in the Eclipse Maven Dependencies folder when using an Eclipse Maven Project.

    If your project is using any of these dependencies present in the Maven Dependencies folder in Eclipse, their respective .jar must be added also to AIQ scenario resources, as type Jar as seen in the above figure.

    IMPORTANT: Make sure to convert the resource paths to relative paths before executing your scenario.

  3. Verify all resources are present

    Need to make sure that files accessed in your java code are present in the AIQ scenario, and very important, verify that they are in the required paths.

    3.1 In code, file paths should use "/" as a path separator as that ensures your paths are compatible with Linux/mac/windows nodes.

    3.2 In code, file paths must NOT use absolute references like D:\myfolder\file.xml, but use relative paths always like ./myfolder/file.xml

    For example, if you have an Eclipse project that requires access to files like properties, configuration, text, or other resources files, you need to ensure that those files do get exported inside the .jar that will read in the AIQ test case definition.

    One way to ensure that resource files are exported inside the project .jar is by putting the required resource files inside the Eclipse src folder.

    Important:

    If you have an Eclipse project with a resources folder (and obviously, it is outside the src folder), then that folder will have to be manually added to the .jar exported by Eclipse.

    If a resource file is not found during AIQ execution, an error will be listed with an exception like java.lang.NullPointerException, with the offending class and the line number. Use that info to verify in the code the missing resource and the path required.

  4. Verify that your Code is Thread Safe

    Code that works fine in a single-threaded environment does not necessarily mean that it will perform well in a multi-threaded environment, as in AIQ testing with multiple users.

    So you should test your project in AIQ first in a functional test with one test case. If it runs smoothly then try it in a performance test with 10 or more users. If errors pop up, a big chance exists that there are concurrency design problems. The error logs point to the code that needs to be checked for concurrency safety.

    All threads in Java virtual machines share the same heap and method areas. Because all threads share the same heap, and the heap is where all instance variables are stored, multiple threads can attempt to use the same object's instance variables concurrently.

    Likewise, because all threads share the same method area, and the method area is where all class variables are stored, multiple threads can attempt to use the same class variables concurrently.

    For example:

    class MyCounter {

    private static int counter = 0;

    public static int getCount() {

    return counter++; // this is not thread-safe

    }

    }

    The above method is not thread-safe, because the counter++; operation is not atomic, which means it consists of more than one atomic operation over a class variable (shared by all threads). In this case, one thread (user) can be accessing its value and the other thread (user) can be increasing the value by one at the same time.

    Articles with more on designing for thread safety: http://www.developer.com/java/fundamentals-of-thread-safety-in-java.html http://www.javaworld.com/article/2076747/core-java/design-for-threadsafety.html?page=2

    You need not worry about multithreaded access to local variables, method parameters, and return values because these variables reside on the Java stack. In the JVM, each thread is awarded its own Java stack.