Search code examples
javamaventestingnetbeansnetbeans-platform

Functional tests (Jellytools) don't start on netbeans platform


I'm trying to add some functional tests on existing netbeans application.
Info about application: packaged by maven, used netbeans platform 7.3.1. I've added dependencies how described in this article but got exception:

Running qa.FuncTest
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.067 sec <<< FAILURE! - in qa.FuncTest
org.netbeans.junit.NbModuleSuite$S@67ad77a7(org.netbeans.junit.NbModuleSuite$S)  Time elapsed: 0.066 sec  <<< ERROR!
java.lang.ClassNotFoundException: org.netbeans.Main
    at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
    at org.netbeans.junit.NbModuleSuite$S.runInRuntimeContainer(NbModuleSuite.java:819)
    at org.netbeans.junit.NbModuleSuite$S.access$100(NbModuleSuite.java:667)

Does anybody know why it happend? And how to fix it? Thanks in advance.

UPD dependency section from application/pom.xml

<dependencies>
    <dependency>
        <groupId>org.netbeans.cluster</groupId>
        <artifactId>platform</artifactId>
        <version>${software.netbeans.version}</version>
        <type>pom</type>
    </dependency>
    <dependency>
        <groupId>org.netbeans.api</groupId>
        <artifactId>org-jdesktop-beansbinding</artifactId>
        <version>${software.netbeans.version}</version>
    </dependency>
    <dependency>
        <groupId>org.netbeans.api</groupId>
        <artifactId>org-netbeans-modules-nbjunit</artifactId>
        <version>${software.netbeans.version}</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.netbeans.api</groupId>
        <artifactId>org-netbeans-modules-jellytools-platform</artifactId>
        <version>${software.netbeans.version}</version>
        <scope>test</scope>
    </dependency>
</dependencies>

UPD1 test class:

package qa;

import junit.framework.Test;
import org.netbeans.jellytools.JellyTestCase;
import org.netbeans.jellytools.OptionsOperator;
import org.netbeans.junit.NbModuleSuite;
import org.openide.windows.TopComponent;

public class FuncTest extends JellyTestCase {

    public static Test suite() {
        return NbModuleSuite.allModules(FuncTest.class);
    }

    public FuncTest(String n) {
        super(n);
    }

    public void testWhatever() throws Exception {
        TopComponent tc = new TopComponent();
        tc.setName("label");
        tc.open();
        OptionsOperator.invoke().selectMiscellaneous();
        Thread.sleep(5000);
        System.err.println("OK.");
    }
}

Solution

  • I would like to share results of my investigation. I noticed when application was started as usual i saw in output window:

      Installation            =.../application/target/application/extra
                               .../application/target/application/java
                               .../application/target/application/kws
                               .../application/target/application/platform
    

    but when application was started via nbjubit/jellytool i saw only:

      Installation            =.../application/target/application/platform
    

    so i decided to expand this values and investigated source code. Let's consider a few interesting methods in NbModuleSuite.java :

        private static String[] tokenizePath(String path) {
            List<String> l = new ArrayList<String>();
            StringTokenizer tok = new StringTokenizer(path, ":;", true); // NOI18N
    
    
        .....
            }
    
    static File findPlatform() {
            String clusterPath = System.getProperty("cluster.path.final"); // NOI18N
            if (clusterPath != null) {
                for (String piece : tokenizePath(clusterPath)) {
                    File d = new File(piece);
                    if (d.getName().matches("platform\\d*")) {
                        return d;
                    }
                }
            }
            String allClusters = System.getProperty("all.clusters"); // #194794
            if (allClusters != null) {
                File d = new File(allClusters, "platform"); // do not bother with old numbered variants
                if (d.isDirectory()) {
                    return d;
                }
            }
    
    
        ....
            }
    
    static void findClusters(Collection<File> clusters, List<String> regExps) throws IOException {
            File plat = findPlatform().getCanonicalFile();
            String selectiveClusters = System.getProperty("cluster.path.final"); // NOI18N
            Set<File> path;
            if (selectiveClusters != null) {
                path = new TreeSet<File>();
                for (String p : tokenizePath(selectiveClusters)) {
                    File f = new File(p);
                    path.add(f.getCanonicalFile());
                }
            } else {
                File parent;
                String allClusters = System.getProperty("all.clusters"); // #194794
                if (allClusters != null) {
                    parent = new File(allClusters);
                } else {
                    parent = plat.getParentFile();
                }
                path = new TreeSet<File>(Arrays.asList(parent.listFiles()));
            }
    
    
    ....
            }
    

    As you can see we can set path values in cluster.path.final or all.clusters and use ; : as delimeters. I spent some time to play with this constants and realised that settings didn't set up in pom.xml:

    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>${software.maven-surefire-plugin}</version>
        <configuration>
            <skipTests>false</skipTests>
            <systemPropertyVariables>
                <branding.token>${brandingToken}</branding.token>
                <!--problem part start-->
                <property>
                    <name>cluster.path.final</name>
                    <value>${project.build.directory}/${brandingToken}/platform:${project.build.directory}/${brandingToken}/java:...etc</value>
                </property>
                <!--problem part end-->
            </systemPropertyVariables>
        </configuration>
    </plugin>
    

    but this work well:

    <properties>
        <cluster.path.final>${project.build.directory}/${brandingToken}/platform:${project.build.directory}/${brandingToken}/java:...etc</cluster.path.final>
    </properties>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>${software.maven-surefire-plugin}</version>
        <configuration>
            <skipTests>false</skipTests>
            <systemPropertyVariables>
                <branding.token>${brandingToken}</branding.token>
                <cluster.path.final>${cluster.path.final}</cluster.path.final>
            </systemPropertyVariables>
        </configuration>
    </plugin>
    

    I don't know why it happens but I would recommend to use maven section properties to set systemPropertyVariables of maven-surefire-plugin. Good luck!