Forum Discussion

nimishbhuta's avatar
nimishbhuta
Frequent Contributor
7 years ago
Solved

Ready API - Writing the output to datasink in the same excel file

Hello, 

 

I have scenario in which I need to write the response in the excel sheet. I get two responses and both should be written in the same excel file. 

 

Test steps are as follows :

 

 1) DataSource - This is an unique identifier required in my request and I am using DataGenerator for it. 

 2) Request1    - This is the request which has an product item number and quantity as well as unique identifier. It gives me the response as OrderNo 

3) Request2 :This is the request which has an another product item number and quantity as well as unique identifier. It gives me the response as another OrderNo 

4) Property Transfer :- I have created 2 properties for this First Order and Second Order and transfer it to the data sink 

4) FisrtDataSink :- I am using the excel file and getting the FirstOrder response in the excel with the cell start at A1 

5)SecondDataSink I am using the excel file and getting the FirstOrder response in the excel with the cell start at A2

 

But the thing it only prints second order response in A2 and A1 is blank. It seems that it is writing the last data sink value. 

 

I need to write both the values one in A1 and another in A2. Is there any way to do it ?

 

Regards,

 

Nimish

 

 

  • Lucian's avatar
    Lucian
    7 years ago

    Hey, thought I answered to this on Friday evening but the answer was somehow lost... :smileysad: I also attached then the demo SoapUI project but I don't have it anymore. I only found a screenshot I took and the code (which was luckily saved in my clipboard manager)...

     

    So the point of my solution is to name all your requests from where you want to extract the customerPo/documentNumber in a certain way. Note that all mine where named 'GetOrder_*'

     

     

    Then in the groovy script I would filter for those requests, get all the required data and then finally write it to an existing excel:

     

    import java.io.File;
    import java.io.IOException;
    import jxl.*;
    import jxl.write.*;
    
    // Define the customerPo and documentNumber variables
    def customerPo = ''
    def documentNumber = ''
    def requestCounter = 0
    
    // Get a list of all test steps in the current test case
    def testSteps = context.testCase.getTestStepList()
    // Loop through all the test steps in the current test case
    // If a test step respects a certain naming then extract the response from it
    //   and register the customerPo and documentNumber in an excel
    testSteps.each{
    	if (it.name.startsWith("GetOrder_")) {
    
    		/**
    		 * Extract the customerPo and documentNumber from current request
    		 */
    		def rawResponse = testRunner.testCase.testSteps[ it.name ].testRequest.response.contentAsString
    		// Extract customerPo
    		def customerPoStartIndex = rawResponse.indexOf("<customerPO>") + "<customerPO>".length()
    		customerPo = rawResponse.substring( customerPoStartIndex, rawResponse.indexOf( "</", customerPoStartIndex ) )
    		// Extract documentNumber
    		def documentNumberStartIndex = rawResponse.indexOf("<documentNumber>") + "<documentNumber>".length()
    		documentNumber = rawResponse.substring( documentNumberStartIndex, rawResponse.indexOf( "</", documentNumberStartIndex ) )
    
    		/**
    		 * Write to file
    		 */
    		Workbook workbook = Workbook.getWorkbook(new File("D:\\test3.xls"));
    		WritableWorkbook writableWorkbook = Workbook.createWorkbook(new File("D:\\test3.xls"), workbook);
    		WritableSheet writableSheet = writableWorkbook.getSheet(0); 
    			
    		// Write the first colummn
    		Label label = new Label( 0, requestCounter, customerPo );
    		writableSheet.addCell(label);
    
    		// Write the second colummn
    		Label label2 = new Label( 1, requestCounter, documentNumber );
    		writableSheet.addCell(label2);
    		
    		//Write and close the workbook
    		writableWorkbook.write();
    		writableWorkbook.close();
    
    		requestCounter++
    	}
    }

    One final thing though, the excel file needs to be saved as xls (that is as an excel 2003 file). 

     

    Cheers!

  • Lucian's avatar
    Lucian
    6 years ago

    :smileylol:

     

    Like this... ?

     

    <customerPO>${DataSource#customerPO}-${=testRunner.testCase.testSteps['DataSource'].currentRow}</customerPO>

21 Replies

  • Lucian's avatar
    Lucian
    Community Hero

    Hi,

     

    I don't know much about datasink but instead of the steps 4, 5 and 6 you can use a single groovy step:

     

     

    import java.io.File;
    import java.io.IOException;
    import java.util.Date;
     
    import jxl.*;
    import jxl.write.*;
    import jxl.write.Boolean;
    import jxl.write.Number;
    import jxl.write.biff.RowsExceededException;
    
    def firstOrder = testRunner.testCase.getTestStepByName( "Properties" ).getPropertyValue( "firstOrderProperty" )
    def secondOrder = testRunner.testCase.getTestStepByName( "Properties" ).getPropertyValue( "secondOrderProperty" )
    
    try {
    	// Create the excel file
    	File exlFile = new File("D:/target_file.xls");
    	final WritableWorkbook writableWorkbook = Workbook.createWorkbook( exlFile );	
    	// Create a sheet in the excel file
    	final WritableSheet writableSheet = writableWorkbook.createSheet("Sheet1", 0);
    	
    	// Write the first row
    	Label label = new Label(0, 0, firstOrder);
    	writableSheet.addCell(label);
    
    	// Write the second row
    	label = new Label(0, 1, secondOrder);
    	writableSheet.addCell(label);
    
    	//Write and close the workbook
    	writableWorkbook.write();
    	writableWorkbook.close();
    
    } catch (IOException e) {
    	e.printStackTrace();
    } catch (RowsExceededException e) {
    	e.printStackTrace();
    } catch (WriteException e) {
    	e.printStackTrace();
    }

     

    Cheers!

     

    • mpartyka's avatar
      mpartyka
      Contributor

      Maybe this will help?   Not A1  / A2 ... but  A1 / B1 will work. 

       

      Use only a single Data Sink test step and include both properties in that data sink to Excel.   The first property will be written to cell A1, and the second to cell B1.   

    • nimishbhuta's avatar
      nimishbhuta
      Frequent Contributor

      Thanks Lucian. As I understand, I need to to first create firstOrderProperty and secondOrderProperty in SOAPUI Pro

       

      But I already have existing target file,so how can I open the target excel file rather than creating it?

       

      Regards,

       

      Nimish

  • Lucian's avatar
    Lucian
    Community Hero

    Quickly googled and found:

     

    Workbook workbook1 = Workbook.getWorkbook(new File("D:\\test.xls"));
    WritableWorkbook copy = Workbook.createWorkbook(new File("D:\\test.xls"), workbook1);
    WritableSheet sheet2 = copy.getSheet(0); 
    	
    // Write the first row Label label = new Label(0, 0, firstOrder); sheet2.addCell(label);
    // Write the second row label = new Label(0, 1, secondOrder); sheet2.addCell(label); //Write and close the workbook copy.write(); copy.close();

    As for the other part... you don't necessarily need to create properties for the first/second order. You can get those values directly in the script if you want. So you can replace:

     

    def firstOrder = ...
    def secondOrder = ...

    with anything you need (for instance you can extract the values from the response directly here)

     

    Let me know if you need more help. :D

  • Lucian's avatar
    Lucian
    Community Hero

    I will try to help you but only later today. I am quite busy now. :smileyhappy:

  • Lucian's avatar
    Lucian
    Community Hero

    Just a thing... I saw no <document> node in your response.

    • nimishbhuta's avatar
      nimishbhuta
      Frequent Contributor

      Hello, 

       

      It is documentNumber

       

      Regards,

       

      Nimish

      • Lucian's avatar
        Lucian
        Community Hero

        Hey, thought I answered to this on Friday evening but the answer was somehow lost... :smileysad: I also attached then the demo SoapUI project but I don't have it anymore. I only found a screenshot I took and the code (which was luckily saved in my clipboard manager)...

         

        So the point of my solution is to name all your requests from where you want to extract the customerPo/documentNumber in a certain way. Note that all mine where named 'GetOrder_*'

         

         

        Then in the groovy script I would filter for those requests, get all the required data and then finally write it to an existing excel:

         

        import java.io.File;
        import java.io.IOException;
        import jxl.*;
        import jxl.write.*;
        
        // Define the customerPo and documentNumber variables
        def customerPo = ''
        def documentNumber = ''
        def requestCounter = 0
        
        // Get a list of all test steps in the current test case
        def testSteps = context.testCase.getTestStepList()
        // Loop through all the test steps in the current test case
        // If a test step respects a certain naming then extract the response from it
        //   and register the customerPo and documentNumber in an excel
        testSteps.each{
        	if (it.name.startsWith("GetOrder_")) {
        
        		/**
        		 * Extract the customerPo and documentNumber from current request
        		 */
        		def rawResponse = testRunner.testCase.testSteps[ it.name ].testRequest.response.contentAsString
        		// Extract customerPo
        		def customerPoStartIndex = rawResponse.indexOf("<customerPO>") + "<customerPO>".length()
        		customerPo = rawResponse.substring( customerPoStartIndex, rawResponse.indexOf( "</", customerPoStartIndex ) )
        		// Extract documentNumber
        		def documentNumberStartIndex = rawResponse.indexOf("<documentNumber>") + "<documentNumber>".length()
        		documentNumber = rawResponse.substring( documentNumberStartIndex, rawResponse.indexOf( "</", documentNumberStartIndex ) )
        
        		/**
        		 * Write to file
        		 */
        		Workbook workbook = Workbook.getWorkbook(new File("D:\\test3.xls"));
        		WritableWorkbook writableWorkbook = Workbook.createWorkbook(new File("D:\\test3.xls"), workbook);
        		WritableSheet writableSheet = writableWorkbook.getSheet(0); 
        			
        		// Write the first colummn
        		Label label = new Label( 0, requestCounter, customerPo );
        		writableSheet.addCell(label);
        
        		// Write the second colummn
        		Label label2 = new Label( 1, requestCounter, documentNumber );
        		writableSheet.addCell(label2);
        		
        		//Write and close the workbook
        		writableWorkbook.write();
        		writableWorkbook.close();
        
        		requestCounter++
        	}
        }

        One final thing though, the excel file needs to be saved as xls (that is as an excel 2003 file). 

         

        Cheers!

  • Lucian's avatar
    Lucian
    Community Hero

    I think there are multiple  ways to do this. This is how I did it:

     

    I  gave all the requests where I wanted to extract the customerPO and documentNumber a similar name (notice GetOrder_*):

     

     

    Then in the groovy script I simply looped over all the test steps with that similar name and extracted the required elements:

     

    import java.io.File;
    import java.io.IOException;
    import jxl.*;
    import jxl.write.*;
    
    // Define the customerPo and documentNumber variables
    def customerPo = ''
    def documentNumber = ''
    def requestCounter = 0
    
    // Get a list of all test steps in the current test case
    def testSteps = context.testCase.getTestStepList()
    // Loop through all the test steps in the current test case
    // If a test step respects a certain naming then extract the response from it
    //   and register the customerPo and documentNumber in an excel
    testSteps.each{
    	if (it.name.startsWith("GetOrder_")) {
    
    		/**
    		 * Extract the customerPo and documentNumber from current request
    		 */
    		def rawResponse = testRunner.testCase.testSteps[ it.name ].testRequest.response.contentAsString
    		// Extract customerPo
    		def customerPoStartIndex = rawResponse.indexOf("<customerPO>") + "<customerPO>".length()
    		customerPo = rawResponse.substring( customerPoStartIndex, rawResponse.indexOf( "</", customerPoStartIndex ) )
    		// Extract documentNumber
    		def documentNumberStartIndex = rawResponse.indexOf("<documentNumber>") + "<documentNumber>".length()
    		documentNumber = rawResponse.substring( documentNumberStartIndex, rawResponse.indexOf( "</", documentNumberStartIndex ) )
    
    		/**
    		 * Write to file
    		 */
    		Workbook workbook = Workbook.getWorkbook(new File("D:\\test3.xls"));
    		WritableWorkbook writableWorkbook = Workbook.createWorkbook(new File("D:\\test3.xls"), workbook);
    		WritableSheet writableSheet = writableWorkbook.getSheet(0); 
    			
    		// Write the first colummn
    		Label label = new Label( 0, requestCounter, customerPo );
    		writableSheet.addCell(label);
    
    		// Write the second colummn
    		Label label2 = new Label( 1, requestCounter, documentNumber );
    		writableSheet.addCell(label2);
    		
    		//Write and close the workbook
    		writableWorkbook.write();
    		writableWorkbook.close();
    
    		requestCounter++
    	}
    }

     

    Hope it helps!

  • Lucian's avatar
    Lucian
    Community Hero

    The current iteration can be extracted like:

     

    def currentRow = testRunner.testCase.testSteps['DataSourceStepName'].currentRow
    • nimishbhuta's avatar
      nimishbhuta
      Frequent Contributor

      Thanks. 

       

      I wanted to know that if I have 2 values coming from the variables. How can I combined 2 values with a delimeter as "-" in the soap request.

       

      For example: I am having unique number coming from the DataSource and another value coming from the groovy script. I need combined both the values with "-"

       

      To elaborate further, this is for the customerPO in the header section of my soapui request. I looks like this in the customerPoNode in the soap request

       

      customerPO>${DataSource#customerPO}${=testRunner.testCase.testSteps['DataSource'].currentRow}</customerPO>

       

       

      I will get a unique number from ${DataSource#customerPO} and then wants to add "-" and then ${=testRunner.testCase.testSteps['DataSource'].currentRow}

       

      I am not aware how add "-" in between this 2 values in the soapui request

       

      • Lucian's avatar
        Lucian
        Community Hero

        :smileylol:

         

        Like this... ?

         

        <customerPO>${DataSource#customerPO}-${=testRunner.testCase.testSteps['DataSource'].currentRow}</customerPO>