Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
#ACCU2016 ACCU Bristol 2016
USING THE GROOVY
ECOSYSTEM FOR RAPID
JVM DEVELOPMENT
Schalk W. Cronjé
1
ABOUT ME
Email:
Twitter / Ello : @ysb33r
ysb33r@gmail.com
2
 
3 . 1
SDKMAN
Manages parallel version of multiple SDKs
Mostly for (but not limited to) JVM-related systems
Windows users c...
3 . 2
SDKMAN DEMO
3 . 3
 
SdkMan:
Posh-GVM:
@sdkmanager
http://sdkman.io
https://github.com/ ofreud/posh-gvm
3 . 4
APACHE GROOVY
A dynamic & static typed language for the JVM with REPL
capability.
4 . 1
GROOVY VS JAVA
In Groovy:
All class members are public by default
No need to create getters/setters for public elds
...
4 . 2
CALLING METHODS
class Foo {
void bar( def a,def b ) {}
}
def foo = new Foo()
foo.bar( '123',456 )
foo.bar '123', 456...
4 . 3
CALLING METHODS WITH CLOSURES
class Foo {
void bar( def a,Closure b ) {}
}
def foo = new Foo()
foo.bar( '123',{ prin...
4 . 4
MAPS IN GROOVY
Hashmaps in Groovy are simple to use
def myMap = [ plugin : 'java' ]
Maps are easy to pass inline to ...
4 . 5
LISTS IN GROOVY
Lists in Groovy are simple too
def myList = [ 'clone', 'http://github.com/ysb33r/GradleLectures' ]
T...
4 . 6
CLOSURE DELEGATION IN GROOVY
When a symbol cannot be resolved within a closure,
Groovy will look elsewhere
In Groovy...
4 . 7
CLOSURE DELEGATION IN GROOVY
class Foo {
def target
}
class Bar {
Foo foo = new Foo()
void doSomething( Closure c ) ...
4 . 8
MORE CLOSURE MAGIC
If a Groovy class has a method call(Closure), the object
can be passed a closure directly.
class ...
4 . 9
SMOOTH OPERATOR: ELVIS
?:
// Selecting a default value if variable is not set
String a
String b = 'def'
// Prints 'f...
4 . 10
SMOOTH OPERATOR: SAFE NAVIGATION
?.
// Returns a value if not-null, otherwise null
String a
String b = 'def'
assert...
4 . 11
4 . 12
SMOOTH OPERATOR: SPREAD
*.
// Apply operation to each member in collection
def a = [ 'a','bb','c' ]
assert a...
STATIC VS DYNAMIC
By default code in Groovy is compiled with dynamic typing.
Typing can be modifed by selective applicatio...
4 . 13
IS GROOVY SLOWER THAN JAVA?
Yes and No.
Context is critical
Russell Winder has done number of experiments
JSON pars...
4 . 14
APACHE GROOVY
Apache Groovy home
Documentation
Twitter
@ApacheGroovy
http://groovy-lang.org/
http://groovy-lang.org...
4 . 15
5 . 1
 
5 . 2
GRADLE
Very modern, next-generation build & deployment pipeline
tool
DSL is based on Groovy
Vast collection of plugi...
GRADLE
apply plugin : 'groovy'
repositories {
jcenter()
}
dependencies {
testCompile 'org.spockframework:spock-core:1.0-gr...
5 . 3
GRADLE
Make it easy to integrate development and complex testing
Deploy local & to remote sites via plugins
Use Dock...
5 . 4
GRADLE JVM POLYGOT
Build a distributable application packaged as as ZIP
Runnable via shell script or batch le
Contai...
5 . 5
GRADLE JVM POLYGOT
apply plugin : 'java'
apply plugin : 'groovy'
apply plugin : 'com.zoltu.kotlin'
apply plugin : 'a...
5 . 6
GRADLE DEPENDENCY MANAGEMENT
Easy to use
Flexible to con gure for exceptions
Uses dependencies closure
First word on...
5 . 7
GRADLE REPOSITORIES
Speci ed within a repositories closure
Processed in listed order to look for dependencies
jcente...
5 . 8
GRADLE REPOSITORIES
repositories {
jcenter()
mavenCentral()
maven { url "https://plugins.gradle.org/m2/" }
ivy {
url...
5 . 9
BUILDSCRIPT
The buildscript closure is special
It tells Gradle what to load into the classpath before
evaluating the...
5 . 10
EXTENSIONS
Extensions are global con guration blocks added by
plugins.
Example: The jruby-gradle-base plugin will a...
5 . 11
GRADLE TASKS
Can be based upon a task type
task runSomething ( type : Exec ) {
command 'git'
args 'clone', 'https:/...
5 . 12
5 . 13
GRADLE: BUILDING C++
apply plugin : 'cpp'
GRADLE: BUILDING C++
Need to change convention from traditional C++ projects
.cpp les go in src/${name}/cpp
Exported heade...
5 . 14
5 . 15
BUILDING C++: PROJECT LAYOUT
├── build.gradle
└── src
└─── hello
   ├── cpp
│ └─── hello.cpp
│
   └── header...
5 . 16
BUILDING C++: EXISTING PROJECTS
Source directories can be adjusted
Alternative compiler locations
5 . 17
BUILDING C++: ALTERNATIVE SOURCE
sources {
cpp {
source {
srcDir "myDir"
include "**/*.cpp"
}
}
}
BUILDING C++: TOOL SUPPORT
Operating
System
Tool Chain Of cial
Linux gcc, clang Y
MacOS X Xcode Y
gcc-macports, clang-
mac...
Unix-like gcc, clang N
5 . 18
5 . 19
BUILDING C++: EXECUTABLE
model {
components {
hello(NativeExecutableSpec)
}
}
BUILDING C++: CUSTOM COMPILER
model {
toolChains {
gcc(Gcc) {
path '/installed/in/foo/dir/gcc'
eachPlatform {
cppCompiler....
5 . 20
BUILDING C++: OTHER FEATURES
Cross compilation
Multi-architecture targets
Set compiler & linker ags
Multi-variant b...
5 . 21
BUILDING C++: WEAKNESS
Currently only have built-in support for CUnit
Only platform con guration tool support is CM...
5 . 22
 
Website:
Plugins Portal:
User Forum:
@gradle
@DailyGradle
http://gradle.org
http://plugins.gradle.org
http://disc...
5 . 23
 
http://leanpub.com/idiomaticgradle
6
LET’S REVIEW OUR TESTS
7 . 1
LET’S GET UNIT TESTING
class CalculatorSpec extends Specification {
def "A calculator must be able to add numbers"()...
7 . 2
WHEN THIS TEST FAILS
7 . 3
WHEN THIS TEST FAILS
7 . 4
SPOCK FRAMEWORK
Built on top of JUnit 4.x.
Use it with all your JUnit tools!
Use for more than just unit tests.
Mock...
7 . 5
DATA-DRIVEN TESTS
@Unroll
def "A calculator must be able to multiply"() {
given: 'That I have a multiplying calculat...
7 . 6
ANOTHER COOL FAILURE REPORT
7 . 7
HANDLING EXCEPTIONS
def "Dividing by zero should throw an exception"() {
given: 'That I have a dividing calculator'
...
7 . 8
MOCK OUT INTERFACES
public interface RemoteCalculator {
public Number plus(Number... args);
}
def "Remote calculator...
7 . 9
SPOCK FRAMEWORK
Spock Framework:
Spock Reports
http://spockframework.github.io/spock/docs/1.0/index.html
https://git...
7 . 10
WEBSITE TESTING
One of the most predominant area of testing of this decade
Test-driven webpage development is less ...
8 . 1
TRIVIAL TEST EXAMPLE
def "Learn about testing checkboxes"() {
when: "I go to that the-internet site"
go "${webroot}/...
8 . 2
9 . 1
 
GEB
Integrates with
Spock Framework
JUnit
TestNG
Cucumber-JVM
Makes Selenium readable
Anything you can do in Selenium you ...
9 . 2
TRIVIAL TEST EXAMPLE COMPLETE
class CheckboxExampleSpec extends GebSpec {
def "Learn about testing checkboxes"() {
w...
9 . 3
GRABBING SCREENSHOTS
class CheckboxReportingSpec extends GebReportingSpec {
def 'Learn about testing checkboxes'() {...
9 . 4
GRABBING SCREENSHOTS
9 . 5
 
@GemFramework
http://gebish.org
9 . 6
10 . 1
 
10 . 2
RATPACK FRAMEWORK
Set of Java libraries for building modern HTTP applications.
Built on Java 8, Netty and reactive ...
RATPACK QUICKSTART SERVER
@Grapes([
@Grab('io.ratpack:ratpack-groovy:1.2.0'),
@Grab('org.slf4j:slf4j-simple:1.7.12')
])
im...
10 . 3
10 . 4
RATPACK’S TESTHTTPCLIENT
Can be used standalone
Use maven coordinates:
io.ratpack:ratpack-test:1.2.0
RATPACK’S TESTHTTPCLIENT
ApplicationUnderTest app = new ApplicationUnderTest() {
@Override
URI getAddress() { "http://127....
10 . 5
QUICK HTTP TESTING
Quickly point to a remote or in-process server
Build payload in a simplistic manner
Execute the ...
10 . 6
QUICK HTTP TESTING
def "The echo path should return what is send to it"() {
given: "A simple text request"
requestS...
10 . 7
OTHER GR8-UNIVERSE TOOLS
Grails - Build web applications fast
Griffon - Best way to build desktop apps
Grooscript -...
11
THANK YOU
Schalk W. Cronjé
Email: ysb33r@gmail.com
Twitter: @ysb33r
12
BITS & PIECES
13
GROOVY VFS
def vfs = new VFS()
vfs {
cp 'ftp://some.server/pub/file0.txt?vfs.ftp.passiveMode=1',
'sftp://user:pass@anot...
14
15
SSHOOGR
remoteSession('user:pass@another.server') {
exec 'rm -rf ~/tmp/*'
exec 'touch this.file'
remoteFile('this.fi...
16
GROOSCRIPT
http://grooscript.org/
THANK YOU
Schalk W. Cronjé
Email: ysb33r@gmail.com
Twitter: @ysb33r
17
ABOUT THIS PRESENTATION
Written in Asciidoctor (1.5.3.2)
Styled by asciidoctor-revealjs extension
Built using:
Gradle
g...
Upcoming SlideShare
Loading in …5
×

Using the Groovy Ecosystem for Rapid JVM Development

620 views

Published on

Overviewing Ratpack, Geb, Spock & Gradle to help with rapid development on the JVM. Mentions of other Gr8 tools & libraries. Swift introduction to Groovy.

Published in: Software
  • Be the first to comment

Using the Groovy Ecosystem for Rapid JVM Development

  1. 1. #ACCU2016 ACCU Bristol 2016 USING THE GROOVY ECOSYSTEM FOR RAPID JVM DEVELOPMENT Schalk W. Cronjé
  2. 2. 1 ABOUT ME Email: Twitter / Ello : @ysb33r ysb33r@gmail.com
  3. 3. 2  
  4. 4. 3 . 1 SDKMAN Manages parallel version of multiple SDKs Mostly for (but not limited to) JVM-related systems Windows users can use Posh-GVM (Powershell) Windows 10 Bash ?? curl -s http://get.sdkman.io | bash
  5. 5. 3 . 2 SDKMAN DEMO
  6. 6. 3 . 3   SdkMan: Posh-GVM: @sdkmanager http://sdkman.io https://github.com/ ofreud/posh-gvm
  7. 7. 3 . 4 APACHE GROOVY A dynamic & static typed language for the JVM with REPL capability.
  8. 8. 4 . 1 GROOVY VS JAVA In Groovy: All class members are public by default No need to create getters/setters for public elds Both static & dynamic typing supported def means Object
  9. 9. 4 . 2 CALLING METHODS class Foo { void bar( def a,def b ) {} } def foo = new Foo() foo.bar( '123',456 ) foo.bar '123', 456 foo.with { bar '123', 456 }
  10. 10. 4 . 3 CALLING METHODS WITH CLOSURES class Foo { void bar( def a,Closure b ) {} } def foo = new Foo() foo.bar( '123',{ println it } ) foo.bar ('123') { println it } foo.bar '123', { println it }
  11. 11. 4 . 4 MAPS IN GROOVY Hashmaps in Groovy are simple to use def myMap = [ plugin : 'java' ] Maps are easy to pass inline to functions project.apply( plugin : 'java' ) Which can also be written as project.with { apply plugin : 'java' }
  12. 12. 4 . 5 LISTS IN GROOVY Lists in Groovy are simple too def myList = [ 'clone', 'http://github.com/ysb33r/GradleLectures' ] This makes it possible write a method call as args 'clone', 'http://github.com/ysb33r/GradleLectures'
  13. 13. 4 . 6 CLOSURE DELEGATION IN GROOVY When a symbol cannot be resolved within a closure, Groovy will look elsewhere In Groovy speak this is called a Delegate. This can be programmatically controlled via the Closure.delegate property.
  14. 14. 4 . 7 CLOSURE DELEGATION IN GROOVY class Foo { def target } class Bar { Foo foo = new Foo() void doSomething( Closure c ) { c.delegate = foo c() } } Bar bar = new Bar() bar.doSomething { target = 10 }
  15. 15. 4 . 8 MORE CLOSURE MAGIC If a Groovy class has a method call(Closure), the object can be passed a closure directly. class Foo { def call( Closure c) { /* ... */ } } Foo foo = new Foo() foo { println 'Hello, world' } // This avoids ugly syntax foo.call({ println 'Hello, world' })
  16. 16. 4 . 9 SMOOTH OPERATOR: ELVIS ?: // Selecting a default value if variable is not set String a String b = 'def' // Prints 'foo' println a ?: 'foo' // Print 'def' println b ?: 'foo'
  17. 17. 4 . 10 SMOOTH OPERATOR: SAFE NAVIGATION ?. // Returns a value if not-null, otherwise null String a String b = 'def' assert a?.size() == null assert b?.size() == 3 println a.size() // Throws NPE
  18. 18. 4 . 11 4 . 12 SMOOTH OPERATOR: SPREAD *. // Apply operation to each member in collection def a = [ 'a','bb','c' ] assert a*.size() == [ 1,2,1 ]
  19. 19. STATIC VS DYNAMIC By default code in Groovy is compiled with dynamic typing. Typing can be modifed by selective application of annotations: @CompileStatic - compile static typing @CompileDynamic - compile dynamic typing @TypeChecked - compile dynamic, but check types Apply to classes & methods.
  20. 20. 4 . 13 IS GROOVY SLOWER THAN JAVA? Yes and No. Context is critical Russell Winder has done number of experiments JSON parsing in Groovy is faster than Java. Develop rst, measure, then optimise! Remember C++ → C → Assembler optimisation?
  21. 21. 4 . 14 APACHE GROOVY Apache Groovy home Documentation Twitter @ApacheGroovy http://groovy-lang.org/ http://groovy-lang.org/documentation.html
  22. 22. 4 . 15 5 . 1  
  23. 23. 5 . 2 GRADLE Very modern, next-generation build & deployment pipeline tool DSL is based on Groovy Vast collection of plugins
  24. 24. GRADLE apply plugin : 'groovy' repositories { jcenter() } dependencies { testCompile 'org.spockframework:spock-core:1.0-groovy-2.4' testCompile "org.gebish:geb-spock:0.13.0" testCompile "org.seleniumhq.selenium:selenium-api:2.53.0" testRuntime "org.seleniumhq.selenium:selenium-support:2.53.0" testRuntime "org.seleniumhq.selenium:selenium-firefox-driver:2.53.0" }
  25. 25. 5 . 3 GRADLE Make it easy to integrate development and complex testing Deploy local & to remote sites via plugins Use Docker local & remote "I do not have means to test on my machine" becomes less of an argument.
  26. 26. 5 . 4 GRADLE JVM POLYGOT Build a distributable application packaged as as ZIP Runnable via shell script or batch le Contains classes written Java, Groovy & Kotlin source Test source code with Spock Framework
  27. 27. 5 . 5 GRADLE JVM POLYGOT apply plugin : 'java' apply plugin : 'groovy' apply plugin : 'com.zoltu.kotlin' apply plugin : 'application' repositories { jcenter() } dependencies { compile 'org.codehaus.groovy:groovy-all:2.4.3' compile 'org.jetbrains.kotlin:kotlin-stdlib:1.0.1-1' testCompile 'org.spockframework:spock-core:1.0-groovy-2.4' } version = '1.0' mainClassName = "gradle.workshop.HelloJava"
  28. 28. 5 . 6 GRADLE DEPENDENCY MANAGEMENT Easy to use Flexible to con gure for exceptions Uses dependencies closure First word on line is usually name of a con guration. Con gurations are usually supplied by plugins. Dependencies are downloaded from repositories Maven coordinates are used as format
  29. 29. 5 . 7 GRADLE REPOSITORIES Speci ed within a repositories closure Processed in listed order to look for dependencies jcenter() preferred open-source repo. mavenLocal(), mavenCentral(), maven {} Ivy repositories via ivy {} Flat-directory repositories via flatDir
  30. 30. 5 . 8 GRADLE REPOSITORIES repositories { jcenter() mavenCentral() maven { url "https://plugins.gradle.org/m2/" } ivy { url 'file://path/to/repo' layout 'pattern', { artifact '[module]/[revision]/[artifact](.[ext])' ivy '[module]/[revision]/ivy.xml' } } }
  31. 31. 5 . 9 BUILDSCRIPT The buildscript closure is special It tells Gradle what to load into the classpath before evaluating the script itself. It also tells it where to look for those dependencies. Even though Gradle 2.1 has added a new way of adding external plugins, buildscript are much more exible.
  32. 32. 5 . 10 EXTENSIONS Extensions are global con guration blocks added by plugins. Example: The jruby-gradle-base plugin will add a jruby block. apply plugin: 'com.github.jruby-gradle.base' jruby { defaultVersion = '1.7.11' }
  33. 33. 5 . 11 GRADLE TASKS Can be based upon a task type task runSomething ( type : Exec ) { command 'git' args 'clone', 'https://bitbucket.com/ysb33r/GradleWorkshop' } Can be free-form task hellowWorld << { println 'Hello, world' }
  34. 34. 5 . 12 5 . 13 GRADLE: BUILDING C++ apply plugin : 'cpp'
  35. 35. GRADLE: BUILDING C++ Need to change convention from traditional C++ projects .cpp les go in src/${name}/cpp Exported headers les go in src/${name}/headers Local header les should be in src/${name}/cpp Object les will end up in ${buildDir}/objs Binary les will end up in ${buildDir}/binaries
  36. 36. 5 . 14 5 . 15 BUILDING C++: PROJECT LAYOUT ├── build.gradle └── src └─── hello    ├── cpp │ └─── hello.cpp │    └── headers └─── hello.hpp
  37. 37. 5 . 16 BUILDING C++: EXISTING PROJECTS Source directories can be adjusted Alternative compiler locations
  38. 38. 5 . 17 BUILDING C++: ALTERNATIVE SOURCE sources { cpp { source { srcDir "myDir" include "**/*.cpp" } } }
  39. 39. BUILDING C++: TOOL SUPPORT Operating System Tool Chain Of cial Linux gcc, clang Y MacOS X Xcode Y gcc-macports, clang- macports N Windows Visual C++, gcc-cygwin32, gcc-mingw Y gcc-cygwin64 N
  40. 40. Unix-like gcc, clang N
  41. 41. 5 . 18 5 . 19 BUILDING C++: EXECUTABLE model { components { hello(NativeExecutableSpec) } }
  42. 42. BUILDING C++: CUSTOM COMPILER model { toolChains { gcc(Gcc) { path '/installed/in/foo/dir/gcc' eachPlatform { cppCompiler.withArguments { args -> args << "-DNDEBUG" } } } } }
  43. 43. 5 . 20 BUILDING C++: OTHER FEATURES Cross compilation Multi-architecture targets Set compiler & linker ags Multi-variant builds
  44. 44. 5 . 21 BUILDING C++: WEAKNESS Currently only have built-in support for CUnit Only platform con guration tool support is CMake No Autotools equivalent DSL can be slicker
  45. 45. 5 . 22   Website: Plugins Portal: User Forum: @gradle @DailyGradle http://gradle.org http://plugins.gradle.org http://discuss.gradle.org
  46. 46. 5 . 23   http://leanpub.com/idiomaticgradle
  47. 47. 6 LET’S REVIEW OUR TESTS
  48. 48. 7 . 1 LET’S GET UNIT TESTING class CalculatorSpec extends Specification { def "A calculator must be able to add numbers"() { given: 'That I have a calculator' def calc = new Calculator() when: "I add 2, 3 and -20" def answer = calc.plus 2,3,-20 then: "The answer should be -15" answer == -15 } }
  49. 49. 7 . 2 WHEN THIS TEST FAILS
  50. 50. 7 . 3 WHEN THIS TEST FAILS
  51. 51. 7 . 4 SPOCK FRAMEWORK Built on top of JUnit 4.x. Use it with all your JUnit tools! Use for more than just unit tests. Mocks & stubs included Easily test Java, Groovy, Kotlin, Scala etc.
  52. 52. 7 . 5 DATA-DRIVEN TESTS @Unroll def "A calculator must be able to multiply"() { given: 'That I have a multiplying calculator' def calc = new Calculator() expect: "The answer to be #answer" answer == calc.multiply (a,b,c) where: "The operation is #a * #b * #c" a | b | c || answer 3 | 7 | 5 || 105 1 | 3 | 0 || 0 2 | -1| 1 || -2 }
  53. 53. 7 . 6 ANOTHER COOL FAILURE REPORT
  54. 54. 7 . 7 HANDLING EXCEPTIONS def "Dividing by zero should throw an exception"() { given: 'That I have a dividing calculator' def calc = new Calculator() when: "I divide by zero" calc.divide 1,0 then: "I expect an error" thrown(ArithmeticException) }
  55. 55. 7 . 8 MOCK OUT INTERFACES public interface RemoteCalculator { public Number plus(Number... args); } def "Remote calculator"() { given: "A remote calculator is available" def calc = Mock(RemoteCalculator) when: "Multiple items are sent for addition" calc.plus 1,2,3,4,5 then: "The calculator is only called once" 1 * calc.plus(_) }
  56. 56. 7 . 9 SPOCK FRAMEWORK Spock Framework: Spock Reports http://spockframework.github.io/spock/docs/1.0/index.html https://github.com/renatoathaydes/spock-reports
  57. 57. 7 . 10 WEBSITE TESTING One of the most predominant area of testing of this decade Test-driven webpage development is less effort in long run Selenium is the leading tool Selenium tests can be overly verbose
  58. 58. 8 . 1 TRIVIAL TEST EXAMPLE def "Learn about testing checkboxes"() { when: "I go to that the-internet site" go "${webroot}/checkboxes" then: 'I am expecting Checkbox page' $('h3').text() == 'Checkboxes' and: 'The checkbox states are no & yes' $(By.id('checkboxes')).$('input')*.@checked == ['','true'] }
  59. 59. 8 . 2 9 . 1  
  60. 60. GEB Integrates with Spock Framework JUnit TestNG Cucumber-JVM Makes Selenium readable Anything you can do in Selenium you can do in Geb
  61. 61. 9 . 2 TRIVIAL TEST EXAMPLE COMPLETE class CheckboxExampleSpec extends GebSpec { def "Learn about testing checkboxes"() { when: "I go to that the-internet site" go "${webroot}/checkboxes" then: 'I am expecting Checkbox page' $('h3').text() == 'Checkboxes' and: 'The checkbox states are no & yes' $(By.id('checkboxes')).$('input')*.@checked == ['','true'] } }
  62. 62. 9 . 3 GRABBING SCREENSHOTS class CheckboxReportingSpec extends GebReportingSpec { def 'Learn about testing checkboxes'() { when: 'I go to that the-internet site' go "${webroot}/checkboxes" report 'checkbox-screen' then: 'I am expecting Checkbox page' $('h3').text() == 'Checkboxes' and: 'The checkbox states are no & yes' $(By.id('checkboxes')).$('input')*.@checked == ['','true'] } } Keep record during test Stores HTML & PNG.
  63. 63. 9 . 4 GRABBING SCREENSHOTS
  64. 64. 9 . 5   @GemFramework http://gebish.org
  65. 65. 9 . 6 10 . 1  
  66. 66. 10 . 2 RATPACK FRAMEWORK Set of Java libraries for building modern HTTP applications. Built on Java 8, Netty and reactive principles. Groovy syntax for those who prefer it.
  67. 67. RATPACK QUICKSTART SERVER @Grapes([ @Grab('io.ratpack:ratpack-groovy:1.2.0'), @Grab('org.slf4j:slf4j-simple:1.7.12') ]) import static ratpack.groovy.Groovy.ratpack ratpack { handlers { get { render "Hello World!nn" } get(":name") { render "Hello $pathTokens.name!nn" } } }
  68. 68. 10 . 3 10 . 4 RATPACK’S TESTHTTPCLIENT Can be used standalone Use maven coordinates: io.ratpack:ratpack-test:1.2.0
  69. 69. RATPACK’S TESTHTTPCLIENT ApplicationUnderTest app = new ApplicationUnderTest() { @Override URI getAddress() { "http://127.0.0.1:${PORT}".toURI() } } @Delegate TestHttpClient client = TestHttpClient.testHttpClient(app) def "The echo path should return what is send to it"() { given: "A simple text request" requestSpec { pay -> pay.body.type(MediaType.PLAIN_TEXT_UTF8).text(' ') } when: "The data is posted" post '/' then: "It should be echoed back" response.statusCode == 200 response.body.text == 'You said: ' }
  70. 70. 10 . 5 QUICK HTTP TESTING Quickly point to a remote or in-process server Build payload in a simplistic manner Execute the verb Check the response in a readable manner
  71. 71. 10 . 6 QUICK HTTP TESTING def "The echo path should return what is send to it"() { given: "A simple text request" requestSpec { pay -> pay.body.type(MediaType.PLAIN_TEXT_UTF8).text(' ') } when: "The data is posted" post '/' then: "It should be echoed back" response.statusCode == 200 response.body.text == 'You said: ' }
  72. 72. 10 . 7 OTHER GR8-UNIVERSE TOOLS Grails - Build web applications fast Griffon - Best way to build desktop apps Grooscript - Groovy to Javascript Groovy VFS - File operations on remote servers using variety of protocols Sshoogr - SSH & SCP Groowin - WinRM
  73. 73. 11 THANK YOU Schalk W. Cronjé Email: ysb33r@gmail.com Twitter: @ysb33r
  74. 74. 12 BITS & PIECES
  75. 75. 13 GROOVY VFS def vfs = new VFS() vfs { cp 'ftp://some.server/pub/file0.txt?vfs.ftp.passiveMode=1', 'sftp://user:pass@another.server/path/file1.txt', overwrite : true } https://github.com/ysb33r/groovy-vfs
  76. 76. 14 15 SSHOOGR remoteSession('user:pass@another.server') { exec 'rm -rf ~/tmp/*' exec 'touch this.file' remoteFile('this.file').text = "enabled=true" } https://github.com/aestasit/sshoogr
  77. 77. 16 GROOSCRIPT http://grooscript.org/
  78. 78. THANK YOU Schalk W. Cronjé Email: ysb33r@gmail.com Twitter: @ysb33r
  79. 79. 17 ABOUT THIS PRESENTATION Written in Asciidoctor (1.5.3.2) Styled by asciidoctor-revealjs extension Built using: Gradle gradle-asciidoctor-plugin gradle-vfs-plugin All code snippets tested as part of build

×