Forum Discussion

jurven007's avatar
jurven007
Occasional Contributor
7 years ago
Solved

Run script assertion without sending

Hi All,

 

I copied an xml message into a request (part of a testcase using property transfer). Next I created a script assertion which will validate the content of the request. Is it possible to run the script assertion without sending the request? I only want to know if the message validates against the xsd...

Thanks in advance,

 

Jurriaan

  • Hi,

     

    Thanks for sharing the script. I replaced the 'println' with 'log.info' so I can see what's going on. The script is now:

    /**
    * this groovy script validates given xml file 
    * with the given xsd file
    **/
    import org.xml.sax.SAXException
    import javax.xml.transform.stream.StreamSource
    import java.nio.charset.StandardCharsets
    import javax.xml.XMLConstants
    import javax.xml.validation.SchemaFactory
    
    //Provide valid xml instance & and xsd file paths below
    def xml = 'C://Temp//BGTConnector//test2.xml'
    def xsd = 'C://SoapUI projecten//BGT Connector//imgeo0300//verticaal//imgeo0300_msg_verticaal.xsd'
    
    //Not required to edit beyond this point
    
    def isFileExists(String fileName) {
        def file = new File(fileName)
        def result = file.exists()
        if (result) {
            log.info "$fileName exists"
        } else {
            log.info "$fileName does not exist"
        }
        result
    }
    
    def isValid(String xsd, String xml) {
        def result = false
        if (isFileExists(xsd) && isFileExists(xml)) {
            def factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI)
            try {
                def schema = factory.newSchema(new File(xsd))
                def validator = schema.newValidator()
                validator.validate(new StreamSource(new InputStreamReader(new FileInputStream(xml), StandardCharsets.UTF_8)))
                log.info "$xml is valid."
                result = true
            } catch (SAXException ex) {
                log.info "$xml is not valid because \n"
                log.info ex.localizedMessage 
            } catch (FileNotFoundException ex) {
                log.info ex.localizedMessage
            } catch (IOException ex) {
                log.info ex.localizedMessage
            } finally {
                return result
            }
        } else {
            log.info "Can't validate file as one of the file is not found"
        }
        result
    }
    
    //Validate xml by calling above method
    isValid(xsd, xml)

     When I run the groovy script it finds the xsd and xml but fails because it cannot resolve a name.

     

     

     

    I searched for it and it's found in another xsd. I suspect the selected xsd has references to other xsd's which aren't loaded. Is it possible to load multiple xsd's? Can I refer to a property (which contains the message) instead of the xml file?

    Thanks for helping out,

     

    Jurriaan

11 Replies

  • From my experience with assertion scripts, it depends on what your assertion is that you test for in that script. For simplicity, if you test for HTTP status code 200 without having any response in memory, it will fail the test. Take a look at your response window in SoapUI Pro. If it's empty (no JSON, no HTML, no XML, you cannot expect a PASS assertion on that content unless you test for no content!

     

    But if you already ran the request and you have response data populated, sure, you can of course alter your assertion script and add new assertion tests. Then hit the green arrow button and it will be accurate.

    • jurven007's avatar
      jurven007
      Occasional Contributor

      Hi Bill,

       

      Thanks for your suggestion. Once the request is sent and I add extra assertions, they are automatically executed. In my situation that's not the case.

      The request is a teststep in a testcase and the response is empty. When I leave the URL bar empty and execute the test I receive a message an url must be entered.

      The script assertion consists of:

      def project = messageExchange.modelItem.testStep.testCase.testSuite.project
      
      def wsdlcontext = project.getInterfaceAt(1).getDefinitionContext()
      def validator = new com.eviware.soapui.impl.wsdl.support.wsdl.WsdlValidator(wsdlcontext);
      
      def errors = validator.assertRequest(messageExchange, false)
      
      assert errors.length < 1

       

      The message itself is first stored in a property and than transfered to the request via the property transfer step. The property is filled with the following setup script:

      def myRequest=new File("c:\\temp\\bgtconnector\\test2.xml").getText()
      
      testRunner.testCase.setPropertyValue( "Request", myRequest )
      
      def xmltop = '''<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:stuf="http://www.geostandaarden.nl/imgeo/2.1/stuf-imgeo" xmlns:stuf1="http://www.egem.nl/StUF/StUF0301" xmlns:xlin="http://www.w3.org/1999/xlink" xmlns:gml="http://www.opengis.net/gml" xmlns:ns="http://www.opengis.net/citygml/2.0">
         <soapenv:Header/>
         <soapenv:Body>'''
      
      def xmlbottom = '''   </soapenv:Body>
      </soapenv:Envelope>'''
      
      testRunner.testCase.setPropertyValue( "Bericht", xmltop+myRequest+xmlbottom )

      By transferring the message in the property to an actual message I thought it would be easier to validate (xsd validation) the message. Maybe it's easier (if possible?) to directly validate the content of the property?

       

    • jurven007's avatar
      jurven007
      Occasional Contributor

      Hi,

       

      Thanks for sharing the script. I replaced the 'println' with 'log.info' so I can see what's going on. The script is now:

      /**
      * this groovy script validates given xml file 
      * with the given xsd file
      **/
      import org.xml.sax.SAXException
      import javax.xml.transform.stream.StreamSource
      import java.nio.charset.StandardCharsets
      import javax.xml.XMLConstants
      import javax.xml.validation.SchemaFactory
      
      //Provide valid xml instance & and xsd file paths below
      def xml = 'C://Temp//BGTConnector//test2.xml'
      def xsd = 'C://SoapUI projecten//BGT Connector//imgeo0300//verticaal//imgeo0300_msg_verticaal.xsd'
      
      //Not required to edit beyond this point
      
      def isFileExists(String fileName) {
          def file = new File(fileName)
          def result = file.exists()
          if (result) {
              log.info "$fileName exists"
          } else {
              log.info "$fileName does not exist"
          }
          result
      }
      
      def isValid(String xsd, String xml) {
          def result = false
          if (isFileExists(xsd) && isFileExists(xml)) {
              def factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI)
              try {
                  def schema = factory.newSchema(new File(xsd))
                  def validator = schema.newValidator()
                  validator.validate(new StreamSource(new InputStreamReader(new FileInputStream(xml), StandardCharsets.UTF_8)))
                  log.info "$xml is valid."
                  result = true
              } catch (SAXException ex) {
                  log.info "$xml is not valid because \n"
                  log.info ex.localizedMessage 
              } catch (FileNotFoundException ex) {
                  log.info ex.localizedMessage
              } catch (IOException ex) {
                  log.info ex.localizedMessage
              } finally {
                  return result
              }
          } else {
              log.info "Can't validate file as one of the file is not found"
          }
          result
      }
      
      //Validate xml by calling above method
      isValid(xsd, xml)

       When I run the groovy script it finds the xsd and xml but fails because it cannot resolve a name.

       

       

       

      I searched for it and it's found in another xsd. I suspect the selected xsd has references to other xsd's which aren't loaded. Is it possible to load multiple xsd's? Can I refer to a property (which contains the message) instead of the xml file?

      Thanks for helping out,

       

      Jurriaan