Jenkins comes with a test harness built around JUnit to make test development simpler. This harness provides the following features:
The following code shows a very simple test case. Your test will use JenkinsRule to provide test fixtures for some of those features outlined above.
Each test method will start with a fresh temporary installation of Jenkins. The first method doesn't request any particular Jenkins dataset to seed Jenkins, so it will start from an empty installation.
The test then proceed to create a new project and set it up. As you can see, the code directly talks to the in-memory Jenkins object model. (There is the jenkins variable defined in JenkinsRule that you can use for access.) While you can do the same by emulating the user HTTP interaction through HtmlUnit, this way is often a convenient way to prepare an environment for the code that you want to test.
The test code in this example then switch to HtmlUnit to emulate the UI interaction and verify that we get results that we expect.
When a test completes, the temporary Jenkins installation will be destroyed.
When preparing your virtual test environment, you may wish to simulate Jenkins environment variables that can be set on the Jenkins configuration page. Adding environment variables to a Jenkins instance before a test is simple, as the example below demonstrates.
Your IDE would most likely have an ability of selecting a single JUnit test and execute it in the debugger. Otherwise you can run mvn -Dmaven.surefire.debug -Dtest=hudson.SomeTest test to run a test with the debugger.
To debug slaves launched by Jenkins, set -Dorg.jvnet.hudson.test.HudsonTestCase.slaveDebugPort=PORT to the system property, or from your test case set JenkinsRule.SLAVE_DEBUG_PORT to a non-0 value.
Sometimes you want to have quick tests which don't start up a 'full' Jenkins instance - as JenkinsRule does - as this can take some time. In that case you shouldn't have your test classes use JenkinsRule. (Or you can use @WithoutJenkins on certain methods.)
As creating most Jenkins core classes without a Jenkins instance is unfortunately not easy, mocking can come in handy. One excellent mocking framework is e.g. Mockito. For example, if you want to mock a build with a certain result you could do:
See Mocking in Unit Tests for more info.
If you'd like to test the HTML generated by Jenkins, XPath test is often convenient.
So you'd have to look for the corresponding HtmlButton element, then use that to call the submit method, like this:
The original HtmlUnit doesn't really do a good job of chaining all exceptions together, so we are patching HtmlUnit to make sure it retains the full stack trace leading up to the root cause. If you found a case where this chain is broken, please file a bug.
This test ensures that your configuration page is properly pre-populated with the current setting of your model object, and it also makes sure that the submitted values are correctly reflected on the constructed model object. To be really sure, do this twice with different actual values — for example, you should try a non-null string and null string, true and false, etc., to exhaust representative cases.
HtmlUnit has a WebAssert class that can be used for simple assertions on HTML pages.
To assert that the System configuration page contains the CVS SCM configuration entry:
To find Elements by name= vs. id=, use page.getElementsByName.
An example from the ironmqNotifier plugin.
See note on pom.xml below if this example gives you ClassNotFound errors.
When changing from 1.625.1 to 1.625.2, there appears to be a difference in the support library for HtmlPage.
When parsing pages for Number (Long or Integer), you may get the following error:
The supporting library appears to need HtmlNumberInput instead of HtmlTextInput to function correctly with numbers.
Make the following change...
Note; If you wish to move back to a version prior to 1.625.2, you will need to modify your Tests as the previous library associated with HtmlPage will not recognize HtmlNumberInput as part of the class.
TestCase as an RootAction
Instance of the test case being executed is added to Jenkins' URL space as /self because JenkinsRule is itself a RootAction. Among other things, this enables your test class to define Jelly views, and invoke it like j.createWebClient().goTo("self/myview").
Unit test harness contains a SecurityRealm implementation suitable for unit tests. This can be installed to as follows:
This virtual security realm allows login attempt by any user names so long as its password is exactly the same as the user name. WebClient.login method provides a convenient method that allows you to login a session object.
You can extend TestBuilder to write a one-off builder that can coordinate with your test. This is often convenient to stage things up for testing your Publisher, for example by placing files in the workspace, etc.
OneShotEvent is also often an useful companion so that the thread that runs your test method and the thread that runs the build can coordinate — for example, the following program have the main thread block until a build starts.
During the test, one might want to register extensions just during that particular test, for example to assist the test scenario. You can do this by defining such extension as a nested type of your test case class and put TestExtension instead of Extension.
It lets you tie an extension to just one test method, or all test methods on the same class.
See Unit Test on Windows.
There are several annotations in the Jenkins test framework.
Related issue id in tracker.
Production classes that tests are related to. Useful when the relationship between the test class name and the test target class is not obvious.
URL to the web page indicating a problem related to this test case.
URL to the e-mail archive. Look for the e-mail in http://jenkins.361315.n4.nabble.com/Jenkins-users-f361316.html or http://jenkins.361315.n4.nabble.com/Jenkins-dev-f387835.html
The specified class will be used to set up the test environment using HudsonTestCase.
Runs a test case with a data set local to test method or the test class.
This recipe allows your test case to start with the preset HUDSON_HOME data loaded either from your test method or from the test class.
Search is performed in this specific order. The fall back mechanism allows you to write one test class that interacts with different aspects of the same data set, by associating the dataset with a test class, or have a data set local to a specific test method.
The choice of zip and directory depends on the nature of the test data, as well as the size of it.
Runs a test case with one of the preset HUDSON_HOME data set:
Installs the specified plugin before launching Jenkins in the test. For now, this has to be one of the plugins statically available in resources "/plugins/NAME".
Runs a test case without create and tear down a Jenkins instance.
Runs a test case with the given timeout expressed in seconds.
HudsonTestCase is available for JUnit 3 tests. The functionality is similar to JenkinsRule.
When seeing the following error : java.lang.NoClassDefFoundError: org/hamcrest/MatcherAssert when running mvn:test if you are using WebPage Assertions per the above example.
It may be necessary to add org.hamcrest / hamcrest-all to your pom.xml file to avoid a matcher error. The cause is not yet know but may allow you to continue to learn how to create appropriate tests.
Skip to end of metadata Go to start of metadata