Support Groovy configuration and functions
See original GitHub issueHello, and thank you for building an awesome API testing tool!
My organization is primarily a Java shop, and we use Groovy extensively for testing, DevOps tools, and other automation. In using Karate, it would streamline our development if we could define configuration and reusable functions in Groovy, rather than JavaScript. In my opinion, these aspects of Groovy make it a great fit for Karate:
- It is a JVM language
- Java interop is seamless
- Familiar Java-like syntax, but much more concise
- Dynamic language (like JavaScript), but with optional static typing
- Excellent functional programming features
- String interpolation
- Many other scripting-level features built into the Groovy language
It is worth noting that a number of popular enterprise-level technologies support Groovy configuration, including Gradle and Jenkins, which my company uses for build automation.
Here is an example usage, converted from the Karate README on “JavaScript Functions” to use a Groovy closure:
* def greeter = { name -> 'hello ' + name }
* assert greeter('Bob') == 'hello Bob'
Java interop is simpler (i.e., it just works):
* def dateStringToLong = { new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ").parse(it).time }
* assert dateStringToLong("2016-12-24T03:39:21.081+0000") == 1482550761081
Note that Groovy context can have automatic imports, in this case just adding import java.text.SimpleDateFormat
to the default imports for the Groovy script runner.
Calling functions with JSON arguments, and using string interpolation:
* def greeter = { name -> "Hello $name.first $name.last!" }
* def greeting = call greeter { first: 'John', last: 'Smith' }
Here is karate-config.groovy
, adapted from the karate-config.js
example:
// an example using Groovy's shorthand ternary operator "?:"
// for custom 'intelligent' defaults
env = karate.env ?: 'dev'
// string interpolation
karate.log("karate.env system property was: $env")
// native Java Map and List syntax
config = [
appId: 'my.app.id',
appSecret: 'my.secret',
someUrlBase: 'https://some-host.com/v1/auth/',
anotherUrlBase: 'https://another-host.com/v1/',
fallbackPorts: [9998, 9997]
]
// over-ride specific settings
if (env == 'stage') {
config.someUrlBase = 'https://stage-host/v1/auth'
} else if (env == 'e2e') {
config.someUrlBase = 'https://e2e-host/v1/auth'
}
// don't waste time waiting for a connection or if servers don't respond within 5 seconds
karate.configure('connectTimeout', 5000)
karate.configure('readTimeout', 5000)
return config
As you can see, although it looks Java-like, it has the dynamic power of JavaScript, but is more flexible. The script itself does not need to be wrapped in a function, there are no semi-colons, default imports can be added, any Java library can be easily added as a dependency and leveraged in the config script or reusable function, native Map and List syntax is easy and understandable, etc.
Is this a feature you would be willing to support? If so, I can volunteer to contribute it. Do let me know if you have any questions.
Thanks for the consideration!
Issue Analytics
- State:
- Created 5 years ago
- Comments:7 (4 by maintainers)
Top GitHub Comments
Just to follow up: after digging into the source code I realized that, as you said, this would be more than I bargained for. The JavaScript usage is baked in at many levels of this tool, so it cannot just be swapped out with another language. While I would much prefer to use Groovy with Karate, I don’t really mind writing the small amount of JavaScript where it is needed. Thus, I don’t anticipate actually making this contribution. Still, awesome tool, and I’m glad to be using it!
@ptrthomas Thanks for the overview, that helps provide a starting point. I will dig into it and see how it goes.