From 6ebb8cfd20d255309d72ff27a688db5f1fa1991f Mon Sep 17 00:00:00 2001 From: Jeff Scott Brown Date: Mon, 27 Nov 2017 16:15:03 -0600 Subject: [PATCH] Updating slides --- 3.3.x/build.gradle | 9 +++++ 3.3.x/grails-app/conf/application.yml | 2 ++ .../groovy/demo/MusicFunctionalSpec.groovy | 16 +++++++-- src/docs/asciidoc/controllers_traits.adoc | 27 ++++++++++++++ src/docs/asciidoc/domain_classes.adoc | 2 +- src/docs/asciidoc/domain_classes_traits.adoc | 15 ++++++++ src/docs/asciidoc/index.adoc | 18 +++++++--- src/docs/asciidoc/oci.adoc | 12 ++++--- src/docs/asciidoc/rest.adoc | 25 ++++++------- src/docs/asciidoc/services_traits.adoc | 20 +++++++++++ src/docs/asciidoc/tag_libraries_traits.adoc | 36 +++++++++++++++++++ 11 files changed, 155 insertions(+), 27 deletions(-) create mode 100755 src/docs/asciidoc/controllers_traits.adoc create mode 100755 src/docs/asciidoc/domain_classes_traits.adoc create mode 100644 src/docs/asciidoc/services_traits.adoc create mode 100755 src/docs/asciidoc/tag_libraries_traits.adoc diff --git a/3.3.x/build.gradle b/3.3.x/build.gradle index 0130ae3..fee8ddb 100644 --- a/3.3.x/build.gradle +++ b/3.3.x/build.gradle @@ -29,7 +29,11 @@ repositories { maven { url "https://repo.grails.org/grails/core" } } +// tag::begin_dependencies[] dependencies { + // ... + +// end::begin_dependencies[] compile "org.springframework.boot:spring-boot-starter-logging" compile "org.springframework.boot:spring-boot-autoconfigure" compile "org.grails:grails-core" @@ -64,8 +68,13 @@ dependencies { testRuntime "org.seleniumhq.selenium:selenium-htmlunit-driver:2.47.1" testRuntime "net.sourceforge.htmlunit:htmlunit:2.18" + // tag::http_builder[] testCompile "org.grails:grails-datastore-rest-client" + // end::http_builder[] + +// tag::end_dependencies[] } +// end::end_dependencies[] bootRun { jvmArgs('-Dspring.output.ansi.enabled=always') diff --git a/3.3.x/grails-app/conf/application.yml b/3.3.x/grails-app/conf/application.yml index 5b0817d..1050ada 100644 --- a/3.3.x/grails-app/conf/application.yml +++ b/3.3.x/grails-app/conf/application.yml @@ -1,7 +1,9 @@ --- +# tag::string_conversion[] grails: databinding: convertEmptyStringsToNull: false +# end::string_conversion[] --- grails: profile: web diff --git a/3.3.x/src/integration-test/groovy/demo/MusicFunctionalSpec.groovy b/3.3.x/src/integration-test/groovy/demo/MusicFunctionalSpec.groovy index 57b58d7..1d46547 100644 --- a/3.3.x/src/integration-test/groovy/demo/MusicFunctionalSpec.groovy +++ b/3.3.x/src/integration-test/groovy/demo/MusicFunctionalSpec.groovy @@ -55,6 +55,9 @@ class MusicFunctionalSpec extends Specification { resp.json.title == 'Red' resp.json.genre == 'PROGRESSIVE_ROCK' + // ... + // end::create_albums[] + when: resp = rest.post("http://localhost:${serverPort}/albums") { json { @@ -115,6 +118,7 @@ class MusicFunctionalSpec extends Specification { resp.json.artistName == 'Motorhead' resp.json.title == "No Sleep 'til Hammersmith" resp.json.genre == 'HEAVY_METAL' + // tag::create_albums[] } // end::create_albums[] @@ -139,6 +143,8 @@ class MusicFunctionalSpec extends Specification { resp.json[1].artistName == 'Riverside' resp.json[1].title == 'Love, Fear and the Time Machine' resp.json[1].genre == 'PROGRESSIVE_ROCK' + // ... + // end::get_albums[] and: resp.json[3].artistName == 'Motorhead' @@ -149,13 +155,14 @@ class MusicFunctionalSpec extends Specification { resp.json[2].artistName == 'Johnny Winter' resp.json[2].title == 'Progressive Blues Experiment' resp.json[2].genre == 'BLUES' + // tag::get_albums[] } // end::get_albums[] // tag::by_genre[] void "test retrieving albums by genre"() { when: - def resp = rest.get("http://localhost:${serverPort}/genre/PROGRESSIVE_ROCK/albums") // <1> + def resp = rest.get("http://localhost:${serverPort}/genre/PROGRESSIVE_ROCK/albums") def contentType = resp.headers.getContentType() then: @@ -165,7 +172,7 @@ class MusicFunctionalSpec extends Specification { resp.json.size() == 2 when: - resp = rest.get("http://localhost:${serverPort}/genre/HEAVY_METAL/albums") // <2> + resp = rest.get("http://localhost:${serverPort}/genre/HEAVY_METAL/albums") contentType = resp.headers.getContentType() then: @@ -173,9 +180,11 @@ class MusicFunctionalSpec extends Specification { contentType.subtype == 'json' contentType.type == 'application' resp.json.size() == 1 + // ... + // end::by_genre[] when: - resp = rest.get("http://localhost:${serverPort}/genre/BLUES/albums") // <3> + resp = rest.get("http://localhost:${serverPort}/genre/BLUES/albums") contentType = resp.headers.getContentType() then: @@ -183,6 +192,7 @@ class MusicFunctionalSpec extends Specification { contentType.subtype == 'json' contentType.type == 'application' resp.json.size() == 1 + // tag::by_genre[] } // end::by_genre[] diff --git a/src/docs/asciidoc/controllers_traits.adoc b/src/docs/asciidoc/controllers_traits.adoc new file mode 100755 index 0000000..ae5d0c8 --- /dev/null +++ b/src/docs/asciidoc/controllers_traits.adoc @@ -0,0 +1,27 @@ +== Testing Controllers With Traits + +== Controller + +[source,groovy] +---- +include::{projectdir}/3.3.x/grails-app/controllers/demo/DemoController.groovy[] +---- + +== Command Object Unit Test + +[source,groovy] +---- +include::{projectdir}/3.3.x/src/test/groovy/demo/DemoControllerSpec.groovy[tags=class_begin;command_object_spec;class_end] +---- + +== String Conversion Unit Test + +[source,yml] +---- +include::{projectdir}/3.3.x/grails-app/conf/application.yml[tags=string_conversion] +---- + +[source,groovy] +---- +include::{projectdir}/3.3.x/src/test/groovy/demo/DemoControllerSpec.groovy[tags=class_begin;string_conversion_spec;class_end] +---- diff --git a/src/docs/asciidoc/domain_classes.adoc b/src/docs/asciidoc/domain_classes.adoc index 0799f7d..d249edd 100755 --- a/src/docs/asciidoc/domain_classes.adoc +++ b/src/docs/asciidoc/domain_classes.adoc @@ -4,7 +4,7 @@ [source,groovy] ---- -include::{projectdir}/3.2.x/grails-app/domain/demo/Person.groovy[] +include::{projectdir}/3.3.x/grails-app/domain/demo/Person.groovy[] ---- == Domain Class Validation Unit Test diff --git a/src/docs/asciidoc/domain_classes_traits.adoc b/src/docs/asciidoc/domain_classes_traits.adoc new file mode 100755 index 0000000..fb658a5 --- /dev/null +++ b/src/docs/asciidoc/domain_classes_traits.adoc @@ -0,0 +1,15 @@ +== Testing Domain Classes With Traits + +== Domain Class + +[source,groovy] +---- +include::{projectdir}/3.3.x/grails-app/domain/demo/Person.groovy[] +---- + +== Domain Class Validation Unit Test + +[source,groovy] +---- +include::{projectdir}/3.3.x/src/test/groovy/demo/PersonSpec.groovy[tags=person_spec] +---- diff --git a/src/docs/asciidoc/index.adoc b/src/docs/asciidoc/index.adoc index ba9affe..a4c56e2 100755 --- a/src/docs/asciidoc/index.adoc +++ b/src/docs/asciidoc/index.adoc @@ -1,11 +1,11 @@ -= Grails 3 Testing Overview -Jeff Scott Brown - @jeffscottbrown -:deckjs_transition: fade += Groovy And Grails Testing Techniques +:deckjs_transition: horizontal-slide :navigation: :menu: :goto: :status: + include::oci.adoc[] == Agenda @@ -13,6 +13,8 @@ include::oci.adoc[] * Domain Classes * Command Objects * Tag Libraries +* Grails 3.3 Trait Based Testing Library +* GEB * REST APIs * Running Tests @@ -24,6 +26,14 @@ include::services.adoc[] include::tag_libraries.adoc[] +include::domain_classes_traits.adoc[] + +include::controllers_traits.adoc[] + +include::services_traits.adoc[] + +include::tag_libraries_traits.adoc[] + include::geb.adoc[] include::rest.adoc[] @@ -32,7 +42,7 @@ include::running_tests.adoc[] == Thank you! -* Slides and code : https://github.com/jeffbrown/testingdemo +* Slides and code : https://github.com/jeffbrown/ggtesting * Jeff Scott Brown * brownj@objectcomputing.com * @jeffscottbrown diff --git a/src/docs/asciidoc/oci.adoc b/src/docs/asciidoc/oci.adoc index ebee5b8..47a9eb1 100644 --- a/src/docs/asciidoc/oci.adoc +++ b/src/docs/asciidoc/oci.adoc @@ -11,9 +11,9 @@ * May 2015 ** Jeff Brown and Graeme Rocher -* May 2017 -** 17 Full Time -** 11 U.S. - 5 Europe - 1 Australia +* November 2017 +** 18 Full Time +** 13 U.S. - 4 Europe - 1 Australia * We Need More ** grailsjobs@objectcomputing.com @@ -21,5 +21,7 @@ == Grails At OCI * 30+ Releases Per Year -** 2.5.x, 3.0.x, 3.1.x, 3.2.x -** Working On 3.3 +** 2.5.x, 3.0.x, 3.1.x, 3.2.x, 3.3.x +** Shorter Release Cycles +*** Easier To Upgrade +*** Less Time To Wait For Enhancements diff --git a/src/docs/asciidoc/rest.adoc b/src/docs/asciidoc/rest.adoc index b8c9c39..7be9ec4 100644 --- a/src/docs/asciidoc/rest.adoc +++ b/src/docs/asciidoc/rest.adoc @@ -4,28 +4,28 @@ [source,groovy] ---- -include::{projectdir}/3.2.x/grails-app/domain/demo/Album.groovy[] +include::{projectdir}/3.3.x/grails-app/domain/demo/Album.groovy[] ---- == Rest Controller [source,groovy] ---- -include::{projectdir}/3.2.x/grails-app/controllers/demo/MusicController.groovy[tags=begin_class;class_end] +include::{projectdir}/3.3.x/grails-app/controllers/demo/MusicController.groovy[tags=begin_class;class_end] ---- == URL Mapping [source,groovy] ---- -include::{projectdir}/3.2.x/grails-app/controllers/testingdemo/UrlMappings.groovy[] +include::{projectdir}/3.3.x/grails-app/controllers/testingdemo/UrlMappings.groovy[] ---- -== RestClient From Http Builder +== RestBuilder From Datastore Rest Client [source,groovy] ---- -include::{projectdir}/3.2.x/build.gradle[tags=begin_dependencies;http_builder;end_dependencies] +include::{projectdir}/3.3.x/build.gradle[tags=begin_dependencies;http_builder;end_dependencies] ---- == Create Integration Test @@ -41,43 +41,40 @@ include::{projectdir}/3.2.x/build.gradle[tags=begin_dependencies;http_builder;en [source,groovy] ---- -include::{projectdir}/3.2.x/src/integration-test/groovy/demo/MusicFunctionalSpec.groovy[tags=begin_class;end_class] +include::{projectdir}/3.3.x/src/integration-test/groovy/demo/MusicFunctionalSpec.groovy[tags=begin_class;end_class] ---- == Test No Data [source,groovy] ---- -include::{projectdir}/3.2.x/src/integration-test/groovy/demo/MusicFunctionalSpec.groovy[tags=begin_class;no_albums;end_class] +include::{projectdir}/3.3.x/src/integration-test/groovy/demo/MusicFunctionalSpec.groovy[tags=begin_class;no_albums;end_class] ---- == Test Create Albums [source,groovy] ---- -include::{projectdir}/3.2.x/src/integration-test/groovy/demo/MusicFunctionalSpec.groovy[tags=begin_class;create_albums;end_class] +include::{projectdir}/3.3.x/src/integration-test/groovy/demo/MusicFunctionalSpec.groovy[tags=begin_class;create_albums;end_class] ---- == Test Retrieve Albums [source,groovy] ---- -include::{projectdir}/3.2.x/src/integration-test/groovy/demo/MusicFunctionalSpec.groovy[tags=begin_class;get_albums;end_class] +include::{projectdir}/3.3.x/src/integration-test/groovy/demo/MusicFunctionalSpec.groovy[tags=begin_class;get_albums;end_class] ---- == Query Filter [source,groovy] ---- -include::{projectdir}/3.2.x/grails-app/controllers/demo/MusicController.groovy[tags=begin_class;query_filter;class_end] +include::{projectdir}/3.3.x/grails-app/controllers/demo/MusicController.groovy[tags=begin_class;query_filter;class_end] ---- == Test Query Filter [source,groovy] ---- -include::{projectdir}/3.2.x/src/integration-test/groovy/demo/MusicFunctionalSpec.groovy[tags=begin_class;by_genre;end_class] +include::{projectdir}/3.3.x/src/integration-test/groovy/demo/MusicFunctionalSpec.groovy[tags=begin_class;by_genre;end_class] ---- -<1> /albums?genre=PROGRESSIVE_ROCK -<2> /albums?genre=HEAVY_METAL -<3> /albums?genre=BLUES diff --git a/src/docs/asciidoc/services_traits.adoc b/src/docs/asciidoc/services_traits.adoc new file mode 100644 index 0000000..b063c9f --- /dev/null +++ b/src/docs/asciidoc/services_traits.adoc @@ -0,0 +1,20 @@ +== Testing Services With Traits + +== Services + +[source,groovy] +---- +include::{projectdir}/3.3.x/grails-app/services/demo/MoneyService.groovy[] +---- + +[source,groovy] +---- +include::{projectdir}/3.3.x/grails-app/services/demo/BankService.groovy[] +---- + +== Configuring Beans In Test + +[source,groovy] +---- +include::{projectdir}/3.3.x/src/test/groovy/demo/MoneyServiceSpec.groovy[] +---- diff --git a/src/docs/asciidoc/tag_libraries_traits.adoc b/src/docs/asciidoc/tag_libraries_traits.adoc new file mode 100755 index 0000000..b174114 --- /dev/null +++ b/src/docs/asciidoc/tag_libraries_traits.adoc @@ -0,0 +1,36 @@ +== Testing Tag Libraries With Traits + +== Tag Library + +[source,groovy] +---- +include::{projectdir}/3.3.x/grails-app/taglib/demo/HelperTagLib.groovy[] +---- + +== Testing Simple Tag + +[source,groovy] +---- +include::{projectdir}/3.3.x/src/test/groovy/demo/HelperTagLibSpec.groovy[tags=class_begin;test_simple_tag;class_end] +---- + +== Testing Tag With Body + +[source,groovy] +---- +include::{projectdir}/3.3.x/src/test/groovy/demo/HelperTagLibSpec.groovy[tags=class_begin;test_repeat;class_end] +---- + +== Testing Tag With Body + +[source,groovy] +---- +include::{projectdir}/3.3.x/src/test/groovy/demo/HelperTagLibSpec.groovy[tags=class_begin;test_repeat_no_count;class_end] +---- + +== Testing Tag Method Call + +[source,groovy] +---- +include::{projectdir}/3.3.x/src/test/groovy/demo/HelperTagLibSpec.groovy[tags=class_begin;test_method_call;class_end] +----