Running Selenium JUnit tests from Jenkins

In this post I want to show you how to use Jenkins to automatically execute Selenium tests written in JUnit format, and how the results from these tests can be directly reported back to Jenkins. To achieve this, we need to complete the following steps:

  • Write some Selenium tests in JUnit format that we want to execute
  • Create a build file that runs these tests and writes the reports to disk
  • Set up a Jenkins job that runs these tests and interprets the results

Note: First of all a point of attention: I couldn’t get this to work while Jenkins was installed as a Windows service. This has something to do with Jenkins opening browser windows and subsequently not having suitable permissions to access sites and handle Selenium calls. I solved this by starting Jenkins ‘by hand’ by downloading the .war file from the Jenkins site and running it using java -jar jenkins.war

Creating Selenium tests to run
First, we need to have some tests that we would like to run. I’ve created three short tests in JUnit-format, where one has an intentional error for demonstration purposes – it’s good practice to see if any test defects actually show up in Jenkins! Using the JUnit-format implies that tests can be run independently, so there can’t be any dependencies between tests. My test class looks like this (I’ve removed two tests and all import statements for brevity):

package com.ontestautomation.selenium.ci;

public class SeleniumCITest {
	
	static WebDriver driver;
	
	@Before
	public void setup() {
		
		driver = new FirefoxDriver();
		driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);				
	}
	
	@Test
	public void successfulLoginLogout() {
		
		driver.get("http://parabank.parasoft.com");
		Assert.assertEquals(driver.getTitle(), "ParaBank | Welcome | Online Banking");
		driver.findElement(By.name("username")).sendKeys("john");
		driver.findElement(By.name("password")).sendKeys("demo");
		driver.findElement(By.cssSelector("input[value='Log In']")).click();
		Assert.assertEquals(driver.getTitle(), "ParaBank | Accounts Overview");
		driver.findElement(By.linkText("Log Out")).click();
		Assert.assertEquals(driver.getTitle(), "ParaBank | Welcome | Online Banking");
	}
	
	@After
	public void teardown() {
		driver.quit();
	}	
}

Pretty straightforward, but good enough.

Creating a build file to run tests automatically
Now to create a build file to run our tests automatically. I used Ant for this, but Maven should work as well. I had Eclipse generate an Ant build-file for me, then changed it to allow Jenkins to run the tests as well. In my case, I only needed to change the location of the imports (the Selenium and the JUnit .jar files) to a location where Jenkins could find them:

<path id="seleniumCI.classpath">
    <pathelement location="bin"/>
    <pathelement location="C:/libs/selenium-server-standalone-2.44.0.jar"/>
    <pathelement location="C:/libs/junit-4.11.jar"/>
</path>

Note that I ran my tests on my own system, so in this case it’s OK to use absolute paths to the .jar files, but it’s by no means good practice to do so! It’s better to use paths relative to your Jenkins workspace, so tests and projects are transferable and can be run on any system without having to change the build.xml.

Actual test execution is a matter of using the junit and junitreport tasks:

<target name="SeleniumCITest">
    <mkdir dir="${junit.output.dir}"/>
    <junit fork="yes" printsummary="withOutAndErr">
        <formatter type="xml"/>
        <test name="com.ontestautomation.selenium.ci.SeleniumCITest" todir="${junit.output.dir}"/>
        <classpath refid="seleniumCI.classpath"/>
        <bootclasspath>
            <path refid="run.SeleniumCITest (1).bootclasspath"/>
        </bootclasspath>
    </junit>
</target>
<target name="junitreport">
    <junitreport todir="${junit.output.dir}">
        <fileset dir="${junit.output.dir}">
            <include name="TEST-*.xml"/>
        </fileset>
        <report format="frames" todir="${junit.output.dir}"/>
    </junitreport>
</target>

This is generated automatically when you create your build.xml using Eclipse, by the way.

Running your tests through Jenkins
The final step is setting up a Jenkins job that simply calls the correct Ant target in a build step:
Ant build step
After tests have been run, Jenkins should pick up the JUnit test results from the folder specified in the junitreport task in the Ant build.xml:
JUnit report post build action
If everything is set up correctly, you should now be able to run your tests through Jenkins and have the results displayed:
Build result in Jenkins
You can also view details on the individual test results by clicking on the error message:
Error details in Jenkins

The Eclipse project I have used for this example can be downloaded here.

