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.

Cool Jvm Tools to Help you Test - Aylesbury Testers Version

1,235 views

Published on

Awesome tools on the JVM to make te

Published in: Software
  • Be the first to comment

Cool Jvm Tools to Help you Test - Aylesbury Testers Version

  1. 1. @AylTesters Aylesbury Testers Meetup May 2016 © S COOL JVM TOOLS TO HELP YOU TEST Schalk W. Cronjé
  2. 2. 1 ABOUT ME Email: Twitter / Ello : @ysb33r ysb33r@gmail.com
  3. 3. 2 CLARITY OF INTENT   Readability   Expressiveness
  4. 4. 3 LET’S REVIEW OUR TESTS
  5. 5. 4 . 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 } }
  6. 6. 4 . 2 WHEN THIS TEST FAILS
  7. 7. 4 . 3 WHEN THIS TEST FAILS
  8. 8. 4 . 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.
  9. 9. 4 . 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 }
  10. 10. 4 . 6 ANOTHER COOL FAILURE REPORT
  11. 11. 4 . 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) }
  12. 12. 4 . 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(_) }
  13. 13. 4 . 9 SPOCK FRAMEWORK Spock Framework: Spock Reports http://spockframework.github.io/spock/docs/1.0/index.html https://github.com/renatoathaydes/spock-reports
  14. 14. 4 . 10 WHAT IS THIS EVIL? Underlying language is (Apache) Groovy You don’t need to be a Groovy expert to be a power user of many of these tools. Groovy doesn’t need ; in most cases Groovy does more with less punctuation, making it an ideal choice for a DSL In most cases lines that do not end on an operator is considered a completed statement.
  15. 15. 5 . 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
  16. 16. 5 . 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 }
  17. 17. 5 . 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 }
  18. 18. 5 . 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' }
  19. 19. 5 . 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'
  20. 20. 5 . 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.
  21. 21. 5 . 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 }
  22. 22. 5 . 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' })
  23. 23. 5 . 9 6 . 1 QUICK HTTP TESTING
  24. 24. 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
  25. 25. 6 . 2 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: ' }
  26. 26. 6 . 3 7 . 1  
  27. 27. 7 . 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.
  28. 28. 7 . 3 RATPACK’S TESTHTTPCLIENT Can be used standalone Use maven coordinates: io.ratpack:ratpack-test:1.2.0
  29. 29. 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: ' }
  30. 30. 7 . 4 OFFLINE API TESTING Sometimes you simply have to use a live site for testing Mocking & stubbing simply not good enough Need live data Do not want to overload service with unnecessary test data Want to test of ine
  31. 31. 8 . 1 OFFLINE API TESTING @Betamax(tape='files') def "Source jar must be posted"() { given: 'The list of files is requested from the repository' def list = get path : "${REPO_ROOT}/bintray-gradle-plugin/files" expect: 'The bintray source jar should be included' list?.find { it?.path == 'org.ysb33r.gradle/bintray/0.0.5/bintray-0.0.5-sources.jar' } }
  32. 32. 8 . 2 9 . 1  
  33. 33. BETAMAX Allows record & playpack Mocks external HTTP resources Web services REST APIs Stores recordings in YAML Easy to edit Commit to source control Remember to sanitize auth credentials!
  34. 34. 9 . 2 DEMO
  35. 35. 9 . 3 9 . 4 CREATE RECORDER @Shared ProxyConfiguration configuration = ProxyConfiguration.builder(). tapeRoot(new File('/path/to/tapes')). ignoreLocalhost(false). sslEnabled(true). build() @Rule RecorderRule recorder = new RecorderRule(configuration)
  36. 36.   http://betamax.software https://github.com/betamaxteam/betamax
  37. 37. 9 . 5 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
  38. 38. 10 . 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'] }
  39. 39. 10 . 2 11 . 1  
  40. 40. GEB Integrates with Spock Framework JUnit TestNG Cucumber-JVM Makes Selenium readable Anything you can do in Selenium you can do in Geb
  41. 41. 11 . 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'] } }
  42. 42. 11 . 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.
  43. 43. 11 . 4 GRABBING SCREENSHOTS
  44. 44. 11 . 5   @GemFramework http://gebish.org
  45. 45. 11 . 6 TIE IT TOGETHER Automation is very important for effectiveness and time- to-market Ability to run all tests locally, under CI and under special environments Modern testers needs to know about deployment
  46. 46. 12 13 . 1  
  47. 47. 13 . 2 GRADLE Very modern, next-generation build & deployment pipeline tool DSL is based on Groovy Vast collection of plugins
  48. 48. 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" }
  49. 49. 13 . 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.
  50. 50. 13 . 4   Website: Plugins Portal: User Forum: @gradle @DailyGradle http://gradle.org http://plugins.gradle.org http://discuss.gradle.org
  51. 51. 13 . 5 14 DEMO
  52. 52.   http://leanpub.com/idiomaticgradle
  53. 53. 15 OTHER NOTEWORTHY TOOLS AccuREST ( ) REST APIs with customer-driven contracts UniTEE ( ) Multi-component test framework Arquillian ( ) J2EE testing within app servers JSelenide ( ) Alternative to Geb https://github.com/Codearte/accurest http://www.autocognite.com/ http://arquillian.org/ http://selenide.org/
  54. 54. 16 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 https://github.com/ysb33r/FastTrackJvm/tree/AylTestersMay2016
  55. 55. 17 THANK YOU Schalk Cronjé ysb33r@gmail.com @ysb33r

×