Tycho-surefire throws java.lang.IllegalAccess Exceptions - eclipse

I have a maven tycho build (which is running fine) and I want now to add the already existing unit tests to the build setup.
The unit tests are organized in a way that each plugin has its test fragment.
All tests are called from a single test suite which contains the tests suites of the fragments and these are containing the actual unit test classes. This is possible due to the Eclipse-ExtensibleAPI: true setting in Manifest.MF
Each test fragment has its pom.xml which contains true to avoid executing tests twice. The test fragments are set as in main pom.xml.
The main test plugin (which contains the main test suite) contains in its pom.xml an target platform extension (which is a feature containing the test fragments).
Now as soon as a tests is called which is written to test a protected method the tycho-surefire throws an java.lang.IllegalAccessException.
In Eclipse the unit tests run fine (as unit tests, not as plugin unit tests!).
I assume that somehow the classes and the test classes are loaded with different class loaders?
Otherwise, since the test is contained in a fragment to the host plugin and the Eclipse-ExtensibleAPI: true should take care that the visibility is such that this should not happen?
Therefor, I would expect tycho to detect fragments and that it is loading them in a way that they have the same visibility?!
Is there a way/strategy to avoid this behaviour?
I know that tycho-surefire tests are executed in an OSGi environment.
But what does that mean regarding class loading of fragments and the IllegalAccessException?
Any help is highly appreciated!
Thanks in advance!

I found the reason why it was not working.
There where two plugins (one containing the ui code, one the domain model code) and one test fragment. The test fragment was referring to the ui code plugin but contained also tests which tested classes from domain model code.
The packages in the test fragment where named the same as where the packages within the two plugins. I can only make a guess but I think that is why it was working with junit called from within eclipse.
Within the OSGi environment the tycho-surefire tests are running this was not working anymore.
To solve this I split the one test fragment into two (one for each plugin), named the packages of the test classes the same as the packages in the plugin and then it worked as expected.
This is also reflected in my short example project on github.

Related

What is the right way to create JUnit tests for Eclipse fragments?

