How to Enable/Disable Particular Assertion in all Test Case using Groovy? - groovy

I have suite to run the regression Test Case in Soap UI. It has a Assertion Capture Response which measures the time of each request. This is needed on demand.
If metrics needed then I need to Enable the Capture Response Time assertion and if it is not needed then I don't need the capture response time.
I have written the below code to check that whether it is disabled or not. If it is disabled then OK else i need to disable it.
The following code returns
java.lang.NullPointerException: Cannot get property 'disabled' on null object.
Can any one help on this?
def project = testRunner.getTestCase().getTestSuite().getProject().getWorkspace().getProjectByName("Regression");
//Loop through each Test Suite in the project
for(suite in project.getTestSuiteList())
{
//log.info(suite.name)
//Loop through each Test Case
if(suite.name == "ReusableComponent")
{
for(tcase in suite.getTestCaseList())
{
log.info(tcase.name)
for(tstep in tcase.getTestStepList())
{
stepName = tstep.name
suiteName=suite.name
caseName=tcase.name
def testStep = testRunner.testCase.testSuite.project.testSuites["$suiteName"].testCases["$caseName"].getTestStepByName("$stepName")
log.info(testStep.getAssertionByName("CaptureResponseTime").disabled)
}
}
}
}

Below statement is causing NullPointerException:
log.info(testStep.getAssertionByName("CaptureResponseTime").disabled)
In order to avoid NPE, then change it to:
log.info(testStep.getAssertionByName("CaptureResponseTime").isDisabled)
If you need to disable the assertion, then use below statement:
testStep.getAssertionByName("CaptureResponseTime")?.disabled = true
Another input:
In order to get the project, do not use workspace.
Instead use:
def project = context.testCase.testSuite.project

Related

Excluding testcases from testsuite properties in Soapui

I want to disable certain test cases based on the value of some test suite properties (i.e if the property IsActive1 = false, then testcase1 will be disabled).
I used this code at test suite setup script but got an error:
def testSuite = context.testCase.testSuite;
def totalTestCases = testSuite.getTestCases().size();
for(n in (0..totalTestCases-1)) {
if(testSuite.getTestCaseAt(n).name == "${#TestSuite#IsActive}"){
testSuite.getTestCaseAt(n).setDisabled(true)
}
}
How can I do that?
Here is how I would go to achieve this.
Assuming that there is a suite with test cases, namely TestCase1, TestCase2, TestCase3, TestCase4, TestCase5. Using this approach, it would be a simple change of the property value to include or exclude the test case name to be disable. I believe that this would be better to change things from one place(single property) instead of changing IsActive property for each test case. If you have more cases to handle this would be a burden (going to each case and modify true or false for IsActive)
Create a custom property at test suite level, say DISABLE_TESTS with value (comma separated list to disable) as TestCase1, TestCase5
Here is the Setup Script at Suite level which would achieve to selectively execute the test cases.
/**
* Test Suite Setup Script
* Enable or disable selected list of test cases
* Based on the test suite property DISABLE_TESTS value
**/
//Disables a Test case
def disableTestCase(testCaze) {
log.info "Disabling test case : ${testCaze.name}"
testCaze.disabled = true
}
//Enables a Test case
def enableTestCase(testCaze) {
log.info "Enabling test case : ${testCaze.name}"
testCaze.disabled = false
}
//Read the test case names to enable and convert it to list
def disableList = testSuite.getPropertyValue('DISABLE_TESTS')?.split(',')?.collect { it.trim()} ?: []
log.info "List of test for disable: ${disableList}"
//Loop thru the test cases and enable or disable
testSuite.testCaseList.each { kase ->
//If the above list contains test case name disable, enable otherwise
if (disableList && disableList.contains(kase.name)) {
disableTestCase(kase)
} else {
enableTestCase(kase)
}
}
Since some of the cases are disabled, it would be good to enable all the cases as part of Test Suite Teardown Script. It would look mostly same, but there wont be any condition.
/**
* Test Suite Teardown Script
* Which enables all the test cases after selective execution
**/
//Enables a Test case
def enableTestCase(testCaze) {
log.info "Enabling test case : ${testCaze.name}"
testCaze.disabled = false
}
//Loop thru the test cases and enable
testSuite.testCaseList.each { kase ->
enableTestCase(kase)
}
You can do that with a Groovy script. You could place this script in the Setup script tab on testSuite Window, in order that the script is executed before your testSuite, disabling/enabling testCases depending on the properties.
Based on your requeriments this script could be something like:
// get property names getting only
// the one which start with "isactive"
def isActiveList = testSuite.getPropertyNames().findAll {
it.toLowerCase().startsWith('isactive')
}
log.info isActiveList
// get testCaseList in order
def testCaseList = testSuite.getTestCaseList()
// for each "isactive" property
// enable or disable the corresponding
// testCase
isActiveList.each{ name ->
// get the value
def isActive = testSuite.getPropertyValue(name).toBoolean()
// get the order from the property name
def testCaseIndex = name.toLowerCase() - 'isactive'
log.info "testCase at index $testCaseIndex will be disabled ${!isActive}"
// get the testCase and enable/disable depend
// on isactive property
// NOTE: IsActive1 corresponds to array pos 0
// so a -1 is necessary
log.info testCaseList[testCaseIndex.toInteger()-1]?.disabled = !isActive
}
Maybe it's better to rename your properties based on the testCase name's to enable/disable instead of using a number; to avoid undesired behaviors if you change i.e the testCase order or add a new one...
Hope it helps,

