How to read a txt file, get a data and store it as variable in Custom Properties of SOAPUI using Groovy? - groovy

i started to use Soapui this week and i did some tests like sending a request POST and save the response as txt file ina folder.
What i'm trying to do is to read this txt file, copy a sepcific data and store it in Custom Properties.
Because i want to use this object in the nest Request POST which is depending of the first request.
I want to do it in Groovy.
i have only the Open source SOAPUI version 5.0.0
Thank you

You've to add a groovy test step in your test case and do it similar as you would in java, check groovy documentation.
Only as a reference SOAPUI 5.2.0 has the groovy 2.1.7 version (check the dependency in pom.xml) so in groovy scripts which runs on SOAPUI you can use the java standard api included in the jre, the SOAPUI classes, the groovy 2.1.7 API among some others, additionally you can include other jars in SOAPUI\bin\ext in order to use them in groovy script.
Finally you're asking about to read some data from a file and write it to a custom property, so for example you can do it as follows:
// read the file from path
def file = new File('/path/yourFile')
// for example read line by line
def yourData = file.eachLine { line ->
// check if the line contains your data
if(line.contains('mySpecifiyData=')){
return line
}
}
// put the line in a custom property in the testCase
testRunner.testCase.setPropertyValue('yourProp',yourData)
Since your problem it's not clear I show you a possible sample showing how to read a file looking for specific content and saving this content in a custom property in the testCase.
Note that in groovy scripts the are a global objects which you can use: testRunner, context and log, in this sample I use testRunner to access testCase and its properties, in the same way you can go thought testRunner to access testSuites, project, testSteps etc... check the documentation:
http://www.soapui.org/Scripting-Properties/tips-a-tricks.html
http://www.soapui.org/Functional-Testing/working-with-scripts.html
Hope this helps,

Related

How to run testStep in another project using SoapUI testrunner in command line?

We have few soapui projects each sending testrequests at different web services. The Groovy script that executes the tests is however for the most part identical for each project. Therefore we decided it would be good with regard to easy versioning and maintenance to keep the common script in separate "dummy" project ("TestWSScript-soapui-project.xml") with one testsuite/case (Autotest/Test) with only one testStep (Groovy script named "Run").
The idea is to have one project for each WebService (say WS1-soapui-project.xml) which has testSuite with one TestCase. Within this TestCase will be
Groovy test step to set WS specific properties and call the universal script from TestWSScript-soapui-project.xml
Request test step to call the webservice and perform assertions
Ending Groovy test step.
This works from within SoapUI, but I want to run the tests from Windows command line (batch file for automatization purposes). Here I ran into a problem: when invoking testrunner from command line with
set "SOAPUI_FOR_TEST_DIR=..\..\..\programs\SoapUI-5.6.0"
"%SOAPUI_FOR_TEST_DIR%\bin\testrunner.bat" -sAutoTest -r -a -j -I "..\resources\WS1-soapui-project.xml"
it does not load whole workspace with all SoapUi projects. Therefore the following script (in WS1-soapui-project.xml/AutoTest suite/Test TestCase) that should run testStep from project TestWSScript-soapui-project.xml/AutoTest suite/Test TestCase returns Null (more specifically "Cannot invoke method getProjectByName() on null object")
import com.eviware.soapui.model.project.ProjectFactoryRegistry
import com.eviware.soapui.impl.wsdl.WsdlProjectFactory
def workspace = testRunner.testCase.testSuite.project.workspace
def testProject = (workspace==null) ?
ProjectFactoryRegistry.getProjectFactory(WsdlProjectFactory.WSDL_TYPE).createNew("TestWSScript.xml") :
workspace.getProjectByName("TestWSScript")
if(!testProject.open && workspace!=null) workspace.openProject(testProject)
// Connect to the test step in another project.
def prj = testRunner.testCase.testSuite.project.workspace.getProjectByName('TestWSScript')
tCase = prj.testSuites['AutoTest'].testCases['Test']
tStep = tCase.getTestStepByName("Run")
// Call the test runner and check if it can run the specified step.
def runner = tStep.run(testRunner, context)
The called script just loops through parameters read from csv file and calls request step. It is irrelevant for the problem I need to solve as the issue happens before the script is called.
Is there even a way to achieve what we want? We are using the free version of SoapUI-5.6.0.
Thanks in advance.
Here is what I suggest in your case.
Instead of a separate project for just one groovy script, create a library out of it.
Create a class and methods as needed. Use method arguments or class members in case if you are passing data from the callers.
Use your existing script, convert them into class, methods.
Create the class(es) based on the need.
It can be programmed either java or groovy
Compile the class(es) and create library
Copy this library under %SOAPUI_HOME%\bin\ext directory
Now you can just call those methods in any project. No more dummy project is required.
Good thing is all the projects are independent.
Here is blog content created by Rupert Anderson, one of the SoapUI export and Author.
Steps
1.Create the following directory structure
soapuilib/src/main/groovy/custom
2.Get some Groovy code
For this example, I have knocked together a simple script to generate sequential ids. It may be of little practical use, but I wanted something with a simple public static method to call. Since the method is static, there will be no need to instantiate the class before calling it in step #8.
[groovy title=”SequentialIdGenerator.groovy”]
package custom
import java.util.concurrent.atomic.AtomicLong
public class SequentialIdGenerator {
public static final long counterSeed = 1000
public static final String prefix = "id"
private static AtomicLong counter = new AtomicLong(counterSeed)
public static String nextId() {
return prefix + counter.incrementAndGet()
}
}
[/groovy]
create the above script as a text file called SequentialIdGenerator.groovy
copy it to soapuilib/src/main/groovy/custom
3.Create Gradle build script
For this part, there are plenty of options to build the code and package it, such as Maven, Ant or just running the right shell commands! The following minimal Gradle script allows us to compile and package the code as a jar in one easy statement.
[code language=”groovy”]
apply plugin: ‘groovy’
version = ‘1.0’
jar {
classifier = ‘library’
manifest {
attributes ‘Implementation-Title’: ‘SoapUI Sample Groovy Library’, ‘Implementation-Version’: version
}
}
repositories {
mavenCentral()
}
dependencies {
compile ‘org.codehaus.groovy:groovy:2.1.7’ //Matches Groovy in SoapUI 5.2.1
}
[/code]
Create the above Gradle script as soapuilib/build.gradle
INFO: Groovy Version – (At time of writing) The current version of Groovy is v2.4.6, but SoapUI 5.2.1 ships with Groovy 2.1.7. If you try to compile with a Groovy version 2.3+ and use it with SoapUI, you will see an error popup and log message in like ‘org/codehaus/groovy/runtime/typehandling/ShortTypeHandling‘ – see http://glaforge.appspot.com/article/groovy-2-3-5-out-with-upward-compatibility for more details and options. Basically, you can still use the latest Groovy version, but will need to include an additional groovy-backports-compat23 dependency!
5.Compile it & Create jar file
Now we’re ready to use the Gradle script to compile the sample script from step #2 and package it as a jar file.
Open a shell/command prompt at soapuilib/
gradle clean build jar
You should then see output like:
[bash]
tests-MacBook-Pro:soapuilib test$ gradle clean build jar
:clean
:compileJava UP-TO-DATE
:compileGroovy
:processResources UP-TO-DATE
:classes
:jar
:assemble
:compileTestJava UP-TO-DATE
:compileTestGroovy UP-TO-DATE
:processTestResources UP-TO-DATE
:testClasses UP-TO-DATE
:test UP-TO-DATE
:check UP-TO-DATE
:build
BUILD SUCCESSFUL
Total time: 5.499 secs
This build could be faster, please consider using the Gradle Daemon: https://docs.gradle.org/2.12/userguide/gradle_daemon.html
[/bash]
and our new library jar file created under the directory:
soapuilib/build/soapuilib-1.0-sample.jar
6.Add jar file to SoapUI
To make our new Groovy library jar available for use in SoapUI, it should be added in SoapUI Home under the following external library directory:
SoapUI ext Directory
Or the Windows equivalent e.g. C:\Program Files\SmartBear\SoapUI-5.2.1\bin\ext
7.Verify jar file is imported
When SoapUI is restarted, you should see the following log entry indicating that the jar file has been successfully added to the SoapUI classpath:
SoapUI ext Lib Loaded
8.Call the code
Our SequentialIdGenerator has a public static method nextId() that we can call, so to do this we can either import the class (Example 1) or just prefix the class with its package (Example 2). See below:
Example 1 – Call from Groovy TestStep:
[code]
import custom.*
log.info SequentialIdGenerator.nextId()
[/code]
Gives output like:
[code]
Thu May 12 16:49:20 BST 2016:INFO:id1001
[/code]
Example 2 – Call from Property Expansion:
[code]
${= custom.SequentialIdGenerator.nextId()}
[/code]
EDIT:
Here is the sample code with context, log variable access.
<script src="https://gist.github.com/nmrao/c489a485bbe3418cf49d8442f9fb92eb.js"></script>

Store custom Groovy function in JMeter UI

Been struggling with this a lot lately: How do I store a custom Groovy script with imports etc in the JMeter UI so I can reuse it later?
I don't want to alter JMeter startup property files in any way
I want to be able to call this Groovy 20+ times within the JMX with different parameters
From the JMeter doc:
Once the script is working properly, it can be stored as a variable on
the Test Plan. The script variable can then be used to create the
function call.
The groovy (compatible with Beanshell) is 62 lines and includes imports of custom JAR files. If I could store this as a var callable with __groovy(param) that would be great, I don't see how to do that from the docs. Setting up 20 JSR223s is incredibly clunky but I am coming up with workarounds if there is no JMeter way to do this.
References:
https://jmeter.apache.org/usermanual/best-practices.html#developing_scripts
Depending on what you're trying to achieve:
There is a possibility to specify a path to the file with your code in any of JSR223 Test Elements so you won't have to copy and paste it multiple times into "Script" area so in case of changes you will need to amend it in one place only:
There is groovy.utilities property where you can specify the path to your .groovy file containing the logic callable from the __groovy() function, it defaults to bin/utility.groovy
You can compile your code to .jar file and store it under JMeter Classpath, this way you will be able to call your functions from any place. See How to Reuse Your JMeter Code with JAR Files and Save Time article for example implementation/usage details

Call function from different sampler in JMeter - Groovy

I have a sampler that get data from DB (budget), and I have some assertions that I made using JSR223 assertion.
In each assertion I write the same function (check_budget) and to each assertion I pass different values (start_budget, end_budget etc)
The problem is that I duplicate the code for each assertion and it is not friendly for maintenance.(if logic change need to change at 7 duplicate functions)
It there a way to create a sampler and write generic function in it (calc_budget) and to call it from each assertion,
like creating a class in java and perform import?
In Groovy you have evaluate() function, so given you stored it into a JMeter Variable or JMeter Property or into a file you can call it like:
evaluate(vars.get('your_var'))
or
evaluate(new File('your_test.groovy'))
See Scripting JMeter Assertions in Groovy - A Tutorial article for more information.
In that case, and in general also, you can keep groovy script in a script file and call the same script file from all JSR223 elements
Script File
Name of a file to be used as a JSR223 script, if a relative file path is used, then it will be relative to directory referenced by "user.dir" System property

BSF Assertion from script file does not load UDVs

I am trying to use groovy scripts as BSF assertion in JMeter. The script written inside the JMETER assertion script box works well, but when I try to use it through a groovy file it is not loading the User Defined Variables it needs for assertions
It says
org.apache.bsf.BSFException: exception from Groovy: groovy.lang.MissingPropertyException: No such property: mobileNumber class: D__RESTAPITesting_JmeterBSFAssertionScripts_Script1
Not sure why it is looking for property when ${..} refers to a variable (if I am not wrong). Any help on the error message and how to use a script file for assertions ?
The scripts I have written are saved as *.groovy. Do I need to save scripts in some other extensions for BSF to read it correctly ?
Pass your User Defined Variables via Parameters input like ${foo} ${bar}
In your .groovy script body refer variables as args[0] args[1]
See image below for details (the solution works fine for file inputs as well) and How to Use JMeter Assertions in 3 Easy Steps guide for advanced information on using JMeter's assertions.

Append content from file using Email Ext Jenkins plugin

I have been modifying the default groovy template that the Email Ext plugin supplies.
Firstly, I had to modify the JUnitTestResult and need to format it accordingly to my need. I found in the it.JUnitTestResult, it is a reference to the ScriptContentBuildWrapper class. And then I was able to format the JUnitTestResult according to my need.
Now I am facing a second difficulty:
Along with those contents, I need to append more content from a file that resides in the job workspace. How to access the files that reside in the workspace directory.
I would be interested to know how I can access the build context object. Whats the java class name and things like that.
Just use build which returns an AbstractBuild
Try -
build.workspace
Which returns the FilePath of the directory where the build is being built.
See AbstractBuild.getWorkspace.
Tip: in Groovy, you can avoid the "get" and use field-like access notation.
Depending on which version of email-ext you are using, you can use the tokens provided to get access to things, so if you look at the token help, you'll see lots of tokens. These can be used in the groovy templates to do the same thing. For instance, the FILE token can be used in the Groovy by doing FILE(path: 'path/to/file') and it will replace with the contents of the file (only works on files that are below the workspace).
The build object is not available directly in all groovy scripts (e.g. groovy build script, groovy system build script, groovy post-build script, groovy script as evaluated in email-ext). The most portable way of obtaining build object in groovy script for a running build is:
import hudson.model.*
def build = Thread.currentThread().executable
Then you can get workspace and access files inside like this:
workspace = build.getEnvVars()["WORKSPACE"]
afilename = workspace + "/myfile"
afile = new File(afilename);
// afile.write "write new file"
// afile << "append to file"
// def lines = afile.readLines()

Resources