I am bumping into an issue in my integration test. My code uses a system property (System.getProperty(...) ) and I am not being able to set the system property when running the integration test. Any idea on how to define system properties that are visible inside code running in integration test?
I am using Grails 3.3.1.
Slimmed down example of integration test not seeing the system property:
package injecttest
import grails.testing.mixin.integration.Integration
import grails.transaction.*
import org.springframework.beans.factory.annotation.Autowired
import spock.lang.Specification
#Integration
#Rollback
class C1ITSpec extends Specification {
void "test system property readable inside test"() {
String val = System.getProperty("var1", "ERROR")
expect:"system variable to match value passed as '-Dvar1=OK' in command line"
"OK" == val
}
}
A new JVM is forked to run the test, so you have to pass the command-line system properties to the test's JVM.
In Grails 4, which uses gradle, you can pass the system properties in your gradle file:
integrationTest.doFirst {
systemProperties System.getProperties().subMap(["var1"])
}
I adapted this from the answers to this question for Grails 3: How to give System property to my test via Gradle and -D.
Related
Problem statement:
How to execute a function at the end of all specification files have been executed using spock framework.
Explantion: I am using geb-spock framework for automation.
I have few specification files. I want to run a function after all specification files have been executed.
I want something like AfterSuite in TestNG. How can i get the feature of AfterSuite in spock. cleanupSpec will be called after every specification file is executed.
Thanks,
Debasish
The simple answer is: no. There's nothing like before or after suite methods in spock since spock is JUnit based and JUnit does not handle such methods. If you siÄ™ tool like maven or gradle maybe you can use task's lifecycle methods.
You can use the JUnit 4 SuiteRunner Look at this answer
#RunWith(Suite.class)
#SuiteClasses({ TestSpec.class, TestSpec.class })
public class CompleteTestSuite {
#BeforeClass
public static void setUpClass() {
System.out.println("Master setup");
}
#AfterClass public static void tearDownClass() {
System.out.println("Master tearDown");
}
}
If you are using build tool as for example Gradle you may wire it on a build configuration level after tests are finished.
I am adding a first spock integration test to an existing set of tests for a grails 2.1.1 application. The test runs and tests pass when run using:
grails test-app integration:spock CreditServiceSpec
(Yes, everything is in the default package - fixing this is a ton of work that will not be approved...file under technical debt.)
However, when I run all the tests (grails test-app), unit test pass, spock unit tests pass, integration tests pass, but I get the following failure for spock integration:
| Completed 818 integration tests, 0 failed in 104001ms
| Running 1 spock test...
| Failure: CreditServiceSpec
| groovy.lang.GroovyRuntimeException: failed to invoke constructor: public org.codehaus.groovy.grails.test.support.GrailsTestAutowirer(org.springframework.context.ApplicationContext) with arguments: [] reason: java.lang.IllegalArgumentException
at grails.plugin.spock.IntegrationSpec.$spock_initializeSharedFields(IntegrationSpec.groovy:33)
| Completed 0 spock test, 0 failed in 33ms
| Tests PASSED - view reports in /Users/*/projects/GrailsPlugins/DomainServices/target/test-reports
I get the exact same exception whether I run the full test I built or the following, very strip down example:
import grails.plugin.spock.IntegrationSpec
class CreditServiceSpec extends IntegrationSpec {
def setup() {}
def cleanup() {}
public void "sample"() {
setup:"Nothing to do here."
expect:"This is the truest of truths..."
true == true
}
}
I did crack open IntegrationSpec and looked at line 33:
#Shared private autowirer = new GrailsTestAutowirer(applicationContext)
But determining how/why the applicationContext is not being passed in properly is beyond me and, perhaps, is the thrust of my question.
Has anyone encountered this kind of behavior and found a way to get spock integration to play nice with other tests? Thanks.
It looks like Grails 2.1.1 had several issues with Spock tests in the Integration scope. Jeff's comment and Peter's in particular sound like the issue you were having; basically the ApplicationHolder was null or an empty list.
The parent task lists Grails 2.2.5 as the fix version. Any chance you can upgrade to that (or some even later version) and see if the problem persists?
There have also been cases where a simple grails clean has fixed issues like this.
I had a problem with the exact same symptom.
I was using the BuildTestData plugin and used the #Build annotation in a IntegrationSpec, but using the #Build with use a transformation wich extended the #TestFor transformation which is incompatible with the Intengration runtime.
So just remove the #Build annotations and it will run.
In Grails 2.0.4, I'm trying to write a controller unit test which invokes the static SpringSecurityUtils.reauthenticate. The test returns a NullPointerException on that invocation. In a debugger, I can see that none of the Groovy dynamic properties (declaredMethods,etc.) of SpringSecurityUtils are populated.
I do note that when running the tests, the "Configuring Spring Security Core" log message is emitted after the unit-test failure. Here is a sample test:
class ReproTest {
void testSpringSecurityUtils() {
String.valueOf(true) // OK: a public final class from the JDK
URLUtils.isRelativeURL("foo") // OK: a class from another plugin
SpringSecurityUtils.reauthenticate "user", "pw" // fails, NPE
}
}
My initial reaction is that maybe plugins aren't accessible during unit tests, but if so, why is the URLUtils call working? And why does the test get "far enough" to initialize the plugin, but after the tests have completed?
For a unit test the container isn't starting up. No Spring injection or "grails goodness" is happening. You see in the logs that the plugin is initializing after the unit tests run, because it [container] does start for the integration tests. If you want to test the SpringSecurityUtils, although guessing it is already tested properly in the plugin, you would want to write an integration test.
I am trying to get some geb tests running in a Grails project within IntelliJ but am having trouble & after 2 days of web searching & trying different things am still stuck. We did have some Groovy tests running fine, previously, but no luck so far with geb. We're using cucumber-jvm.
Currently I am getting the following error:
Error Error executing script TestApp: groovy.lang.MissingMethodException:
No signature of method: GebConfig.environments() is applicable for argument types:
(GebConfig$_run_closure2) values: [GebConfig$_run_closure2#4ad3727e]
My GebConfig.groovy file is in test/functional, and contains:
import org.openqa.selenium.htmlunit.HtmlUnitDriver
import org.openqa.selenium.firefox.FirefoxDriver
import org.openqa.selenium.chrome.ChromeDriver
// Use htmlunit as the default
// See: http://code.google.com/p/selenium/wiki/HtmlUnitDriver
driver = {
def driver = new HtmlUnitDriver()
driver.javascriptEnabled = true
driver
}
environments {Not sure
chrome {-Dgeb.env=chrome
driver = { new ChromeDriver() }
}
firefox {
driver = { new FirefoxDriver() }
}
}
I have the .feature file also in test/functional. The step def's are in test/functional/steps & contains:
package steps
import geb.*
this.metaClass.mixin (cucumber.runtime.groovy.EN)
this.metaClass.mixin (cucumber.runtime.groovy.Hooks)
def browser = new Browser()
Given (~"I am on the front page") {
browser.go("http://localhost:8081/whereisOne")
}
There is also a shared_driver.groovy class in test/functional/setup that was created for the straight Groovy tests, & I'm not sure if this is still needed.
The run config command is: test-app --stacktrace, with VM options: -Dgeb.env=chrome
Any help appreciated, thank you!
Is the -Dgeb.env=chrome in the code? If so, you have to remove this line. Everything else looks fine.
My original issue is described perfectly by this post: I want to follow TDD:
write a small test
watch it fail
write just enough code to make it succeed
watch it succeed
repeat
I am working on a Grails project in IntelliJ. If all I want is to write normal JUnit tests, the above post solves everything:
Head to /test/unit
Put some test code in a "class Xyz extends GroovyTestCase" class
Hit Shift F10
JUnit report pops up within a second or two
The problem is that I would like to use one of the very cool "describe-in-english" testing setups, like Easyb or Spock.
What do I do? It would be magic to just start with the auto-generated Test class Grails makes for me, then cram Spock stuff into it. Obviously I can't use "extends" twice. Does this give the gist of what I'm trying to do though?
class Xyz extends GroovyTestCase extends spock.lang.Specification {
//void testSomething() {
// fail "Implement me"
//}
def "length of Spock's and his friends' names"() {
expect:
name.size() == length
where:
name | length
"Spock" | 5
"Kirk" | 4
"Scotty" | 6
}
}
Extend spock classes, not groovy's. You can choose from UnitSpec, ControllerSpec, IntegrationSpec and others as listed in source code. Spock will take care of the rest.
-Use "grails install-templates"
-Change the Tests templates to something along the lines of:
#artifact.package#
import grails.test.mixin.*
import org.junit.*
import spock.lang.Specification
#TestFor(#artifact.testclass#)
class #artifact.name# extends Specification {
}
-Write the test code in Spock (or normal JUnit code)
-IntelliJ->Run->Edit Configurations. Add New Configuration of the JUnit type. Test kind: <All in package/All in UnitTest directory/All in one UnitTest class/etc.>
-(Shortcut: Cursor over method name, or class name->ctrl-shift-F10)
On my original question:
In retrospect, I was getting hung-up on the "run all in directory" part of that blog post. Current IntelliJ DOES let you run all JUnit tests in a directory, or the entire project.
Once I understood that, the next step was to realize that Spock tests ARE JUnit tests. Make a "class Xyz extends Specification {}" class in the test/unit directory, fill it with Spock code, and Run as... JUnit. Magic!