Conversation
Micronaut client is removed from tests in favor of `HttpClientSupport` based on the jdk http client.
There was a problem hiding this comment.
Pull request overview
Adds a new grails-testing-support-httpclient module (JDK HttpClient + Groovy extension assertions) and migrates multiple integration/functional tests across grails-test-examples/* to use the new support API, with corresponding dependency/doc/CI updates.
Changes:
- Introduces
grails-testing-support-httpclient(request helpers +HttpResponsefluent assertions + multipart builder) and publishes it. - Refactors many example integration tests to use
HttpClientSupportinstead of Micronaut’sHttpClient. - Updates docs and build/CI configuration to reflect the new module and test behavior.
Reviewed changes
Copilot reviewed 81 out of 81 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| settings.gradle | Registers the new testing-support module in the build. |
| grails-testing-support-httpclient/build.gradle | New module build with Groovy + JSON/XML + OpenTest4J dependency. |
| grails-testing-support-httpclient/src/main/groovy/org/apache/grails/testing/httpclient/MultipartBody.groovy | Adds a multipart/form-data body builder for tests. |
| grails-testing-support-httpclient/src/main/resources/META-INF/groovy/org.codehaus.groovy.runtime.ExtensionModule | Registers Groovy extension methods for HttpResponse. |
| grails-testing-support-httpclient/src/test/groovy/org/apache/grails/testing/httpclient/MultipartBodySpec.groovy | Unit tests for multipart charset behavior. |
| grails-testing-support-httpclient/src/test/groovy/org/apache/grails/testing/httpclient/HttpResponseExtensionsSpec.groovy | Unit tests for response assertion/parse extensions. |
| grails-testing-support-httpclient/src/test/groovy/org/apache/grails/testing/httpclient/HttpClientSupportSpec.groovy | Unit tests for the HttpClientSupport trait helpers. |
| grails-test-examples/views-functional-tests/build.gradle | Switches integration tests to depend on the new httpclient support module. |
| grails-test-examples/views-functional-tests/src/integration-test/groovy/functional/tests/api/NamespacedBookSpec.groovy | Migrates to HttpClientSupport + fluent JSON assertions. |
| grails-test-examples/views-functional-tests/src/integration-test/groovy/functional/tests/VehicleSpec.groovy | Migrates to HttpClientSupport and structured JSON checks. |
| grails-test-examples/views-functional-tests/src/integration-test/groovy/functional/tests/TestGsonControllerSpec.groovy | Migrates to HttpClientSupport and expectJson/expectContains assertions. |
| grails-test-examples/views-functional-tests/src/integration-test/groovy/functional/tests/TestGmlControllerSpec.groovy | Migrates to HttpClientSupport and xml() parsing. |
| grails-test-examples/views-functional-tests/src/integration-test/groovy/functional/tests/TestControllerSpec.groovy | Migrates to HttpClientSupport and status/body assertions for 401. |
| grails-test-examples/views-functional-tests/src/integration-test/groovy/functional/tests/TeamSpec.groovy | Migrates to HttpClientSupport and JSON assertions. |
| grails-test-examples/views-functional-tests/src/integration-test/groovy/functional/tests/ProxySpec.groovy | Migrates to HttpClientSupport and header/body assertions. |
| grails-test-examples/views-functional-tests/src/integration-test/groovy/functional/tests/ProjectSpec.groovy | Migrates to HttpClientSupport and response JSON extraction. |
| grails-test-examples/views-functional-tests/src/integration-test/groovy/functional/tests/ProductSpec.groovy | Migrates product paging tests to new http helpers and assertions. |
| grails-test-examples/views-functional-tests/src/integration-test/groovy/functional/tests/PersonInheritanceSpec.groovy | Migrates to HttpClientSupport and fluent checks. |
| grails-test-examples/views-functional-tests/src/integration-test/groovy/functional/tests/ObjectTemplateSpec.groovy | Migrates to HttpClientSupport with status/body checks. |
| grails-test-examples/views-functional-tests/src/integration-test/groovy/functional/tests/ModelInterceptorIntSpec.groovy | Migrates to HttpClientSupport for controller requests. |
| grails-test-examples/views-functional-tests/src/integration-test/groovy/functional/tests/InheritanceSpec.groovy | Migrates to HttpClientSupport and JSON assertions. |
| grails-test-examples/views-functional-tests/src/integration-test/groovy/functional/tests/HttpClientSpec.groovy | Removes legacy Micronaut HttpClient base spec. |
| grails-test-examples/views-functional-tests/src/integration-test/groovy/functional/tests/EmbeddedSpec.groovy | Migrates embedded-domain rendering checks to new assertions. |
| grails-test-examples/views-functional-tests/src/integration-test/groovy/functional/tests/CustomerSpec.groovy | Migrates to HttpClientSupport and with(response.json()) validations. |
| grails-test-examples/views-functional-tests/src/integration-test/groovy/functional/tests/CircularSpec.groovy | Migrates circular rendering tests to new JSON/header assertions. |
| grails-test-examples/views-functional-tests/src/integration-test/groovy/functional/tests/BulletinSpec.groovy | Migrates to HttpClientSupport and JSON parsing. |
| grails-test-examples/views-functional-tests/src/integration-test/groovy/functional/tests/BookSpec.groovy | Migrates CRUD/error rendering tests to new http helpers. |
| grails-test-examples/micronaut/build.gradle | Adds integration-test dependency on the new module. |
| grails-test-examples/micronaut/src/integration-test/groovy/micronaut/MicronautErsatzRoundtripSpec.groovy | Replaces Micronaut client calls with HttpClientSupport requests. |
| grails-test-examples/micronaut/src/integration-test/groovy/micronaut/MicronautErsatzPatternSpec.groovy | Replaces Micronaut client calls with new helpers. |
| grails-test-examples/micronaut/src/integration-test/groovy/micronaut/MicronautDeclarativeClientSpec.groovy | Removes redundant Micronaut client roundtrip checks (keeps Ersatz/declarative client tests). |
| grails-test-examples/issue-views-182/build.gradle | Switches integration tests to use new module dependency. |
| grails-test-examples/issue-views-182/src/integration-test/groovy/views182/HttpClientCommonSpec.groovy | Removes legacy Micronaut client base spec. |
| grails-test-examples/issue-views-182/src/integration-test/groovy/views182/CustomErrorSpec.groovy | Migrates to HttpClientSupport and status/body assertions. |
| grails-test-examples/issue-15228/build.gradle | Switches integration tests to use new module dependency. |
| grails-test-examples/issue-15228/src/integration-test/groovy/issue11767/app/GsonViewRespondSpec.groovy | Migrates to HttpClientSupport and JSON assertions. |
| grails-test-examples/issue-11767/build.gradle | Adds integration-test dependency on new module; removes Micronaut client test deps. |
| grails-test-examples/issue-11767/src/integration-test/groovy/issue11767/app/ConfigLoadingSpec.groovy | Migrates HTTP calls to HttpClientSupport. |
| grails-test-examples/issue-11102/build.gradle | Adds integration-test dependency on new module; removes Micronaut client deps. |
| grails-test-examples/issue-11102/src/integration-test/groovy/issue11102/HttpClientCommonSpec.groovy | Removes legacy Micronaut client base spec. |
| grails-test-examples/issue-11102/src/integration-test/groovy/issue11102/TestControllerSpec.groovy | Migrates to HttpClientSupport and status/body assertions. |
| grails-test-examples/hibernate5/issue450/build.gradle | Adds integration-test dependency on new module. |
| grails-test-examples/hibernate5/issue450/src/integration-test/groovy/example/BookControllerSpec.groovy | Migrates to HttpClientSupport and fluent body assertions. |
| grails-test-examples/hibernate5/grails-multiple-datasources/build.gradle | Adds integration-test dependency on new module; removes Micronaut client deps. |
| grails-test-examples/hibernate5/grails-multiple-datasources/src/integration-test/groovy/functionaltests/MultiDataSourceWithSessionSpec.groovy | Migrates to HttpClientSupport and fluent body assertions. |
| grails-test-examples/demo33/build.gradle | Adds integration-test dependency on new module. |
| grails-test-examples/demo33/src/integration-test/groovy/demo/JsonControllerSpec.groovy | Migrates ad-hoc HTTP usage to HttpClientSupport. |
| grails-test-examples/cache/build.gradle | Adds integration-test dependency on new module; removes Micronaut client deps. |
| grails-test-examples/cache/src/integration-test/groovy/com/demo/AdvancedCachingIntegrationSpec.groovy | Migrates caching endpoint tests to new helper/JSON parsing. |
| grails-test-examples/async-events-pubsub-demo/build.gradle | Adds integration-test dependency on new module; removes Micronaut client deps. |
| grails-test-examples/async-events-pubsub-demo/src/integration-test/groovy/pubsub/demo/TaskControllerSpec.groovy | Migrates async error handling test to new helper. |
| grails-test-examples/app1/build.gradle | Adds integration-test dependency on new module; removes Micronaut client test deps. |
| grails-test-examples/app1/src/integration-test/groovy/functionaltests/urlmappings/UrlMappingsSpec.groovy | Migrates URL mapping integration tests to new helpers/assertions. |
| grails-test-examples/app1/src/integration-test/groovy/functionaltests/springevents/SpringEventsSpec.groovy | Migrates Spring events endpoint tests to new helpers/assertions. |
| grails-test-examples/app1/src/integration-test/groovy/functionaltests/interceptors/InterceptorOrderingSpec.groovy | Migrates interceptor endpoint tests to new helpers/assertions. |
| grails-test-examples/app1/src/integration-test/groovy/functionaltests/interceptors/InterceptorAdvancedMatchingSpec.groovy | Migrates interceptor matching tests to new helpers/assertions. |
| grails-test-examples/app1/src/integration-test/groovy/functionaltests/flow/FlashChainForwardSpec.groovy | Migrates flow tests, adds manual redirect handling with a no-redirect client. |
| grails-test-examples/app1/src/integration-test/groovy/functionaltests/errorhandling/ErrorHandlingSpec.groovy | Migrates error-handling endpoint tests to new helpers/assertions. |
| grails-test-examples/app1/src/integration-test/groovy/functionaltests/cors/CorsAdvancedSpec.groovy | Migrates CORS tests to new helpers/assertions. |
| grails-test-examples/app1/src/integration-test/groovy/functionaltests/caching/CachingSpec.groovy | Migrates caching endpoint tests to new helpers/assertions. |
| grails-test-examples/app1/src/integration-test/groovy/functionaltests/async/AsyncPromiseSpec.groovy | Migrates async endpoint tests to new helpers/assertions. |
| grails-test-examples/app1/src/integration-test/groovy/functionaltests/BookRestfulControllerSpec.groovy | Migrates to HttpClientSupport and jsonList() parsing. |
| grails-test-examples/app1/src/integration-test/groovy/functionaltests/AtResourceSpec.groovy | Migrates to HttpClientSupport and status assertions. |
| grails-doc/src/en/guide/testing/integrationTesting.adoc | Documents the new httpclient testing support module and provides examples. |
| grails-doc/src/en/guide/introduction/whatsNew.adoc | Adds “What’s New” entry for the new module. |
| gradle/publish-root-config.gradle | Adds the new module to the list of published projects. |
| gradle/functional-test-config.gradle | Tweaks Geb timeout property usage (comment clarifies default). |
| gradle.properties | Adds openTest4jVersion for the new module dependency. |
| DEVELOPMENT.md | Clarifies what gebAtCheckWaiting does. |
| .github/workflows/groovy-joint-workflow.yml | Enables -PgebAtCheckWaiting for CI build job. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
This test times out regularly in CI.
jdaugherty
left a comment
There was a problem hiding this comment.
This is such an incredible amount of work:
- it's a clear API
- it doesn't pollute our dependencies
- it's useful for all Grails apps and we adopted it ourselves (so the benefits are immediately clear in this PR)
- we own the API so we can enhance it more rapidly than Micronaut or Spring Boot
I have some minor concerns, mainly:
- the assumption is this is used in specs, but we're not following the recommended pattern for spec enhancement (using an extension)
- the naming - I'd like to propose an alternative with the assumption of a future addition
- could including this library with extensions cause a difference in behavior between prod/dev and test? Ancillary to this, I think using a delegate pattern may be better for testing, but I can definitely see the http client enhancements useful for a grails app itself. Interested to discuss this one.
|
I know this is a new feature, but i'd argue we should back port it. We don't have to announce it for 7.0.x, but the reason it should exist in 7.0.x is for easier maintenance given how much clean up on the tests have been done |
|
Thank you @jdaugherty for excellent feedback! |
Add marker annotation for Spring test configuration classes that should be auto-imported into Integration tests.
75d4501 to
e1f1fb5
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 92 out of 92 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
| @Retention(RetentionPolicy.RUNTIME) | ||
| @Target([ElementType.TYPE]) | ||
| @TestConfiguration(proxyBeanMethods = false) | ||
| @interface IntegrationTestAutoConfiguration { |
There was a problem hiding this comment.
So instead of a spock extension, you went with the bean approach. I assume that's why this change is now for 7.1.x instead of 7.0.x? I don't think it's a problem to use the test configuration approach, but can you give background on what led you down this path?
There was a problem hiding this comment.
As it is a new feature, it was always intended it for 7.1.x.
For proper IDE support I think we need an object to work with.
There was a problem hiding this comment.
@jdaugherty So, a bit more context on why I went the @TestConfiguration route. I read here that using Traits on Specifications is not supported/recommended.
Now that I think about this some more, maybe this was overly cautious, as we apparently do that a lot already in Grails testing support:
UrlMappingsUnitTestTagLibUnitTestEnvironmentAwareSpecGrailsUnitTestGrailsWebUnitTestDataTestJsonViewTestMocksDomains- etc.
I'll revert to using a trait...
There was a problem hiding this comment.
My biggest concern of putting this in 7.1.x is this actually makes it easier to test grails-core. Would it be possible to put this in 7.0.x and only publish it in 7.1.x for external use? I want to make merges easier ...
There was a problem hiding this comment.
I think that should be possible by referencing grails-testing-support-http-client as a project dependency instead of as a "usual" dependency in the test projects and remove it from publishing.
# Conflicts: # grails-test-examples/app1/src/integration-test/groovy/functionaltests/async/AsyncPromiseSpec.groovy
🚨 TestLens detected 1 failed tests 🚨Here is what you can do:
Test Summary
🏷️ Commit: 32a9787 Test FailureUserControllerSpec > User list (:grails-test-examples-scaffolding:integrationTest in CI / Functional Tests (Java 17, indy=true))Muted TestsSelect tests to mute in this pull request:
Reuse successful test results:
Click the checkbox to trigger a rerun:
Learn more about TestLens at testlens.app. |
|
I see 7.1.x commits in the commit history for merging to 7.0.x @matrei |
|
Replaced by #15505 |
This pull request adds a new
org.apache.grails:grails-testing-support-httpclientmodule and refactors the HTTP client usage in integration tests to use it, improving consistency and maintainability of test code.