how to test the JSonResult in xunit test case?

I am doing unit testing with xunit (ASP.NET MVC).
I have written Action in controller which returns JsonResult.
For returning JsonResult, in Action I have written:
return Json(new { ok = true, newurl = Url.Action("Login") });
For testing the action, I have written in unit test case as:
JsonResult jsonResult = _accountController.ForgotPassword(ValidUserName) as JsonResult;
Assert.Equal("{ ok = true, newurl = Url.Action('Login') }", jsonResult.Data.ToString());
But, it's not working. Please guide me to correct it.
I would suggest debugging your unit test and looking at the value returned by jsonResult.Data.ToString(). My guess is newurl doesn't contain what you think it does. Assuming you're using VS2013 you can easily debug a unit test by setting a breakpoint, right-click inside the test method body, and select Debug Tests.
An alternative approach to verifying the information is to cast the JsonResult.Data to a dynamic. This allows you to compare each property individually instead of stringifying the JSON and comparing the results. This approach is, in my opinion, cleaner when the JSON becomes larger than a few properties.
var dynData = (dynamic)jsonResult.Data;
Assert.IsTrue( (bool)dynData.ok );
Assert.AreEqual( Url.Action("Login"), (string)dynData.newurl );

How to fail a script assertion in SoapUI?

I'm trying to let a script assertion fail, when a variable has another value than defined. My goal: Mark the TestStep as red, if the TestStep will fail. Please note that I am using a script assertion for a TestStep - not a separate Groovy-Script TestStep.
My script looks like this:
httpResponseHeader = messageExchange.responseHeaders
contentType = httpResponseHeader["Content-Type"]
log.info("Content-Type: " + contentType)
if (contentType != "[image/jpeg]"){
log.info("ERROR! Response is not an image.")
//Script Assertion should fail.
//TestStep should be marked red.
} else {
log.info("OK! ResponseType is an image.")
}
Is there any way, how to let the script assertion fail depending on a property?
I've tried to use the getStatus() method, but this is only available for the testrunner object. Unfortunately the testRunner-object can not be used within a script assertion concerning this post: http://forum.soapui.org/viewtopic.php?f=2&t=2494#p9107
Need to assert so that test fails or passes automatically based on the condition.
def httpResponseHeader = messageExchange.responseHeaders
def contentType = httpResponseHeader["Content-Type"]
log.info("Content-Type: " + contentType)
assert contentType.get(0) == "image/jpeg","Content Type is not an image"
EDIT: Earlier paid attention to how to throw error, assuming you have the rest in place. Now changed last line of code based on the input.

Testng SoftAssert always returns null

I'm using a softassert in testNG from org.testng.asserts.SoftAssert
I'm testing something very basic - the title - just to see if I can get the soft assert to work and to put feedback in the report if it fails. Problem is, in either case where the assertion should pass or fail, it just always returns null.
#Test
void doTest()
{
driver.get("URL")
System.out.println(driver.getTitle())
l_assert.assertEquals(driver.getTitle(), "String")
l_assert.assertAll()
}
This always returns null
Probably the problem is that you didn't initialize it. You have to have this somewhere:
l_assert = new SoftAssert();
Try to use next example:
l_assert.assertEquals(driver.getTitle(), "String", "Error Message Should Be Here");

