A very basic web service test tool

For those of us involved in testing web services and SOA-based applications, there are lots of different test tools on the market that can help speed up the testing and make them repeatable and easy to maintain. Some examples of these tools are SoapUI from SmartBear and SOAtest from Parasoft. SoapUI is available both as a freeware product and as an enterprise edition offering additional functionality. SOAtest is only available in a paid version.

One of the biggest downsides of the freeware version of SoapUI is the lack of data driven test support. This feature is only available in the paid version. In a previous post I introduced a simple way of implementing data driven testing in Selenium Webdriver tests, using Microsoft Excel sheets as the test data container format. As I am very regularly involved in web service testing myself, and often want to use data driven testing to create maintainable and flexible test suites, I thought it would be a good idea to see whether it’s possible to quickly create a very basic web service testing tool that supports data driven testing.

The test data source
As in the previous example, let’s create a test data source first. I chose to base the solution presented here on predefined XML request message files as this saves us the trouble of creating XML objects in our code. There are obvious downsides to this, of course, but for now we will focus on the ability to call a web service and subsequently capture and validate the result.

Our test data source looks like this:

webservice_test_data_source

It contains columns to identify the current test case, the path to the XML file containing the SOAP message to be sent and the endpoint to which the message should be sent. The last two columns contain the name of an element in the web service response we would like to validate and its expected value, respectively.

Reading our test data source
In our very basic web service test tool, we will process this Excel sheet just as we did in the Selenium example posted earlier. For every test data row, we will then execute the following steps:

  • Create a SOAP request from the XML file
  • Send the SOAP request to the right web service endpoint and capture the response
  • Extract the value from a response message element and compare it to the expected value

Create a SOAP request from the XML file
This is an easy step, as all we need to do is open the file, read all of its contents and transform it into a SOAP message object:

private static SOAPMessage createSOAPRequest(String strPath) throws Exception {
        
    // Create a SOAP message from the XML file located at the given path
    FileInputStream fis = new FileInputStream(new File(strPath));
    MessageFactory factory = MessageFactory.newInstance();
    SOAPMessage message = factory.createMessage(new MimeHeaders(), fis);
    return message;
}

Send the SOAP request to the right web service and capture the response
This is fairly straightforward as well and can be done using standard Java methods:

private static SOAPMessage getSOAPResponse(SOAPMessage soapRequest, String strEndpoint) throws Exception, SOAPException {
    	
    // Send the SOAP request to the given endpoint and return the corresponding response
    SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance();
    SOAPConnection soapConnection = soapConnectionFactory.createConnection();
    SOAPMessage soapResponse = soapConnection.call(soapRequest, strEndpoint);
    return soapResponse;	
}

Validating elements from the response message
Finally, we will parse the response message and validate the value of one of its elements. The validation result is sent to the stdout:

private static void validateValue(SOAPMessage soapMsg, String strEl, String strExpected) throws Exception {
    	
    // Get all elements with the requested element tag from the SOAP message
    SOAPBody soapBody = soapMsg.getSOAPBody();
    NodeList elements = soapBody.getElementsByTagName(strEl);
        
    // Check whether there is exactly one element with the given tag
    if (elements.getLength() != 1){
        System.out.println("Expected exactly one element " + strEl + "in message, but found " + Integer.toString(elements.getLength()));
    } else {
        // Validate the element value against the expected value
        String strActual = elements.item(0).getTextContent();
        if (strActual.equals(strExpected)) {
        	System.out.println("Actual value " + strActual + " for element " + strEl + " matches expected value");
        } else {
        	System.out.println("Expected value " + strExpected + " for element " + strEl + ", but found " + strActual + " instead");
        }
    }
}

Running the test
When we run the test, we see that the web service to be tested is called three times. Two tests succeed, the last test case fails (on purpose, to show that the validation is executed properly):

webservice_console_output

