There are three main categories of automated test used in Jenkins:
-
Unit tests, including mocking frameworks such as PowerMock.
-
Functional tests based on the JenkinsRule
API defined in jenkins-test-harness
.
-
Acceptance tests located in the acceptance-test-harness
repository.
These have different levels of fidelity to the class loading behavior of plugin code running in production Jenkins servers.
Unit tests simply pick up the Java classpath (java.class.path) defined by Maven’s test
scope.
Acceptance tests run a full Jenkins server and install plugins (including the plugin(s) being tested) using Jenkins’ normal mechanisms.
Since the test does not compile or link against any types defined in the Jenkins runtime (only against the Selenium web driver),
and does not even run in the same JVM as Jenkins, it has no interaction with the class loading of Jenkins.
Thus the class loading behavior of plugins running in an acceptance test can be assumed to be the same as in production.
Class loading in functional tests is intermediate in behavior, but closer to that of unit tests.
Test code does link against Jenkins core and (test
-scoped) plugin types,
and everything in the Java classpath is in fact loaded in Java’s application class loader—including plugins in test
scope.
This means that certain mistakes in plugin metadata (for example, misuse of pluginFirstClassLoader
) may go unnoticed.
(JenkinsRule
does start a real Jenkins service, and in some cases other plugins can get installed which were not in the Java classpath.
These get their own class loaders.)
Whenever there is any doubt about whether class loading behavior could affect plugin or core code,
use RealJenkinsRule
which launches Jenkins in a separate JVM with the regular class loader hierarchy.