One of the most common uses of eclipse fragments is as a container for JUnit test classes. But how to write JUnit tests for Eclipse fragment when it plays another, more important role? For example, when it has platform specific code.
The problem is that it is impossible to create a fragment for a fragment. And you can't write tests for host plug-in to test the fragment because it doesn't even compile as a fragment is "merged" into a host only at runtime.
I don't know of a satisfactory solution, however, you may want to consider these workarounds.
Eclipse-ExtensibleAPI
You can use the Eclipse-ExtensibleAPI manifest header like this
Eclipse-ExtensibleAPI: true
It causes the packages exported by the fragment to be re-exported by the host bundle. Now you can create a test bundle that imports the desired packages and therefore has access to the public types in the fragment.
This isn't as close as test-fragments where you benefit from tests and production code using the same class loader that gives access to package-private types and methods. But you can at least test through the publicly accessible means.
Note, however, that this header is specific to Eclipse PDE and not part of the OSGi specification. Hence you are tied to this development environment. Furthermore, the packages of the fragment will be exported through its host bundle and will be visible not only for the test bundle but for all bundles.
Java Library
If your fragment has few dependencies and doesn't require the OSGi/Eclipse runtime you could consider treating it as a plain Java library w.r.t tests. Another sibling Java project could contain tests and have a project-dependency (Properties > Java Build Path > Projects) on the fragment project. Again, access to package-private members would not work.
And if you use a build tool like Maven/Tycho, some extra work would be required to declare dependencies and execute these tests during the build.
Bndtools
You could also look into Bndtools to see if this development tool fits your needs better than the Eclipse Plug-in Development Environment (PDE).
Plain JUnit tests are held in a separate source folder in the same project as the production code. This would give your test code access to the production code in the same way as if test-fragments were used.
Bndtools also supports executing integration tests, though I doubt that you would have access to the fragment code other than through services or other API provided by the fragment.
For CI-builds, Bndtools projects usually use Maven or Gradle with the help of the respective bnd(http://bnd.bndtools.org/) plug-in. Just as Maven/Tycho is used to build and package PDE projects.
Since Bndtools is an IDE extension to develop OSGi bundles, it doesn't know about Eclipse plug-in specificities such as extensions declared in the plugin.xml. Hence there is no builder and editor for these artifacts. But if you are lucky, you may even be able to use the PDE builder to show error markers for invalid extensions and extension points.
Another downside that comes with having production- and test-code in the same project, is that pure test dependencies like JUnit, mock libraries, etc. are also visible for the production code at development time.
Of course, the produced (fragment) bundles do neither contain test code nor test dependencies.
However, Bndtools itself is developed with Bndtools. So there is proof that Bndtools can be used to write Eclipse plug-ins.

My jar won't add my junit tests

The contents of my jar file does not contain my junit tests. I tried creating a main class that calls my tests with "Junit Core" but that too doesn't get added to my jar file. What am I missing?
Your production package (your jar) is not supposed to contain the test code (your unit tests).
Test code is supposed to be invoked only when the tests are been executed.
You shouldn't do it, but if you want the test code to be included in your package just put it in the same root folder of your production code. Ex: if you are using Maven, your folders structure might be something like this:
project_name/src/main/java/
-> production code
project_name/src/test/java/
-> test code
In that case, change it to:
project_name/src/main/java/
-> production code
-> test code
Be aware that doing that you will have some problems, like the tests not executing during a normal build. We might help you better if you put a question asking how to accomplish your goal (what is your goal?).
Update based on the goal explained in the comments: Would be better if this tool (Silk Central) could run your tests using Maven or Ant, and I'm pretty sure it can.
I've been used different tools to run my Junit (or other XUnit frameworks) tests. What I do is to configure the tool to:
Get the source code from the version control.
Run the build/tests by calling Maven or Ant installed along the tool.
Read the Junit outputs.
Sometimes the tool has its own integration with Junit and you don't have even to use Maven or Ant.
I mean, your central build or tests tool should be able to run your tests just like you do in your own machine.
Take a look on this or search by "Silk Central junit" in the web:
http://community.microfocus.com/borland/test/silk_central/w/wiki/465.zero-maintenance-junit-testing-using-classpathsuite-in-sctm.aspx

Do not run a category of slow JUnit tests by default in Maven and every IDE (Eclipse, IntelliJ, ...) without an explicit TestSuite

I have a set of really slow tests, which take a week to run. (They literally run some code non-stop for about a week).
Naturally, no developer (or even the default build job) wants to run these tests. Only a specific, separate build job has the time to run them. So these tests needs to be disabled by default.
JUnit's categories seemed perfect for this: I annotated those slow tests with #Category(SlowTests.class). Problem is that they are still run because:
I don't want to maintain TestSuite classes because we add Tests on a daily basis. I have 0 TestSuite classes: Maven, IntelliJ and Eclipse just run all the Test classes from my module. Including all those slow tests.
Even if we had TestSuite classes, most of the open source contributors would still try to run all Test classes from IntelliJ or Eclipse, think it hangs and give up running tests. Those slow tests needs to be excluded by default. Preferably without any extra configuration in IntelliJ or Eclipse.
How do I exclude a category of slow JUnit tests by default without using an explicit TestSuite?
This works by default, in Maven, IntelliJ and Eclipse:
import static org.junit.Assume.assumeTrue;
#Test
public void mySlowTest() {
assumeTrue("true".equals(System.getProperty("runSlowTests")));
...
}
To run them anyway, simply add VM argument -DrunSlowTests=true.
Semantically speaking, it's totally wrong. But it works :)
As far as I know there is no way of preventing Eclipse from running certain tests by default.
Running certain categories from Maven is easy enough using
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12.4</version>
<configuration>
<excludedGroups>${tests.exclude}</excludedGroups>
</configuration>
</plugin>
And then define tests.exclude in certain maven profiles.
Maintaining test suites in JUnit is indeed too much work with the current version of JUnit as I've written about in a blogpost. I also explain how a library called cpsuite automatically does the Suite administration for you like this:
#RunWith(ClasspathSuite.class) // Loads all unit tests it finds on the classpath
#ExcludeBaseTypeFilter(SlowTest.class) // Excludes tests that inherit SlowTest
public class FastTests {}
However, in both methods, Eclipse by default will still just run all Java files with a #Test annotation in them.
Why not making Integration test out of slow running test. Using the maven-failsafe-plugin which would handle such cases via different naming conventions. For example *IT.java which are Themen long runnin test. Furthermore i would suggest to put the activation into a profilr so everyone can control to run those test or not which should be the default

Beginner: How to do JUnit tests on GWT application?

I want to preform a JUnit tests on my application. I've never done JUnit testing before so I have a couple of (maybe trivial) questions:
Where should I put a test class? I came across with this thread:
Where should I put my JUnit tests?,
and the guy that answers the question is referring to maven projects, but I don't use maven. He explains (in the thread I linked above) that he puts the test class in a different location but in the same package. How can it be done in a GWT project?
How should I execute these tests once they are ready (where in the code to put the execution)?
You should begin by reviewing this: Unit Testing GWT Applications with JUnit.
The other thread is good and reflects the typical JUnit practice, and isn't specific to maven: use a mirror of your package tree under a directory called test. So for instance if your GWT EntryPoint module is located in this directory structure:
project/src/com/myproject/mypackage/MyEntryPoint.java
Then your test code will be here:
project/test/com/myproject/mypackage/MyEntryPointTests.java
If you've created your GWT project using webAppCreator then you should already have a test directory containing the package structure as described.
If you use webAppCreator to create your project, the project can be created with unit testing built-in like so:
webAppCreator -junit -out MyProject com.myproject.mypackage.MyEntryPoint
This will create a test target. If you're using Eclipse, then you should have a Run selection for: Run As -> GWT Unit Test for running your tests.
If you're using ant instead of Eclipse then this should run your unit tests:
ant test
If you didn't use -junit to create the project, the test targets are typically still there, just commented out. Search junit in build.xml to find the targets, and un-comment them.
You need to take a look at this article, MVP1 and MVP2, these are a pattern designs used to Unit Test your application in pure java environment, because using GWT Test Case runs very slow the patterns also has many advantages like separate the logic from the view so you can change the view for Android, for example.

Are there disadvantages to setting up unit or integration tests in Eclipse as a separate project?

I'm currently working on a project using Eclipse where the unit and integration tests are in one project that also contains the DAO and service layer, and there is another project that includes the Web interface. The Web interface contains the Spring configuration files, and instead of duplicating them for the tests in the DAO project, I want to reference the ones that already exist. However, as I started thinking about it, if this is possible, why not just move them into their own project completely and setup project dependencies. Has anyone done this, and do you have an example of this setup, or can you provide some roadblocks you encountered?
I went ahead with this approach, and it doesn't appear to be causing any issues so far. One of our projects has a (classpath) dependency on the other, but the third test project is able to manage that with some setup and configuration.