I'm working on a script to automate the running of several TestSuites across multiple projects concurrently in SoapUI 4.5.1:
import com.eviware.soapui.impl.wsdl.panels.testsuite.*;
def properties = new com.eviware.soapui.support.types.StringToObjectMap();
def currentProject = testRunner.getTestCase().testSuite.getProject();
def workspace = currentProject.getWorkspace();
def otherProject = workspace.getProjectByName('Project 1');
def otherTestSuite = CGReportsProject.getTestSuiteByName('TestSuite 1');
otherTestSuite.run(properties, true);
However, I'm also attempting to open the TestSuite Panel for each of the TestSuites that are run by the script to allow visual tracking of the Suites' progress. That's where I run into trouble:
ProWsdlTestSuitePanelBuilder.buildDesktopPanel(otherTestSuite);
This particular line throws the error:
groovy.lang.MissingMethodException: No signature of method:
static com.eviware.soapui.impl.wsdl.panels.testsuite.
ProWsdlTestSuitePanelBuilder.buildDesktopPanel() is
applicable for argument types:
(com.eviware.soapui.impl.wsdl.WsdlTestSuitePro) values:
[com.eviware.soapui.impl.wsdl.WsdlTestSuitePro#1d0b2bc6]
Possible solutions:
buildDesktopPanel(com.eviware.soapui.impl.wsdl.WsdlTestSuitePro),
buildDesktopPanel(com.eviware.soapui.model.ModelItem),
buildDesktopPanel(com.eviware.soapui.impl.wsdl.WsdlTestSuite),
buildDesktopPanel(com.eviware.soapui.model.ModelItem),
buildDesktopPanel(com.eviware.soapui.impl.wsdl.WsdlTestSuite),
buildDesktopPanel(com.eviware.soapui.model.ModelItem)
error at line: 12
Which I take to mean that the instance of the WsdlTestSuitePro I'm throwing at ProWsdlTestSuitePanelBuilder.buildDesktopPanel() isn't being accepted for some reason - but I've no idea why.
At this point, I'm also not sure if the ProWsdlTestSuitePanelBuilder.buildDesktopPanel() is really what I want anyway, but it's the only UI builder that'll take a WsdlTestSuitePro, as that apparently what all my Testsuites are.
Okay, so this falls under the newbie catagory. I wasn't paying attention to the fact that buildDesktopPanel was static.
However, I managed to work around that and create the final product:
// Create a UISupport container for all the panels we'll be showing
def UIDesktop = new com.eviware.soapui.support.UISupport();
// Basic environment information
def properties = new com.eviware.soapui.support.types.StringToObjectMap();
def currentProject = testRunner.getTestCase().testSuite.getProject();
def workspace = currentProject.getWorkspace();
// Get the various Projects we'll be using
def OtherProject = workspace.getProjectByName('Other Project');
// Get the various TestSuites we'll be running
def OtherTestSuite = OtherProject.getTestSuiteByName('Other Test Suite');
// Generate the Panels for the Testsuites
def TestSuitePanel = new com.eviware.soapui.impl.wsdl.panels.testsuite.ProWsdlTestSuiteDesktopPanel(OtherTestSuite);
// Show TestSuite Panels
UIDesktop.showDesktopPanel(TestSuitePanel);
// Run the Testsuites
OtherTestSuite.run(properties, true);
Related
I'm trying to debug my usage of wired and pyramid_services as well as migrate from using named services to registering services with interfaces and context classes.
Is there a way to see everything that is registered with the current container? Both for debugging and also to create fixtures for pytest during testing. Sort of like the get_registrations line of this pseudo code for injecting tests into conftest.py for pytests:
def generate_service_fixture(reg):
#pytest.fixture()
def service_fixture(base_app_request):
return base_app_request.find_service(iface=reg.iface, context=reg.context, name=reg.name)
return service_fixture
def inject_service_fixture(reg):
parts = [
get_iface_name(reg.iface),
get_context_name(reg.context),
get_name(reg.name)]
# Make up a name that tests can use to pull in the appropriate fixture.
fixture_name = '__'.join(filter(None, parts)) + '_service'
globals()[fixture_name] = generate_service_fixture(reg)
def get_iface_name(iface):
return iface.__name__ if iface else None
def get_context_name(context):
return context.__name__ if context else None
def get_name(name):
return name if name else None
def register_fixtures(container):
for reg in container.get_registrations():
inject_service_fixture(reg)
Later on in tests I would do something like:
def test_service_factory(IRequest_service):
assert IRequest_service, "Factory failed to construct request."
This sort of works for debugging after the services have been declared. I'm just posting this half-answer for now. I don't have a clean solution for dynamic pytest fixture creation.
def includeme(config):
# ...
config.commit()
introspector = config.registry.introspector
for intr in introspector.get_category('pyramid_services'):
print (intr['introspectable'])
I feel a bit silly for making this question, but I'm out of options.
Basically, I have this on a "let's learn groovy" project:
package com.mypackage.markupexercise
import groovy.xml.MarkupBuilder
println "Hello MarkupBuilder"
def writer = new StringWriter()
def builder = new MarkupBuilder(writer)
builder.records() {
example(id:1)
}
And I'm getting the following compilation error:
<path>\markupbuilderexercise\Main.groovy: 3: unable to resolve class groovy.xml.MarkupBuilder
# line 3, column 1.
import groovy.xml.MarkupBuilder
^
1 error
Now, I've seen [this question][1], and I have imported the groovy-xml-3.09.jar file (Through right click on project -> Properties -> Java Build Path -> Add Jars...)
There is nothing on the "Problems" tab, and if I try to run through the groovy console, I get the following error:
groovy.lang.MissingMethodException: No signature of method: groovy.xml.MarkupBuilder.records() is applicable for argument types: (com.neuro.groovyhelloworld.markupbuilderexercise.Main$_run_closure1) values: [com.neuro.groovyhelloworld.markupbuilderexercise.Main$_run_closure1#2e757861]
at com.neuro.groovyhelloworld.markupbuilderexercise.Main.run(Main.groovy:10)
at com.neuro.groovyhelloworld.markupbuilderexercise.Main.main(Main.groovy)
My take here is that I'm not adding the dependency in the right way, but I'm a Java developer and dependencies were either what I've done or just relying on Maven/Gradle, so I'm kind of out of ideas here.
What am I missing?
[1]: https://stackoverflow.com/questions/59132101/eclipse-groovy-unable-to-resolve-class
I see the same issue when choosing Run As > Groovy Console and then running the script. It does work fine for Run As > Groovy Script on the following source -- I used grab so I didn't need to add groovy-xml to my project's classpath:
#Grab('org.codehaus.groovy:groovy-xml:3.0.9')
import groovy.xml.MarkupBuilder
def writer = new StringWriter()
new MarkupBuilder(writer).tap {
records {
example(id:1)
}
}
print writer
I get the following output:
<records>
<example id='1' />
</records>
You can also build the project and run the script using Run As > Java Application.
I am running a test case and I want the code to automatically load the respective .json file .
Right now I am hardcoding the file ,but I want it loaded when the respective test class runs ,so looking to make it generic.
def setupSpec() {
config = (Map) new
JsonSlurper().parse(getClass().getResourceAsStream("wps.build.json"))
config.build = "Wps build ${new Date()}"
caps = bsLocal.defaultCaps
caps.setCapability("build", config.build)
caps.setCapability("browserstack.console", "info")
attempts = config.environments.size()
}```
This is the structure
https://imgur.com/g7a2B3n
I want to apply a certain behaviour to a label. When a lateral button is clicked, the corresponding label should rotate 90 degrees. It can be easily done in vala, but I can't discover the particular syntax on genie.
The vala code I am trying to reproduce comes from elementary OS getting started guide:
hello_button.clicked.connect(() =>
{
hello_label.label = "Hello World!";
hello_button.sensitive = false;
});
rotate_button.clicked.connect(() =>
{
rotate_label.angle = 90;
rotate_label.label = "Verbal";
rotate_button.sensitive = false;
});
I actually managed to reproduce almost entirely the code in Genie, for the exception of the rotation. Here is how far I got:
/* ANOTHER GTK EXPERIMENT WITH GENIE BASED ON ELEMENTARY INTRODUCTORY PAGE
** compile with valac --pkg gtk+03.0 layoutgtkexample.gs */
[indent=4]
uses Gtk
init
Gtk.init (ref args)
var window = new Gtk.Window()
window.title = "Hello World!"
window.set_border_width(12)
var layout = new Gtk.Grid ()
layout.column_spacing = 6
layout.row_spacing = 6
var hello_button = new Gtk.Button.with_label("Say Hello")
var hello_label = new Gtk.Label("Hello")
var rotate_button = new Gtk.Button.with_label ("Rotate")
var rotate_label = new Gtk.Label("Horizontal")
// add first row of widgets
layout.attach (hello_button, 0, 0, 1,1)
layout.attach_next_to (hello_label, hello_button, PositionType.RIGHT, 1, 1)
// add second row of widgets
layout.attach(rotate_button, 0,1,1,1)
layout.attach_next_to(rotate_label, rotate_button, PositionType.RIGHT, 1, 1)
window.add(layout)
hello_button.clicked.connect(hello_pushed)
rotate_button.clicked.connect(rotate_pushed)
window.destroy.connect(Gtk.main_quit)
window.show_all ()
Gtk.main ()
def hello_pushed (btn:Button)
btn.label = "Hello World!"
btn.sensitive = false
def rotate_pushed (btn:Button)
btn.label = "Vertical"
//btn.angle = 90
btn.sensitive = false
The problem is to do with where identifiers are valid and is known as "scope".
The Vala example makes use of an anonymous function, also called a lambda expression in Vala. An anonymous function can be a "closure", when the variables in the scope that defines the anonymous function are also available within the anonymous function. This is useful because the callback occurs after the original block of code has been run, but the variables are still available within the callback. So in the Vala example, where both the button and label are defined in the enclosing scope, the button and label are also available in the callback anonymous function.
Unfortunately Genie isn't able to parse anonymous functions as function arguments, in this case within the connect() call. Although some work has been done on this in 2015. So you have rightly used a function name instead. The problem is the callback only passes the button as an argument and not the adjacent label. So to make the label available within the callback function we could use a class:
/* ANOTHER GTK EXPERIMENT WITH GENIE BASED ON ELEMENTARY INTRODUCTORY PAGE
** compile with valac --pkg gtk+-3.0 layoutgtkexample.gs */
[indent=4]
uses Gtk
init
Gtk.init (ref args)
new RotatingButtonWindow( "Hello World!" )
Gtk.main ()
class RotatingButtonWindow:Window
_hello_label:Label
_rotate_label:Label
construct( window_title:string )
title = window_title
set_border_width(12)
var layout = new Grid ()
layout.column_spacing = 6
layout.row_spacing = 6
// add 'hello' row of widgets
var hello_button = new Button.with_label("Say Hello")
_hello_label = new Label("Hello")
layout.attach (hello_button, 0, 0, 1,1)
layout.attach_next_to (_hello_label, hello_button, PositionType.RIGHT, 1, 1)
// add 'rotate' row of widgets
var rotate_button = new Button.with_label ("Rotate")
_rotate_label = new Label("Horizontal")
layout.attach(rotate_button, 0,1,1,1)
layout.attach_next_to(_rotate_label, rotate_button, PositionType.RIGHT, 1, 1)
add(layout)
hello_button.clicked.connect(hello_pushed)
rotate_button.clicked.connect(rotate_pushed)
destroy.connect(Gtk.main_quit)
show_all ()
def hello_pushed (btn:Button)
_hello_label.label = "Hello World!"
btn.sensitive = false
def rotate_pushed (btn:Button)
_rotate_label.label = "Vertical"
_rotate_label.angle = 90
btn.sensitive = false
A few notes:
By placing the definitions of the _hello_label and _rotate_label within the scope of the class they become available to all the functions defined in the class. Definitions like this are often called "fields". The underscore means they are not available outside the class, so in the example you cannot access them from init
construct() is called when the object is created, in the example the line new RotatingButtonWindow( "Hello World!" ) instantiates the object. If you repeat the line you will have two separate windows, that is two instances of the RotatingButtonWindow data type
You will notice that the RotatingButtonWindow type is also defined as a Window type. This means it is adding more detail to the Gtk.Window class. This is why title and set_border_width() can be used within the new class. They have been "inherited" from the parent Gtk.Window class
By using the Gtk namespace with uses Gtk we don't need to prefix everything with Gtk
As your Gtk application gets more complex you probably want to look at GtkBuilder. That allows windows and widgets to be laid out in an external file. Then use GResource to build the file into the binary of your application so there is no need to distribute the UI file separately.
I want to fetch Total TestCase PASS and FAIL count for a build using groovy script. I am using Junit test results. I am using Multiconfiguration project , so is there any way to find this information on a per configuration basis?
If you use the plugin https://wiki.jenkins-ci.org/display/JENKINS/Groovy+Postbuild+Plugin, you can access the Jenkins TestResultAction directly from the build ie.
import hudson.model.*
def build = manager.build
int total = build.getTestResultAction().getTotalCount()
int failed = build.getTestResultAction().getFailCount()
int skipped = build.getTestResultAction().getSkipCount()
// can also be accessed like build.testResultAction.failCount
manager.listener.logger.println('Total: ' + total)
manager.listener.logger.println('Failed: ' + failed)
manager.listener.logger.println('Skipped: ' + skipped)
manager.listener.logger.println('Passed: ' + (total - failed - skipped))
API for additional TestResultAction methods/properties http://javadoc.jenkins-ci.org/hudson/tasks/test/AbstractTestResultAction.html
If you want to access a matrix build from another job, you can do something like:
def job = Jenkins.instance.getItemByFullName('MyJobName/MyAxisName=MyAxisValue');
def build = job.getLastBuild()
...
For Pipeline (Workflow) Job Type, the logic is slightly different from AlexS' answer that works for most other job types:
build.getActions(hudson.tasks.junit.TestResultAction).each {action ->
action.getTotalCount()
action.getFailCount()
action.getSkipCount()
}
(See http://hudson-ci.org/javadoc/hudson/tasks/junit/TestResultAction.html)
Pipeline jobs don't have a getTestResultAction() method.
I use this logic to disambiguate:
if (build.respondsTo('getTestResultAction')) {
//normal logic, see answer by AlexS
} else {
// pipeline logic above
}
I think you might be able to do it with something like this:
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
File fXmlFile = new File("junit-tests.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);
doc.getDocumentElement().normalize();
println("Total : " + doc.getDocumentElement().getAttribute("tests"))
println("Failed : " +doc.getDocumentElement().getAttribute("failures"))
println("Errors : " +doc.getDocumentElement().getAttribute("errors"))
I also harvest junit xml test results and use Groovy post-build plugin https://wiki.jenkins-ci.org/display/JENKINS/Groovy+Postbuild+Plugin to check pass/fail/skip counts. Make sure the order of your post-build actions has harvest junit xml before the groovy post-build script.
This example script shows how to get test result, set build description with result counts and also version info from a VERSION.txt file AND how to change overall build result to UNSTABLE in case all tests were skipped.
def currentBuild = Thread.currentThread().executable
// must be run groovy post-build action AFTER harvest junit xml
testResult1 = currentBuild.testResultAction
currentBuild.setDescription(currentBuild.getDescription() + "\n pass:"+testResult1.result.passCount.toString()+", fail:"+testResult1.result.failCount.toString()+", skip:"+testResult1.result.skipCount.toString())
// if no pass, no fail all skip then set result to unstable
if (testResult1.result.passCount == 0 && testResult1.result.failCount == 0 && testResult1.result.skipCount > 0) {
currentBuild.result = hudson.model.Result.UNSTABLE
}
currentBuild.setDescription(currentBuild.getDescription() + "\n" + currentBuild.result.toString())
def ws = manager.build.workspace.getRemote()
myFile = new File(ws + "/VERSION.txt")
desc = myFile.readLines()
currentBuild.setDescription(currentBuild.getDescription() + "\n" + desc)