Extensions to our tool
As stated earlier in this post, there are a lot of improvements to be made to this very basic web service test tool. For instance, we could add:

  • Dynamic request message generation based on a template and data source values
  • XSD validation for the response messages
  • Support for non-SOAP-based (or plain XML) web services or even for transport protocols other than HTTP

Some of these improvements will probably be featured in later articles at ontestautomation.com. For questions or suggestions on topics to be covered on this blog, please do not hesitate to contact me at bas AT ontestautomation.com or leave a reply through the comment form below.

An example Eclipse project using the pattern described above can be downloaded here.

71 thoughts on “A very basic web service test tool

  1. Your explanation is up to the mark and very easy to understand.
    I will surely recommend this site to everyone learning to use Automation

  2. Yes, I agree with Yogesh…your delivery is impeccable!

    I notice you run many of your examples from Main(). Is that something you practice in production or just here to simplify the examples? We use Selenium Webdriver within the JUnit framework, so we have a testRunner that executes each case. I wonder if this has implications for some of these topics.

    Also, we’re using Excel as well to implement a more data-driven approach…I would imagine you create a class to encapsulate data access layer of your test suite…are there any best practices around this? Thanks!

    • Thanks again!

      I run tests from a main method because it’s the easiest way to explain a concept without having to explain a complete framework that would have been built around it. It’s not something I’d do in practice, I’d use a testrunner of some sorts as you do.

      The same goes for using Excel to separate your test data from your test execution code. In the example I kind of threw it all in the main method for brevity and ease of use, but in practice I’d create a separate class that would handle access to the test data (be it in Excel, a database or any other test data store). I didn’t find that many information on using Excel in combination with Selenium for data driven testing, so I’m not sure whether there are any established best practices around this, and I wouldn’t call my own approach a best practice (yet..). When I look at the hit counts for this post we’re surely not the only ones interested in this, so I might dive into this a little deeper in the future.

      Thanks for your suggestions!

  3. Hi,

    I am unable to run your sample code which is in the first page of your blog.
    Its showing java.lang.Exceptions such as
    1.method runTest shoud not be static and
    2.method runTest should have no parameters.

    • Hi Sneha,

      which code sample are you referring to? I had a look again at the code attached to this post and it worked perfectly fine for me..

      I’d be happy to correct any errors I might have made, but I need to know where I have to look..

      Thanks again!

  4. Hi,

    Thanks for sharing above code.
    I have one problem, for my web service i need to authenticate http request.
    I tried with adding auth header in saop request but its not working.I tried with 64 bit encryption and without encryption also but auth header is not working.

    Here the error displayed

    Request SOAP Message = ICW_CONFIG_NXTGE.genC0nf1gUserCFA356AE-1A01-4043-8SERVICE-UI-TEST6340558VALIDATEALLLISTPRICEtrueALL-ERRORCONFIGPATHALLOW_NON_WEB_ORDERABLEcabrennan32T26559SAN JOSECA95134USGlobal Price List – USUSDGlobal Price List US AvailabilityResaleUSAuto-Attach22829999HOSTED-BUNDLECONFIGURABLE10.0trueHOSTED-BUNDLEUSER22830000IPCH-MULTICHANCONFIGURABLE10.0falseHOSTED-BUNDLE:APPSWIND:5:APPSWINDNAME|IPCH-MULTICHAN#IPCCE-MODELUSERUS32003785CON-SES4-IPCHMULTSERVICE10.0SES412SERVICE177983495IPCH-ACOL-AGT-LNONCONFIGURABLE11500.0IPCCE-MODEL:AGENT_LICENSES|IPCH-ACOL-AGT-LUSER32003783CON-SES4-HACOLASERVICE10.0SES412SERVICE32003784UCSS-U-AWEB-1-1SUBSCRIPTION10.0UCSS12PRODUCT177983496IPCE-MC-KIT-43-K8NONCONFIGURABLE10.0IPCCE-MODEL:IPCE_MC_KIT_OPT|IPCE-MC-KIT-43-K8USER22830001ICMH-PG-AGENTSCONFIGURABLE10.0falseHOSTED-BUNDLE:ICM HOSTED:5:ICM HOSTEDNAME|ICMH-PG-AGENTS#ICME-MODELUSERUS32003788CON-NLSW-ICMHPGALSERVICE10.0NLSW12SERVICE177983497ICMH-PG-00NONCONFIGURABLE150000.0ICME-MODEL:SELECTACDTYP|ICMH-PG-00USER32003786CON-NLSW-ICH-PG00SERVICE10.0NLSW12SERVICE32003787UCSS-U-ICME-PG-1-1SUBSCRIPTION10.0UCSS12PRODUCT22830002IPCE-BUNDLECONFIGURABLE10.0trueIPCE-BUNDLEUSER22830004IPCE-SVRCONFIGURABLE115000.0falseIPCE-BUNDLE:APPSWIND:5:APPSWINDNAME|IPCE-SVR#IPCCE-MODELUSERUS32003789CON-SES4-IPESVRSERVICE10.0SES412SERVICE177983498CCBU-LICENSENONCONFIGURABLE10.0IPCCE-MODEL:CHASSIS_EXPANSIONS|CCBU-LICENSESYSTEM22830005IPCE-NPSENT-CPCONFIGURABLE10.0falseIPCE-BUNDLE:LAB:5:LABNAME|IPCE-NPSENT-CP#IPCCE-MODELUSERUS32003790CON-SES4-IPCENPCPSERVICE10.0SES412SERVICE177983499CCEH-MEDIA100-K9NONCONFIGURABLE1100.0IPCCE-MODEL:IPCE_NPS_MEDIA_OPT|CCEH-MEDIA100-K9USER177983500CUIC-V-LAB-PAKNONCONFIGURABLE10.0IPCCE-MODEL:CHASSIS_EXPANSIONS|CUIC-V-LAB-PAKSYSTEM177983501CVP-90-BNDL-NFRNONCONFIGURABLE10.0IPCCE-MODEL:CHASSIS_EXPANSIONS|CVP-90-BNDL-NFRSYSTEM22830006ICME-PGCONFIGURABLE10.0falseIPCE-BUNDLE:OPTIONS:5:OPTIONSNAME|ICME-PG#ICME-MODELUSERUS32003792CON-NLSW-ICEPGSERVICE10.0NLSW12SERVICE177983502CCBU-LICENSENONCONFIGURABLE10.0ICME-MODEL:ICMEEXPANSION|CCBU-LICENSESYSTEM177983503ICME-PG-01NONCONFIGURABLE150000.0ICME-MODEL:ACDTYPES|ICME-PG-01USER32003791CON-NLSW-ICE-PG01SERVICE10.0NLSW12SERVICE
    Sep 01, 2014 3:06:04 PM com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnection post
    SEVERE: SAAJ0009: Message send failed
    Error occurred while sending SOAP Request to Server
    com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: Message send failed
    at com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnection.call(Unknown Source)
    at ModifiedService.main(ModifiedService.java:35)
    Caused by: com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: Message send failed
    at com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnection.post(Unknown Source)
    … 2 more
    Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.ssl.Alerts.getSSLException(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.fatal(Unknown Source)
    at sun.security.ssl.Handshaker.fatalSE(Unknown Source)
    at sun.security.ssl.Handshaker.fatalSE(Unknown Source)
    at sun.security.ssl.ClientHandshaker.serverCertificate(Unknown Source)
    at sun.security.ssl.ClientHandshaker.processMessage(Unknown Source)
    at sun.security.ssl.Handshaker.processLoop(Unknown Source)
    at sun.security.ssl.Handshaker.process_record(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
    at sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(Unknown Source)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(Unknown Source)
    … 3 more
    Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.validator.PKIXValidator.doBuild(Unknown Source)
    at sun.security.validator.PKIXValidator.engineValidate(Unknown Source)
    at sun.security.validator.Validator.validate(Unknown Source)
    at sun.security.ssl.X509TrustManagerImpl.validate(Unknown Source)
    at sun.security.ssl.X509TrustManagerImpl.checkTrusted(Unknown Source)
    at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source)
    … 15 more
    Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(Unknown Source)
    at java.security.cert.CertPathBuilder.build(Unknown Source)
    … 21 more

    CAUSE:

    com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: Message send failed
    at com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnection.post(Unknown Source)
    at com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnection.call(Unknown Source)
    at ModifiedService.main(ModifiedService.java:35)
    Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.ssl.Alerts.getSSLException(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.fatal(Unknown Source)
    at sun.security.ssl.Handshaker.fatalSE(Unknown Source)
    at sun.security.ssl.Handshaker.fatalSE(Unknown Source)
    at sun.security.ssl.ClientHandshaker.serverCertificate(Unknown Source)
    at sun.security.ssl.ClientHandshaker.processMessage(Unknown Source)
    at sun.security.ssl.Handshaker.processLoop(Unknown Source)
    at sun.security.ssl.Handshaker.process_record(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
    at sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(Unknown Source)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(Unknown Source)
    … 3 more
    Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.validator.PKIXValidator.doBuild(Unknown Source)
    at sun.security.validator.PKIXValidator.engineValidate(Unknown Source)
    at sun.security.validator.Validator.validate(Unknown Source)
    at sun.security.ssl.X509TrustManagerImpl.validate(Unknown Source)
    at sun.security.ssl.X509TrustManagerImpl.checkTrusted(Unknown Source)
    at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source)
    … 15 more
    Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(Unknown Source)
    at java.security.cert.CertPathBuilder.build(Unknown Source)
    … 21 more

    CAUSE:

    javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.ssl.Alerts.getSSLException(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.fatal(Unknown Source)
    at sun.security.ssl.Handshaker.fatalSE(Unknown Source)
    at sun.security.ssl.Handshaker.fatalSE(Unknown Source)
    at sun.security.ssl.ClientHandshaker.serverCertificate(Unknown Source)
    at sun.security.ssl.ClientHandshaker.processMessage(Unknown Source)
    at sun.security.ssl.Handshaker.processLoop(Unknown Source)
    at sun.security.ssl.Handshaker.process_record(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
    at sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(Unknown Source)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(Unknown Source)
    at com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnection.post(Unknown Source)
    at com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnection.call(Unknown Source)
    at ModifiedService.main(ModifiedService.java:35)
    Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.validator.PKIXValidator.doBuild(Unknown Source)
    at sun.security.validator.PKIXValidator.engineValidate(Unknown Source)
    at sun.security.validator.Validator.validate(Unknown Source)
    at sun.security.ssl.X509TrustManagerImpl.validate(Unknown Source)
    at sun.security.ssl.X509TrustManagerImpl.checkTrusted(Unknown Source)
    at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source)
    … 15 more
    Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(Unknown Source)
    at java.security.cert.CertPathBuilder.build(Unknown Source)
    … 21 more

    CAUSE:

    com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: Message send failed
    at com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnection.post(Unknown Source)
    at com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnection.call(Unknown Source)
    at ModifiedService.main(ModifiedService.java:35)
    Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.ssl.Alerts.getSSLException(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.fatal(Unknown Source)
    at sun.security.ssl.Handshaker.fatalSE(Unknown Source)
    at sun.security.ssl.Handshaker.fatalSE(Unknown Source)
    at sun.security.ssl.ClientHandshaker.serverCertificate(Unknown Source)
    at sun.security.ssl.ClientHandshaker.processMessage(Unknown Source)
    at sun.security.ssl.Handshaker.processLoop(Unknown Source)
    at sun.security.ssl.Handshaker.process_record(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
    at sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(Unknown Source)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(Unknown Source)
    … 3 more
    Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.validator.PKIXValidator.doBuild(Unknown Source)
    at sun.security.validator.PKIXValidator.engineValidate(Unknown Source)
    at sun.security.validator.Validator.validate(Unknown Source)
    at sun.security.ssl.X509TrustManagerImpl.validate(Unknown Source)
    at sun.security.ssl.X509TrustManagerImpl.checkTrusted(Unknown Source)
    at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source)
    … 15 more
    Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(Unknown Source)
    at java.security.cert.CertPathBuilder.build(Unknown Source)
    … 21 more

    CAUSE:

    javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.ssl.Alerts.getSSLException(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.fatal(Unknown Source)
    at sun.security.ssl.Handshaker.fatalSE(Unknown Source)
    at sun.security.ssl.Handshaker.fatalSE(Unknown Source)
    at sun.security.ssl.ClientHandshaker.serverCertificate(Unknown Source)
    at sun.security.ssl.ClientHandshaker.processMessage(Unknown Source)
    at sun.security.ssl.Handshaker.processLoop(Unknown Source)
    at sun.security.ssl.Handshaker.process_record(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
    at sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(Unknown Source)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(Unknown Source)
    at com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnection.post(Unknown Source)
    at com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnection.call(Unknown Source)
    at ModifiedService.main(ModifiedService.java:35)
    Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.validator.PKIXValidator.doBuild(Unknown Source)
    at sun.security.validator.PKIXValidator.engineValidate(Unknown Source)
    at sun.security.validator.Validator.validate(Unknown Source)
    at sun.security.ssl.X509TrustManagerImpl.validate(Unknown Source)
    at sun.security.ssl.X509TrustManagerImpl.checkTrusted(Unknown Source)
    at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source)
    … 15 more
    Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(Unknown Source)
    at java.security.cert.CertPathBuilder.build(Unknown Source)
    … 21 more

    CAUSE:

    javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.ssl.Alerts.getSSLException(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.fatal(Unknown Source)
    at sun.security.ssl.Handshaker.fatalSE(Unknown Source)
    at sun.security.ssl.Handshaker.fatalSE(Unknown Source)
    at sun.security.ssl.ClientHandshaker.serverCertificate(Unknown Source)
    at sun.security.ssl.ClientHandshaker.processMessage(Unknown Source)
    at sun.security.ssl.Handshaker.processLoop(Unknown Source)
    at sun.security.ssl.Handshaker.process_record(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
    at sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(Unknown Source)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(Unknown Source)
    at com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnection.post(Unknown Source)
    at com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnection.call(Unknown Source)
    at ModifiedService.main(ModifiedService.java:35)
    Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.validator.PKIXValidator.doBuild(Unknown Source)
    at sun.security.validator.PKIXValidator.engineValidate(Unknown Source)
    at sun.security.validator.Validator.validate(Unknown Source)
    at sun.security.ssl.X509TrustManagerImpl.validate(Unknown Source)
    at sun.security.ssl.X509TrustManagerImpl.checkTrusted(Unknown Source)
    at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source)
    … 15 more
    Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(Unknown Source)
    at java.security.cert.CertPathBuilder.build(Unknown Source)
    … 21 more

    • Hi Laxman,

      thank you for your comment. From a quick look at the stack trace you posted it seems like you need an SSL certificate installed in order to be able to communicate with the web service.

      Are you testing against a publicly available web service? If so, I’d love to take a closer look. Please send me the web service endpoint and an example XML request so I can do that.. If you do’t want to post those here just send them to me on bas@ontestautomation.com.

      Thanks.

      • Hi Bas,

        Great post, i’m also interested in get the web services tested whilst using a certificate. Did you manage to provide an answer to laxman’s question? If so please can I have it?

        Thanks

        Omar

  5. Hi Bas, I am exploring Webservice automation using Selenium, while searching through Google I landed into your post. This is really great post and easy to understand.

    I downloaded the files and try executing it, as the zip do not contain XML files when i execute eclipse is showing “request_01.xml (The system cannot find the file specified)” could you please upload the xml files as well?

    Thanks,Prasad

  6. I want to know the above code this post is for SOAP UI for we call from Selenium. Because we wrote groovy script in saop ui but this is not useful. So where we can write above code and how can automate response and validate

    • Hi Surender,

      I’m not sure I understand what you want exactly. You could easily use the code above to add simple SOAP testing to your existing (Java) Selenium-based framework. How this is done exactly depends on your specific framework implementation.

  7. Hi Bas,
    I am not talking about this post but the next one-reading data from excel using apache poi ok?
    4 things:
    1)This not working in excel 2007.
    2)Warning-wb is never used.
    3)which apache poi to download?
    i downloaded poi-3.12 version ok?
    4)It worked when i saved Excel 2007 as Excel 2003 but the output in console showed this in red line along with the Excel Data.
    Jul 23, 2015 1:21:37 PM com.gargoylesoftware.htmlunit.javascript.host.html.HTMLElement addBehavior
    WARNING: Unimplemented behavior: #default#userdata
    5)I think there is a need to put two space in between in the third column of your excel data like this-Ferrari – Google Search.

    • Hi Sherin,

      1) For Excel 2007 and up you need to use the XSSF** classes instead of HSSF**. This is because Office documents from 2007 up are stored differently.
      2) I didn’t get that warning (otherwise I would have fixed it, I am a tester and I hate warnings 🙂 )
      3) That’s fine.
      4) That’s a warning thrown by the HtmlUnitDriver I guess, no idea what that means
      5) That might have something to do with the browser language settings. Other than that, I don’t know, it found a match on my machine. And anyway, it’s just an example.

  8. Hi Bas,
    🙂 i red the warning message wrong 🙂
    it was resource leakage close wb.
    i wrote wb.close before fis.close and it worked.
    you are right.The warning was because of issue of htmlunitsriver.
    It was resolved when i gave:
    WebDriver driver=new HtmlUnitDriver(BrowserVersion.FIREFOX_24)

  9. Hi Bas,
    This article is awesome , Thanks.
    Hope that will going to help me for my purpose

    I have some complex xmls (containing some credentials and various tags), with secured endpoints(https) …

    If you worked on your future scope (Extensions) please give us link. 🙂

    • Hi Chetan, thanks for the kind words. Will do! Still looking for a suitable library that lets me do everything with SOAP over HTTP services that I can do with REST Assured for RESTful services.

  10. Hi bas.

    Its helped me a lot and its easy to understand also.

    While validating elements I got one problem,
    could you please explain how to validate multiple values ?

    And also Is there any a way to print an entire request xml which will get after triggering into end point?

    • Hi Anil,

      thanks for your comment. To be honest, I don’t really like my own solution anymore and would recommend anyone using a tool such as REST Assured or SoapUI for testing web services. I’ll try and answer your questions anyway, though!

      When you want to validate more than one response, one approach you could try is to simply add more columns to the Excel sheet and loop through them (for example until you encounter an empty column) when executing a test case.

      As for your other question, do you mean you want to print the response XML that is returned by the web service? This page gives some example on how to serialize a SOAPMessage to a String.

  11. Hi Bas, You explanation is really good, however i am pondering how making code changes for WS Testing differ from SOAP UI ?

    Could you please provide me info when should we consider Soap UI for webservice testing and Writing pure Java code ?

    • Hi Vipin,

      SoapUI is a perfectly suitable option if you’re testing web services. However, if your test cases have other types of tests as well (UI tests, database validations) that you want to combine in a single test framework, then you might want to build something yourself. For example by using the code I included in this post, or even better by using a tool such as REST Assured if you’re testing RESTful services.

      • Hi Bas, Thanks Much for your comments.
        I am working in SOA architecture where i use to validate my service using SOAP UI and then manually validate the response with DB. Is it possible to completely automate this entire steps in single shot ? i am completely new in WS testing

        • Hi Vipin,

          calling a web service and then doing a check on database level will always require two separate steps in your automated test, if only because two different connections need to be set up (one to the web service using HTTP, one to the database using JDBC). You can easily combine those two in a single test scenario though, and that can be done using SoapUI.

    • Hi Nithya,

      could you please post a question like this under the relevant post? This has nothing to do with web services.. Also, without any concrete URLs or examples there’s no way I can give you a meaningful example..

  12. Hi Bas,

    Good post and good explanation. When I executed your code, I got the following error.

    soap:ClientServer did not recognize the value of HTTP Header SOAPAction: .
    Expected exactly one element Cityin message, but found 0

    Could you please help me with this?

    Regards
    Guruprasad

    • I think you need to specify a SOAPAction explicitly now (which wasn’t the case when I created the post). Please, instead of

      SOAPMessage message = factory.createMessage(new MimeHeaders(), fis);

      try

      MimeHeaders mimeHeaders = new MimeHeaders();
      headers.addHeader(“SOAPAction”, “http://ws.cdyne.com/WeatherWS/GetCityWeatherByZIP”);
      SOAPMessage message = factory.createMessage(mimeHeaders, fis);

      I haven’t tested it (yet) but I think it might just work..

      • Hi bas,

        Yup it worked. Now i am able to get the correct response from the web service. Apart from this I also came across a bit of code with which we can print the SOAP response. Hope it is useful!!!

        public static void printSOAPMessage(SOAPMessage message)
        {
        try
        {
        TransformerFactory tff = TransformerFactory.newInstance();
        Transformer tf = tff.newTransformer();
        tf.setOutputProperty(OutputKeys.INDENT, “yes”);
        tf.setOutputProperty(“{http://xml.apache.org/xslt}indent-amount”, “2”);
        Source sc = message.getSOAPPart().getContent();
        StreamResult result = new StreamResult(System.out);
        tf.transform(sc, result);
        System.out.println();
        }
        catch(Exception e)
        {
        System.out.println(“Error while displaying the SOAP message”);
        e.printStackTrace();
        }
        }

        This can be invoked by passing the response that will be generated by getSOAPResponse method.

        Regards
        Guruprasad

  13. Hello Bas,

    I am working with web services QA. we have multiple loops in the wsdl.
    Do you suggest SOAP ui tool OR parasoft tool.

    • What do you mean by loops in the WSDL? I am personally pretty happy with Parasoft SOAtest for testing web services, but it all depends on requirements and budget.

  14. Hello Bas,

    Indeed an awesome and simple explanation for any one to understand simple web services automation.

    I have one scenario where we have mixture of SOAP and restful web services to be automated for around 120 APIs. We are using Java with Axis (for SOAP) and restful APIs (for REST) testing. Is there any better approach or tools which we can try for such a scenario.

    Appreciate your time in helping all of us with the issues and ideas. Many Thanks 🙂

  15. Hi Bas,

    I had a query. Hope you would be able to help.
    I am testing an application(A) which in turn is communicating with an application(B). We are writing automated tests to automate A and are using a stub for B. Now B is a HTTP POST webservice to which I am sending a JSON request and expecting a JSON response. We do not want to automated B which is a stub. From what I have been researching on net I am getting 2 approaches. First, I need to use a Java API to created an automated test framework. This looks like heavy coding and all. The second is that I just need to create a JAVA method to send an http request and read the response. Could you help clarify and help me started. A sample code would be great.

    Regards

    • Hey Mayank,

      I’m not sure I understand what you’re asking. Isn’t B automatically invoked when you test A? You said you didn’t want to invoke B directly with an automated test, why would you need an automated testing approach then?

      If you want to make calls to a RESTful API directly I recommend REST Assured, to be found at http://rest-assured.io

      Please clarify..

      • Hey Bas, Thanks for responding.

        B would have been automatically invoked, but since we would not have B in our Test environment we are using a stub for B which would NOT be automatically invoked.
        We through our automated test have to invoke B (which is REST webservice). And read the response.
        Our primary goal is to just to send the request to this webservice and read the response. (Not a full-fledged automated test for this webservice).
        So I want to understand, if i can fulfill my purpose just by writing JAVA method\function
        or will I have to use a JAVA API (or something like REST Assured which you have mentioned)?

        • Ah, now I understand. Thanks for clarifying.

          In my opinion it’s always better to use a predefined API than writing your own method to handle this. There are lots of libraries that can handle REST request/response calls for you, and I like the simple interface that REST Assured provides. Check it out and see if it works for you.

      • And just to clarify, we are writing Automated tests for application A and communicating with B is just a pre-requisite.

        • Sure. But wouldn’t it be possible to configure your application A to communicate with the stub directly? That’s what stubbing and service virtualization is all about…

          • I think I have an idea. Will try that.
            The thing is I am new to automation and have no idea what stubbing is and am trying to find my way around it. And wanted to know where to start 🙂
            Thanks again.

    • Hey Anthony, here’s the list of imports I used.

      import java.io.File;
      import java.io.FileInputStream;
      import java.util.HashMap;
      import java.util.Map;
      import javax.xml.parsers.DocumentBuilderFactory;
      import javax.xml.soap.*;
      import org.apache.poi.hssf.usermodel.HSSFCell;
      import org.apache.poi.hssf.usermodel.HSSFRow;
      import org.apache.poi.hssf.usermodel.HSSFSheet;
      import org.apache.poi.hssf.usermodel.HSSFWorkbook;
      import org.w3c.dom.Document;
      import org.w3c.dom.NodeList;

      The only library that is not included by default (through the JDK) is the Apache POI library:


      org.apache.poi
      poi
      3.14

  16. Hi Bas, what are the advantages and disadvantages of using rest assured and post man rest client and soap ui? I want to know when to go for these and when not? Loop holes of each

    • What have you found yourself? I can write up something but I’d like to know what your own thoughts and findings are first, so that we don’t repeat one another.

  17. Hi

    Thanks for wonderful explanation. its really helpful. However i am facing an issue. I am new to API, the xls file you shown above contains some request message in xml that might be store in your local system. Where can i get those xml files. can you please share those messages.

  18. Hi Mark,

    Your explanation is up to mark.

    Please can you explain this scenarion-

    We have to read data from excel ( two headers plan id and subplan id ) using Junit test runner, that data goes and check using Rest API and create unique orchestra id that will store back in excel with plan and subplan id

  19. Hi Ban,
    Thanks for the wonderful post. I have been searching for this kind of data driven webservice testing for quite some time. I tried your code and its perfectly working fine for me.

    In my office network, am trying to implement the same solution but its been blocked proxy. Is there any way i can bypass proxy here.

    • Hi Narendra,

      thanks, glad it has been of help to you!

      I don’t think that bypassing your office proxy possible simply through code, unless you use some sort of fake proxy and bypass your company proxy. I can’t (and do not want to) help you with that though, but if you really need to access and test the web services you’re trying to invoke then I think you should talk to your network admins..

      • Hi Bas,Thanks for the update.
        I really didn’t mean to by pass the proxy completely. I have valid credential that i can pass to proxy. But want to know how can i pass the credentials to proxy programitically so that proxy allows my webservice request.

  20. Hi Bas,
    Thanks for this post. I have been looking for something like this to integrate other tests with web service tests. This eliminates my dependency on SOAP UI.
    I will try your solution today. Thank you once again.

    • You’re welcome Anil! You might also want to try and take a look at REST Assured (if you’re working with RESTful APIs) or Karate (which seems to be able to handle both RESTful and SOAP-based APIs). Those two tools have lots of useful features, which might save you the time and effort to write stuff yourself.

Leave a Reply

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