46 thoughts on “Running Selenium JUnit tests from Jenkins

  1. Scripts are running on jenkins but driver is not opened
    could you tell me the how to open the driver in jenkins

    • What does the console output for your job look like?

      Can you see any events in the Event Viewer (in case you’re running this under Windows)?

  2. I installed Jenkins as a Windows service. Managed to get the JUnit test running, but fail to load the report:

    Started by user anonymous
    Building on master in workspace C:\Program Files (x86)\Jenkins\jobs\SeleniumTest\workspace
    [SeleniumTest] $ cmd.exe /C ‘”C:\eclipse\plugins\org.apache.ant_1.9.2.v201404171502\bin\ant.bat -file build.xml FFAboutUsFooter && exit %%ERRORLEVEL%%”‘
    Buildfile: C:\Users\shahir\workspace\SeleniumTest\build.xml

    FFAboutUsFooter:
    [junit] Running FFAboutUsFooter
    [junit] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 50.635 sec
    [junit] Output:
    [junit] —-Starting the test for About Us (footer) page—-
    [junit] Page title is: | Homeware | Furniture | Fashion Accessories
    [junit] Clicked on Log in button
    [junit] Page title is: Login | Homeware | Furniture | Fashion Accessories
    [junit] Entered email: shtest1@mailinator.com
    [junit] Entered password: XXXXX
    [junit] Unchecked the Remember Me checkbox: false
    [junit] Clicked on: Log In
    [junit] Clicked on: About Us
    [junit] Breadcrumb: Company Profile About Us
    [junit] Hovered on: My
    [junit] Clicked on: Log Out
    [junit] —-The test for About Us (footer) page ended—-
    [junit]

    BUILD SUCCESSFUL
    Total time: 52 seconds
    Recording test results
    ERROR: Publisher hudson.tasks.junit.JUnitResultArchiver aborted due to exception
    hudson.AbortException: No test report files were found. Configuration error?
    at hudson.tasks.junit.JUnitParser$ParseResultCallable.invoke(JUnitParser.java:116)
    at hudson.tasks.junit.JUnitParser$ParseResultCallable.invoke(JUnitParser.java:92)
    at hudson.FilePath.act(FilePath.java:989)
    at hudson.FilePath.act(FilePath.java:967)
    at hudson.tasks.junit.JUnitParser.parseResult(JUnitParser.java:89)
    at hudson.tasks.junit.JUnitResultArchiver.parse(JUnitResultArchiver.java:121)
    at hudson.tasks.junit.JUnitResultArchiver.perform(JUnitResultArchiver.java:138)
    at hudson.tasks.BuildStepCompatibilityLayer.perform(BuildStepCompatibilityLayer.java:74)
    at hudson.tasks.BuildStepMonitor$1.perform(BuildStepMonitor.java:20)
    at hudson.model.AbstractBuild$AbstractBuildExecution.perform(AbstractBuild.java:770)
    at hudson.model.AbstractBuild$AbstractBuildExecution.performAllBuildSteps(AbstractBuild.java:734)
    at hudson.model.Build$BuildExecution.post2(Build.java:183)
    at hudson.model.AbstractBuild$AbstractBuildExecution.post(AbstractBuild.java:683)
    at hudson.model.Run.execute(Run.java:1743)
    at hudson.model.FreeStyleBuild.run(FreeStyleBuild.java:43)
    at hudson.model.ResourceController.execute(ResourceController.java:89)
    at hudson.model.Executor.run(Executor.java:240)
    Finished: FAILURE

    To install run .war file, do I need to uninstall the Jenkins as a Windows service first?

    • Hi Shahir,

      no I don’t think you need to completely uninstall the Jenkins service but I would stop it to prevent it from interfering with the .war version of Jenkins.

      Are the JUnit XML reports in the location where you told Jenkins to find them?

      • Hi Bas,

        Thanks for your quick reply.

        Under ‘Configure’ > ‘Post buld actions’ > ‘Publish JUnit test result report’ > ‘Test report XMLs’ field, I put the path as follows: **/junit/TEST-*.xml

        Which means it will take the report from the Jenkins job folder (eg: C:\Program Files (x86)\Jenkins\jobs\SeleniumTest\junit), am I right?

        During the Ant build file creation via Eclipse, I specified the output path to the folder above.

        But it still fail to load the report. Do I missed something here?

        Thanks

          • Another question.

            When the selenium script was triggered via Jenkins, why can’t I see the web browser being launched? Does it mean it will always run on ‘silent’ mode? Is there any setting to enable us to see the test being run?

          • I assume you’re not using the HtmlUnitDriver or the PhantomJSDriver?

            It could have something to do with the Jenkins service (assuming you’re running it as a service under Windows) not having the appropriate permissions to open a new window in the same session. In my case the only solution was to use the Jenkins .war instead of installing it as a service, but I don’t know whether that’s the issue on your side.

          • Hi Bas,

            I managed to get the Junit report loaded in Jenkins. Apparently, the path to publish the junit report (during ant build.xml creation) was wrong (C:\Program Files (x86)\Jenkins\jobs\SeleniumTest\junit).

            So, I corrected the file path to (C:\Program Files (x86)\Jenkins\jobs\SeleniumTest\workspace\junit) and run the build in Jenkins. Then only Jenkins managed to grab the Junit report and displayed it in web browser.

            Such a noob mistake!!
            Wasted a few hours googling around for solution..LOL

  3. Hi,

    What if I want to run the Selenium script hosted on a Jenkins slave? I have configured the slave and get it connected.

    How do I configure Jenkins so that it will run the build.xml that is on the slave machine and not my own machine?

    • Hi Shahir,

      you could for instance give your slave machine a specific label (under Manage Nodes in the Jenkins configuration) and in your job configuration specify that label under ‘Restrict where this job can be run’.

  4. Hi ,

    I’m trying to integrate Selenium with junit in Jenkins .Locally my test scripts are running fine with ant build.xml and also generating html results reports.

    Whereas when ran in Jenkins , test scripts are passing but html reports are not getting generated.Could you please help me sort this issue?

    Thanks

    • Hi Adit, could you double check your Jenkins job workspace to see whether the report is there yes or no? It could be that the report is generated but not picked up by Jenkins. If that’s all OK, check whether there are any absolute file paths in your build.xml. Those mess up things sometimes!

  5. Hi Bas, i am newbie to the Jenkins. Hope that you can assist me on the Jenkins configuration. And may i know, do i need to configure path in this file TEST-com.ontestautomation.selenium.ci.SeleniumCITest.xml?

    And how to solve below issues:

    build-project:
    [echo] seleniumCI: /var/lib/jenkins/workspace/seleniumCI/build.xml

    build:

    BUILD SUCCESSFUL
    Total time: 0 seconds
    Recording test results
    ERROR: Step ‘Publish JUnit test result report’ failed: Test reports were found but none of them are new. Did tests run?
    For example, /var/lib/jenkins/workspace/seleniumCI/junit/TEST-com.ontestautomation.selenium.ci.SeleniumCITest.xml is 1 yr 6 mo old

    • That XML file is the results file, no need to alter that. Judging from your error message either JUnit does not write the report (which I don’t think is very likely) or Jenkins is looking in the wrong folder for the XML test results. Are you able to locate the correct JUnit test result file by hand in your Jenkins job workspace folder?

      • thanks for your prompt response to this matter.

        JUnit test result file is able to access by hand which is stored in the server. But it is still getting error.

        Under Post-build Actions>Publish JUnit test result report>est report XMLs I fill it as **/junit/TEST-*.xml

        • And is the result file stored in that location? I.e., in the junit sub directory for your job, with the file name matching TEST-*.xml?

          • i copied file name exactly as per what u did sir, which is TEST-com.ontestautomation.selenium.ci.SeleniumCITest.xml.

            So under post-build action need to put as:
            a. **/reports/TEST-*.xml or
            b. target/***/TEST-*.xml or
            c. **/TEST-*.xml

            please advice

          • That depends on where your test execution step creates the report. Is that in a subfolder of your job workspace? If not, then c should work. If it goes into a subfolder reports, then a should be correct.

  6. ic understood..

    Meanwhile, from console output, what does it means by Test reports were found but none of them are new.. how to clear the old reports?

  7. Hi ,

    I’m trying to integrate Selenium with junit in Jenkins .Locally my test scripts are running fine with ant build.xml and also generating html results reports and the JUnit scenarios are passed.

    Whereas running through Jenkins, the Build is getting successful but the JUnit scenarios are getting failed.
    Please find below the Error messages:

    Scenario 1:
    —————————-
    @RegressionTest Scenario Outline: Login with Invalid Credentials
    org.openqa.selenium.WebDriverException: Failed to navigate to https://www.getlocalhealthplans.com/. This usually means that a call to the COM method IWebBrowser2::Navigate2() failed. (WARNING: The server did not provide any stacktrace information)
    Command duration or timeout: 15 milliseconds
    Build info: version: ‘2.45.0’, revision: ‘5017cb8’, time: ‘2015-02-26 23:59:50’
    System info: host: ‘XXXXXXXXX’, ip: ‘XXXXXXXXXX’, os.name: ‘Windows 7’, os.arch: ‘x86’, os.version: ‘6.1’, java.version: ‘1.7.0_15’
    Session ID: 1e26ddc0-5be1-427e-93ed-1a81bfc7255d
    Driver info: org.openqa.selenium.ie.InternetExplorerDriver
    Capabilities [{platform=WINDOWS, javascriptEnabled=true, elementScrollBehavior=0, ignoreZoomSetting=false, enablePersistentHover=true, ie.ensureCleanSession=false, browserName=internet explorer, enableElementCacheCleanup=true, unexpectedAlertBehaviour=dismiss, version=11, ie.usePerProcessProxy=false, ignoreProtectedModeSettings=false, cssSelectorsEnabled=true, requireWindowFocus=false, initialBrowserUrl=http://localhost:39436/, handlesAlerts=true, ie.forceCreateProcessApi=false, nativeEvents=true, browserAttachTimeout=0, ie.browserCommandLineSwitches=, takesScreenshot=true}]
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
    at org.openqa.selenium.remote.ErrorHandler.createThrowable(ErrorHandler.java:204)
    at org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:156)
    at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:599)
    at org.openqa.selenium.remote.RemoteWebDriver.get(RemoteWebDriver.java:304)
    at org.openqa.selenium.remote.RemoteWebDriver$RemoteNavigation.to(RemoteWebDriver.java:854)
    at integrationTestClass.Cucu_Steps_Code.loginScreen(Cucu_Steps_Code.java:40)
    at ✽.Given User is on Login Page(FeatureFile/TestFeature1.feature:5)

    Scenario 2:
    ————————
    org.openqa.selenium.UnhandledAlertException: Modal dialog present:
    Build info: version: ‘2.45.0’, revision: ‘5017cb8’, time: ‘2015-02-26 23:59:50’
    System info: host: ‘XXXXXXXXXX’, ip: XXXXXXXX’, os.name: ‘Windows 7’, os.arch: ‘x86’, os.version: ‘6.1’, java.version: ‘1.7.0_15’
    *** Element info: {Using=xpath, value=/html/body/div[1]/div/ul/li[1]/a}
    Session ID: 54c7d2ea-3da4-4171-b8df-d0ddc4ea060f
    Driver info: org.openqa.selenium.ie.InternetExplorerDriver
    Capabilities [{platform=WINDOWS, javascriptEnabled=true, elementScrollBehavior=0, ignoreZoomSetting=false, enablePersistentHover=true, ie.ensureCleanSession=false, browserName=internet explorer, enableElementCacheCleanup=true, unexpectedAlertBehaviour=dismiss, version=11, ie.usePerProcessProxy=false, ignoreProtectedModeSettings=false, cssSelectorsEnabled=true, requireWindowFocus=false, initialBrowserUrl=http://localhost:8979/, handlesAlerts=true, ie.forceCreateProcessApi=false, nativeEvents=true, browserAttachTimeout=0, ie.browserCommandLineSwitches=, takesScreenshot=true}]
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
    at org.openqa.selenium.remote.ErrorHandler.createThrowable(ErrorHandler.java:204)
    at org.openqa.selenium.remote.ErrorHandler.createUnhandledAlertException(ErrorHandler.java:185)
    at org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:152)
    at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:599)
    at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:352)
    at org.openqa.selenium.remote.RemoteWebDriver.findElementByXPath(RemoteWebDriver.java:449)
    at org.openqa.selenium.By$ByXPath.findElement(By.java:357)
    at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:344)
    at org.openqa.selenium.support.ui.ExpectedConditions.findElement(ExpectedConditions.java:730)
    at org.openqa.selenium.support.ui.ExpectedConditions.access$0(ExpectedConditions.java:728)
    at org.openqa.selenium.support.ui.ExpectedConditions$4.apply(ExpectedConditions.java:130)
    at org.openqa.selenium.support.ui.ExpectedConditions$4.apply(ExpectedConditions.java:1)
    at org.openqa.selenium.support.ui.FluentWait.until(FluentWait.java:208)
    at integrationTestClass.Cucu_Steps_Code.isElementLoaded(Cucu_Steps_Code.java:563)
    at integrationTestClass.Cucu_Steps_Code.login(Cucu_Steps_Code.java:49)
    at ✽.When User enters username as “nguyenq@aetna.com” and password as “Justin96″(FeatureFile/TestFeature1.feature:15)

    • Hi Sam,

      Are you running this on the same machine? Could it be that the browser is asking for proxy settings? This because of the UnhandledAlertException..

      • Hi Bas,

        Thanks for your reply. We are running the code in the same machine.
        The issue is resolved as of now. We have modified the code as mentioned below:

        try {
        click(myButton);
        } catch (UnhandledAlertException f) {
        try {
        Alert alert = driver.switchTo().alert();
        String alertText = alert.getText();
        System.out.println(“Alert data: ” + alertText);
        alert.accept();
        } catch (NoAlertPresentException e) {
        e.printStackTrace();
        }
        }

  8. Hi,

    Thanks for this wonderful post I have similar problem as others have mentioned.. I am trying to publish junit report and this is the location of my xml file(file name -cucumber.xml) within my Jenkins job –

    :C:\Jenkins\jobs\Project_Name\workspace\target\Junit

    And I specify in Jekins as follows: **/*cumber.xml

    When I run the test I get the following error:

    Recording test results
    ERROR: Step ‘Publish JUnit test result report’ failed: Test reports were found but none of them are new. Did tests run?
    For example, C:\Jenkins\jobs\Project_Name\workspace\target\Junit\cucumber.xml is 6 days 10 hr old

    • What happens if you delete that .xml file and run the test again? Is a new one created? I suspect that the actual report is written to a different location…

      • You are correct when I deleted the xml file and ran the test the file was not created. The error shown was :
        Recording test results
        ERROR: Step ‘Publish JUnit test result report’ failed: No test report files were found. Configuration error?
        Finished: FAILURE

        • That confirms that either Jenkins is looking in the wrong directory for the test results or that the test results are not created at all. Could you do a search on your machine for alternative locations where the XML report might have been created?

          • Hi,

            I searched my machine but I could only find the file from my project class path through eclipse but not within my Jenkins job.There seems to be something wrong with my configuration,any idea why I can’t see the report within Jekins directory in machine?

            Thanks

          • What matters is where you define the location for your JUnit reports. Do you do that in your pom.xml?

          • It’s specified in my CucumberOption plugin from the Runner class,thus gets created in target/Junit/testresult.xml
            But my worry is when I deleted it from Jenkins directory,it wasn’t created when I rerun the test as I mentioned earlier.

          • Yes I got that, my assumption is that is WAS recreated, just not at the location where Jenkins is supposed to pick it up. It’s a bit hard to debug from a distance though 😉

  9. Hi,

    Thanks for your help.I will try and run the build by getting the code from the repository and see if it makes any difference because the build running on my VM is getting the code from the repository and I don’t have any problem with the Junit test report getting published.

      • I resolved the issue by polling from SCM rather than from my local machine.

        I have another issue, some tests that pass in my local machine are failing in Jenkins what I mean is that if i run my test from my local machine and Jenkins respectively I have tests that will fail in Jenkins but pass in my local, some pass in both as well.

          • Ok,basically what happens is this.Not that the tests are not passing at all.Say I run 500 tests,eclipse might have just 3 failures due to synchronisation issue but Jenkins might have 100 failures and 100 tests will be skipped .And the error is usually element not found or element is removed from cache or not clickable but if I compare the result with eclipse most of the tests that fail in Jenkins would have passed in eclipse.

            Is this clear a bit?

          • So if you run your tests locally they run fine but from a build server they don’t? Looking at your description of the errors you might want to improve your error handling a bit. I’ve written a post on wrapper methods some time ago, maybe that one can give you some pointers?

  10. Thanks but my worry is why do the same tests pass in my local?isn’t it something to do with Jenkins server or some configuration.Some people say if Jenkins is being run as a window service that it may happen but I am not running Jenkins as a window service.

    • No, I don’t think it is caused by Jenkins running as a Windows service or not, because that would either result in no failed tests or all tests failing. The fact that SOME tests fail indicates that it is very likely a timing thing, something that you can try to handle by using better exception handling, for instance using wrapper methods.

Leave a Reply

Your email address will not be published. Required fields are marked *