As part of a CI (Continuous Integration) process, every day (indeed every night) the source code of these KNIME nodes is downloaded from the SCM, compiled, and a p2 site is built (in a more or less laborious process along CI software like Jenkins and Sonar). This procedure works fine using a combination of maven and tycho for Ecplipse plugin development.
Unfortunately I am stuck in a problem that I have no idea of how to overcome. I want to add some Junit testing in the CI process. Thus the process will be as following: download from SCM, compile, test, mount p2 site with the nodes. I have started with a very simple Junit test following the indications described here
I have tried to do my best coding a very simple junit test in a fragment, but the following error is raised:
java.lang.SecurityException: class "org.knime.core.node.InvalidSettingsException"'s signer information does not match signer information of other classes in the same package
Surfing the KNIME forum I found a message where thor explained the reason of this error:
I wonder if anybody know some kind of workaround or solution to tackle this problem. I firmly believe in JUnit headless testing as a very important part of CI. How could I include headless testing (I really love JUnit but I am willing to use another testing framework if necessary).
The JUnit tests must be run inside Eclipse, otherwise the whole classloading does not work as expected (therefore the SecurityException). If you follow the instructions from the community developers page, you can use the Eclipse application org.knime.testing.UnittestRunner. It will search for JUnit tests in all plug-ins/fragments that have an AbstractTestcaseCollector. The application will create a XML file with the test results that can be read by Jenkins.
So my feature project containing the fragment project that contains the test cases have to be exported as a jar, and dropped into the drops-in folder of KNIME, before i run the NGUnittestRunner?
Please don't use the dropins folder! This is outdated and causes lots of problems. Instead create an update site with your feature(s) and install them from there into KNIME using the p2 directory (you can even create an installation from scratch with the p2 director). This is the standard Eclipse approach and documented in the Eclipse help.
Ok i will try that for installation. Even my test features have to be installed this way?
With regards to running the tests, i will also need to provide the parameters "-configuration" and "-dev" right?
Copied from the launch configuration in eclipse IDE.
knime -application org.knime.testing.NGUnittestRunner -nosplash -xmlResultDir C:\testresults -configuration "file:C:/Users/xxx/workspace-testing/.metadata/.plugins/org.eclipse.pde.core/KNIME Unit Test Runner/" -dev "file:C:/Users/xxx/workspace-testing/.metadata/.plugins/org.eclipse.pde.core/KNIME Unit Test Runner/dev.properties"
Yes, also the test feature can be installed this way. You don't need the -configuration and -dev options if you are running the test in a standalone product. They are mainly used for starting an Eclipse instance out of the SDK (which is set up quite differently regarding plug-ins, features, etc.).
So you put a subclass of AbstractTestcaseCollector into your fragment and registered this class in the fragment at the org.knime.testing.TestcaseCollector extension point? Then this has to work.
It worked. Now when i run in linux. I am getting this SWT error.
[xxx@dev01 eclipse_knime_testing]$ ./eclipse -application org.knime.testing.NGUnittestRunner -xmlResultDir ~/tests -consoleLog
!ENTRY org.eclipse.osgi 4 0 2014-08-13 20:52:47.438
!MESSAGE Application error
!STACK 1
org.eclipse.swt.SWTError: No more handles [gtk_init_check() failed]
at org.eclipse.swt.SWT.error(SWT.java:4308)
at org.eclipse.swt.widgets.Display.createDisplay(Display.java:909)
at org.eclipse.swt.widgets.Display.create(Display.java:897)
at org.eclipse.swt.graphics.Device.<init>(Device.java:157)
at org.eclipse.swt.widgets.Display.<init>(Display.java:500)
at org.eclipse.swt.widgets.Display.<init>(Display.java:491)
at org.eclipse.ui.internal.Workbench.createDisplay(Workbench.java:716)
at org.eclipse.ui.PlatformUI.createDisplay(PlatformUI.java:161)
at org.knime.testing.core.ng.UnittestRunnerApplication.start(UnittestRunnerApplication.java:55)
at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:344)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:622)
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:577)
at org.eclipse.equinox.launcher.Main.run(Main.java:1410)
at org.eclipse.equinox.launcher.Main.main(Main.java:1386)
You cannot. You should start and use a virtual X server (Xvfb) instead. Testcases should in principle be able to open dialogs, windows, etc. We do the following: