Using soapUI free version(5.4.0). I have simple project with test-case which has test-steps and load-tests like:
TestCase
Test-steps
one
two
LoadTests
LoadOne
LoadTwo
I want to run LoadOne and LoadTwo load tests, using Groovy scripting, in separate script. How to do that?
Assuming you're executing a Groovy test step from the same project, the following script will execute a load test called LoadOne:
import com.eviware.soapui.impl.wsdl.loadtest.*;
// Get the load test
def loadTest = testRunner.testCase.getLoadTestByName("LoadOne");
// Run the load test
WsdlLoadTestRunner loadTestRunner = new WsdlLoadTestRunner(loadTest);
loadTestRunner.start(true);
loadTestRunner.waitUntilFinished();
Then, of course, do the same for your other load test.
Related
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>
context,testRunner variables(built-in) in SoapUI are objects/instances of which classes in soapui api.
I was under impression that context variable is an instance of
com.eviware.soapui.impl.wadl.inference.schema.Context
but in the Context class i could not find exapnd method which we use regualrly as shown below
context.expand('${#level#request}')
Please some body clarify...if both are difference where can i find list of all methods of context variable
Thanks
The class of the context variable could be different depending on context.
The best way to get the class name to print it out:
log.info( context.getClass() )
If we talk about groovy script test step then context should be
com.eviware.soapui.impl.wsdl.panels.support.MockTestRunContext if you run just your script without running the whole test case.
com.eviware.soapui.impl.wsdl.testcase.WsdlTestRunContext if you run the whole or part of the test case including your script.
probably it could be other for different soapui project types..
So, what is the context of your groovy script?
Btw, how did you get com.eviware.soapui.impl.wadl.inference.schema.Context ?
SoapUI initializes certain variables in certain level.
Here are the list of variables available at different level.
Project Setup Script
context
project
runner
log
Similarly, below variables available at Test Suite Setup Script
context
testSuite
runner
log
And also certain variables available in Test Case Setup Script.
The same is with TearDown Scripts as well.
However, If I understand right, you were referring to Groovy Script test step.
And the following variables are available there are:
testRunner
context
log
To be more precise, context.expand() is used to read certain property values either from test case, suite or project.
In order to read test case level property, CASE_PROPERTY
User one of the two:
context.expand('${#TestCase#CASE_PROPERTY}')
context.testCase.getPropertyValue('CASE_PROPERTY')
In order to read test suite level property, SUITE_PROPERTY
User one of the two:
context.expand('${#TestSuite#SUITE_PROPERTY}')
context.testCase.testSuite.getPropertyValue('SUITE_PROPERTY')
In order to read test project level property, PROJECT_PROPERTY
User one of the two:
context.expand('${#TestSuite#SUITE_PROPERTY}')
context.testCase.testSuite.getPropertyValue('SUITE_PROPERTY')
I have the following TestCase Set up:
Datasource
Soap Request
Groovy Script
Datasource loop
I would like to get the status of the SoapRequest test step using Groovy Script test step.
It can be done as show below:
myTestStepResult = testRunner.runTestStepByName("Soap Request")
myStatus = myTestStepResult.getStatus()
But I don't want to run the TestStep by script, but just using the soapui testrunner.
In a datasink test step I can use this:
${=testRunner.results[testRunner.results.size()-1].status}
Unfortunately the above doesn't work in a GroovyScript TestStep
Any ideas?
It is possible to run the test step without using test step name and get the status as needed. And it is assumed that the there is no change in the test step sequence i.e., Soap Request step is always the previous step of Groovy Script step, and no other step comes in between the two.
Groovy Script:
log.info testRunner.runTestStep(context.testCase.testStepList[context.currentStepIndex - 1]).status
To avoid having to run the test step (again), please try the following:
results = testRunner.getResults()
status = results.get(results.size() - 1).getStatus()
log.info status
After running the test case, the script log should display the status of the previous test step.
Please note that the Groovy Script test step containing the code has to be executed when running the test case. If you run just the test step, you will get the following error:
(java.lang.ArrayIndexOutOfBoundsException)
which is normal, because you cannot get results.size() if the list is empty.
Background: I am using SoapUI 5.0.0 (not pro) and I have a testStep SCRIPT ASSERTION that I use to check the response that the testStep receives.
If a certain condition is met, i wish to start another testStep (can run once the script is over).
My problem is: testRunner does not work in script assertion so I cannot use testRunner.gotoStepByName("step5")
My question: is there a different option I can call that does work in a script assertion that will make the test jump to that certain testStep ?
In script assetion you've available context variable, this variable is an instance of com.eviware.soapui.impl.wsdl.testcase.WsdlTestRunContext.
Through this class you can get com.eviware.soapui.model.testsuite.TestCaseRunner using getTestRunner() method and from here use gotoStepByName(String name).
You can use the follow code in your assertion script when your conditions are met:
context.getTestRunner().gotoStepByName('step5')
Note that running the script assertion "alone" the context.getTestRunner() returns null because you're running it in assertion context, the same applies if you run it from the TestStep. To get the runner property correctly you've to run the TestStep which contains the script assertion from the TestCase.
Hope this helps,
I have a set of 60 testcases in a project in SoapUI that I want to run concurrently. Each testcase needs to use a value to work. The values are stored in an external file (spreadsheet or textfile). Each testcase needs to get a value from this file and use it. However when I run the testsuite, multiple tests are picking up the same value however only one value can be used for a test (same value cannot be used in more than 1 test at the same time). I would like the external file to be accessed by one testcase at a time in soapUI. Does this involve locking or some sort of queueing system or what groovyscript could I use? thanks
I can't figure out how to get this to work with your external file, but I can think of another way only using SoapUI. Here's my suggestion for a solution:
Create a new TestCase containing only a DataGen TestStep.
Configure it so that it generates the numbers you want.
Change its mode to "READ", so that it will generate a new value every time the test step is run.
Now, wherever you want one of these values, instead of accessing your external file, add a Run TestCase TestStep to run your new DataGen test case, and make sure to return the generated number as a property. Use it where you need the generated number.
As I'm typing this, I just realized this only works with the pro version of SoapUI. If you don't have a license you can get a trial from the website.