How to Report Results to Sauce Labs using Geb/Spock?

I want to use the Sauce Labs Java REST API to send Pass/Fail status back to the Sauce Labs dashboard. I am using Geb+Spock, and my Gradle build creates a test results directory where results are output in XML. My problem is that the results XML file doesn't seem to be generated until after the Spock specification's cleanupSpec() exits. This causes my code to report the results of the previous test run, rather than the current one. Clearly not what I want!
Is there some way to get to the results from within cleanupSpec() without relying on the XML? Or a way to get the results to file earlier? Or some alternative that will be much better than either of those?
Some code:
In build.gradle, I specify the testResultsDir. This is where the XML file is written after the Spock specifications exit:
drivers.each { driver ->
task "${driver}Test"(type: Test) {
cleanTest
systemProperty "geb.env", driver
testResultsDir = file("$buildDir/test-results/${driver}")
systemProperty "proj.test.resultsDir", testResultsDir
}
}
Here is the setupSpec() and cleanupSpec() in my LoginSpec class:
class LoginSpec extends GebSpec {
#Shared def SauceREST client = new SauceREST("redactedName", "redactedKey")
#Shared def sauceJobID
#Shared def allSpecsPass = true
def setupSpec() {
sauceJobID = driver.getSessionId().toString()
}
def cleanupSpec() {
def String specResultsDir = System.getProperty("proj.test.resultsDir") ?: "./build/test-results"
def String specResultsFile = this.getClass().getName()
def String specResultsXML = "${specResultsDir}/TEST-${specResultsFile}.xml"
def testsuiteResults = new XmlSlurper().parse( new File( specResultsXML ))
// read error and failure counts from the XML
def errors = testsuiteResults.#errors.text()?.toInteger()
def failures = testsuiteResults.#failures.text()?.toInteger()
if ( (errors + failures) > 0 ) { allSpecsPass = false }
if ( allSpecsPass ) {
client.jobPassed(sauceJobID)
} else {
client.jobFailed(sauceJobID)
}
}
}
The rest of this class contains login specifications that do not interact with SauceLabs. When I read the XML, it turns out that it was written at the end of the previous LoginSpec run. I need a way to get to the values of the current run.
Thanks!
Test reports are generated after a Specification has finished execution and the generation is performed by the build system, so in your case by Gradle. Spock has no knowledge of that so you are unable to get that information from within the test.
You can on the other hand quite easily get that information from Gradle. Test task has two methods that might be of interest to you here: addTestListener() and afterSuite(). It seems that the cleaner solution here would be to use the first method, implement a test listener and put your logic in afterSuite() of the listener (and not the task configuration). You would probably need to put that listener implementation in buildSrc as it looks like you have a dependency on SauceREST and you would need to build and compile your listener class before being able to use it as an argument to addTestListener() in build.gradle of your project.
Following on from erdi's suggestion, I've created a Sauce Gradle helper library, which provides a Test Listener that parses the test XML output and invokes the Sauce REST API to set the pass/fail status.
The library can be included by adding the following to your build.gradle file:
import com.saucelabs.gradle.SauceListener
buildscript {
repositories {
mavenCentral()
maven {
url "https://repository-saucelabs.forge.cloudbees.com/release"
}
}
dependencies {
classpath group: 'com.saucelabs', name: 'saucerest', version: '1.0.2'
classpath group: 'com.saucelabs', name: 'sauce_java_common', version: '1.0.14'
classpath group: 'com.saucelabs.gradle', name: 'sauce-gradle-plugin', version: '0.0.1'
}
}
gradle.addListener(new SauceListener("YOUR_SAUCE_USERNAME", "YOUR_SAUCE_ACCESS_KEY"))
You will also need to output the Selenium session id for each test, so that the SauceListener can associate the Sauce Job with the pass/fail status. To do this, include the following output in the stdout:
SauceOnDemandSessionID=SELENIUM_SESSION_ID

Resources