Skip to content

Commit cd39cd3

Browse files
committed
- Doc corrections
- Add com.gradle.develocity plugin Signed-off-by: Gopal S Akshintala <[email protected]>
1 parent ec2d11f commit cd39cd3

File tree

6 files changed

+44
-52
lines changed

6 files changed

+44
-52
lines changed

README.adoc

Lines changed: 38 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ endif::[]
1111
:hide-uri-scheme:
1212
:toc:
1313
:toc-placement!:
14+
:figure-caption!:
1415
:sourcedir: src/main/kotlin
1516
:testdir: src/test/java
1617
:integrationtestdir: src/integrationTest/java
@@ -32,7 +33,7 @@ essentially translating your manual testing into Automation, without any loss or
3233
But it's even better!
3334

3435
image::postman-run.png[]
35-
image::manual-to-automation.png[Manual to Automation]
36+
image::manual-to-automation.png[Manual to Automation, align="center"]
3637

3738
[.lead]
3839
It strikes a balance between _flexibility_
@@ -68,19 +69,19 @@ implementation("com.salesforce.revoman:revoman:{revoman-version}")
6869

6970
toc::[]
7071

71-
.Tech-Talk given at https://www.opensourceindia.in/osi-speakers-2023/gopala-sarma-akshintala/[Open Source Conf], https://speakerdeck.com/gopalakshintala/revoman-a-template-driven-api-automation-tool-for-jvm[🎴Slide deck]
72-
image::revoman-demo-thumbnail.png[link="https://www.youtube.com/watch?v=YxeRddSFkxc&list=PLrJbJ9wDl9EC0bG6y9fyDylcfmB_lT_Or&index=2"]
72+
.Tech-Talk given at https://www.opensourceindia.in/osi-speakers-2023/gopala-sarma-akshintala/[Open Source Conf - 2023], https://speakerdeck.com/gopalakshintala/revoman-a-template-driven-api-automation-tool-for-jvm[🎴Slide deck]
73+
image::revoman-demo-thumbnail.png[link="https://www.youtube.com/watch?v=YxeRddSFkxc&list=PLrJbJ9wDl9EC0bG6y9fyDylcfmB_lT_Or&index=2", align="center"]
7374

7475
== Why ReṼoman?
7576

7677
=== The Problem
7778

7879
* The majority of JVM SaaS applications are REST-based. But the API automation is done through a Mul-*T*-verse of Integration/Functional tests, E2E tests and Manual tests, each with its own frameworks, tools, and internal utilities, testing almost the same code flow.
79-
* These custom alien automation frameworks, often built using low-level tools like https://rest-assured.io/[**REST Assured**] which are specific to a service or domain and are rigid to reuse, extend and difficult to maintain.
80+
* These custom alien automation frameworks, often built using low-level tools like https://rest-assured.io/[**REST Assured**], are specific to a service or domain and are rigid to reuse, extend and difficult to maintain.
8081
* This automation competes on cognitive complexity and learning curve with the Prod code, and mostly, automation wins.
8182
* After a point, the API automation may deviate from its purpose of augmenting real end-user interaction and turns into a foot-chain for development.
8283

83-
image::cognitive-complexity.png[]
84+
image::cognitive-complexity.png[align="center"]
8485

8586
=== The Solution
8687

@@ -93,24 +94,25 @@ Leveraging it can mitigate writing a lot of code as we translate those manual st
9394

9495
____
9596
96-
* How _productive_ would it be, if you can plug your exported Postman collection,
97+
* How _productive_ would it be, if you can plug your exported Postman collection template,
9798
that you anyway would have created for your manual testing, and execute them through your JVM tests?
9899
99-
* How about a Universal API automation tool promotes low code and low-cognitive-complexity and strikes a balance between flexibility and ease of use?
100+
* How about a Universal API automation tool that promotes low code and low-cognitive-complexity and strikes a balance between flexibility and ease of use?
100101
101102
____
102103

103104
== API automation with _ReṼoman_
104105

105106
=== Template-Driven Testing
106107

107-
* The exported Postman collection JSON file is referred to as Postman templates, as it contains some placeholders/variables in the `+{{variable-key}}+` pattern. You can read more about it https://learning.postman.com/docs/sending-requests/variables/[here]
108+
* The exported Postman collection JSON file is referred to as a Postman template, as it contains some placeholders/variables in the `+{{variable-key}}+` pattern. You can read more about it https://learning.postman.com/docs/sending-requests/variables/[here]
108109
* ReṼoman understands these templates and replaces these variables at the runtime, similar to Postman. It supports
109110
** Nested variables, e.g., `+{{variable-key{{nested-variable-key}}}}+`
110111
** link:{sourcedir}/com/salesforce/revoman/internal/postman/DynamicVariableGenerator.kt[Dynamic variables], e.g., `{{$randomUUID}}`, `{{$randomEmail}}`
112+
** <<Custom Dynamic variables>>
111113

112114
[.lead]
113-
You can _kick off_ this *Template-Driven Testing* by invoking `revUp`,
115+
You can _kick off_ this *Template-Driven Testing* by invoking `ReVoman.revUp()`,
114116
supplying your Postman templates and environments, and all your customizations through a configuration:
115117

116118
[source,java,indent=0,options="nowrap"]
@@ -148,12 +150,13 @@ void restfulApiDev() {
148150
.templatePath(PM_COLLECTION_PATH) // <2>
149151
.environmentPath(PM_ENVIRONMENT_PATH) // <3>
150152
.off());
151-
assertThat(rundown.stepReports).hasSize(3);
153+
assertThat(rundown.stepReports).hasSize(3); // <4>
152154
}
153155
----
154156
<1> `revUp` is the method to call passing a configuration, built as below
155157
<2> Supply an exported Postman collection JSON file path
156158
<3> Supply an exported Postman environment JSON file path
159+
<4> Run more assertions on the <<Rundown>>
157160

158161
endif::[]
159162
ifndef::env-github[]
@@ -166,10 +169,10 @@ include::{integrationtestdir}/com/salesforce/revoman/integration/restfulapidev/R
166169
<1> `revUp` is the method to call passing a configuration, built as below
167170
<2> Supply an exported Postman collection JSON file path
168171
<3> Supply an exported Postman environment JSON file path
172+
<4> Run more assertions on the <<Rundown>>
169173

170174
endif::[]
171175

172-
[#_rundown]
173176
=== Rundown
174177

175178
After all this, you receive back a detailed *Rundown* in return.
@@ -197,14 +200,13 @@ StepReport(
197200
[.lead]
198201
`Rundown` has many convenience methods to ease applying further assertions on top of it.
199202

200-
TIP:
201-
Other simple examples to see in Action: link:{integrationtestdir}/com/salesforce/revoman/integration/pokemon/PokemonTest.java[PokemonTest.java]
203+
TIP: Other simple examples to see in Action: link:{integrationtestdir}/com/salesforce/revoman/integration/pokemon/PokemonTest.java[PokemonTest.java]
202204

203205
=== Advanced Example
204206

205207
[.lead]
206-
ReṼoman isn't just limited to that;
207-
you can add more _bells & whistles_:
208+
ReṼoman isn't just limited to executing Collection like Postman;
209+
you can add more _bells & whistles_ 🔔:
208210

209211
ifdef::env-github[]
210212

@@ -281,7 +283,7 @@ assertThat(pqRundown.mutableEnv)
281283
"quoteCalculationStatus", PricingPref.System.completeStatus,
282284
"quoteCalculationStatusAfterAllUpdates", PricingPref.System.completeStatus));
283285
----
284-
<1> `revUp` is the method to call passing a configuration, built as below
286+
<1> `revUp()` is the method to call passing a configuration, built as below
285287
<2> Supply the path (relative to resources) to the Template Collection JSON file
286288
<3> Supply the path (relative to resources) to the Environment JSON file
287289
<4> Supply any dynamic environment that is runtime-specific
@@ -291,10 +293,10 @@ assertThat(pqRundown.mutableEnv)
291293
<8> <<#_type_safety_with_flexible_json_pojo_marshallingserialization_and_unmarshallingdeserialization, Request Config>>
292294
<9> <<#_type_safety_with_flexible_json_pojo_marshallingserialization_and_unmarshallingdeserialization, Response Config>>
293295
<10> <<#_pre_and_post_hooks>>
294-
<11> <<#_response_validations>>
296+
<11> <<Response Validations>>
295297
<12> <<#_type_safety_with_flexible_json_pojo_marshallingserialization_and_unmarshallingdeserialization, Custom Adapters>>
296298
<13> Ignore Java cert issues when firing HTTP calls
297-
<14> More assertions on top of <<#_rundown>>
299+
<14> Run more assertions on the <<Rundown>>
298300

299301
endif::[]
300302
ifndef::env-github[]
@@ -304,7 +306,7 @@ ifndef::env-github[]
304306
----
305307
include::{integrationtestdir}/com/salesforce/revoman/integration/core/pq/PQE2EWithSMTest.java[tag=pq-e2e-with-revoman-config-demo]
306308
----
307-
<1> `revUp` is the method to call passing a configuration, built as below
309+
<1> `revUp()` is the method to call passing a configuration, built as below
308310
<2> Supply the path (relative to resources) to the Template Collection JSON file
309311
<3> Supply the path (relative to resources) to the Environment JSON file
310312
<4> Supply any dynamic environment that is runtime-specific
@@ -314,19 +316,16 @@ include::{integrationtestdir}/com/salesforce/revoman/integration/core/pq/PQE2EWi
314316
<8> <<#_type_safety_with_flexible_json_pojo_marshallingserialization_and_unmarshallingdeserialization, Request Config>>
315317
<9> <<#_type_safety_with_flexible_json_pojo_marshallingserialization_and_unmarshallingdeserialization, Response Config>>
316318
<10> <<#_pre_and_post_hooks>>
317-
<11> <<#_response_validations>>
319+
<11> <<Response Validations>>
318320
<12> <<#_type_safety_with_flexible_json_pojo_marshallingserialization_and_unmarshallingdeserialization, Custom Adapters>>
319321
<13> Ignore Java cert issues when firing HTTP calls
320-
<14> More assertions on top of <<#_rundown>>
322+
<14> Run more assertions on the <<Rundown>>
321323
endif::[]
322324

323325
== Debugging UX
324326

325327
[.lead]
326-
This tool has particular emphasis on Debugging experience.
327-
328-
The rundown you get as a return from `revUp` after the execution completes has everything you need to know about what happened during each step execution,
329-
along with environment snapshot during that step execution. Here is what a debugger view of a Rundown looks like:
328+
This tool has particular emphasis on Debugging experience. Here is what a debugger view of a <<Rundown>> looks like:
330329

331330
image:rundown.png[Rundown of all steps]
332331

@@ -377,7 +376,8 @@ link:{sourcedir}/com/salesforce/revoman/input/json/JsonPojoUtils.kt[JSON POJO Ut
377376

378377
[TIP]
379378
====
380-
Examples to refer:
379+
See in Action:
380+
381381
* link:{testdir}/com/salesforce/revoman/input/json/JsonPojoUtilsTest.java[JsonPojoUtilsTest]
382382
* link:{integrationtestdir}/com/salesforce/revoman/input/json/JsonPojoUtils2Test.java[JsonPojoUtils2Test]
383383
====
@@ -389,7 +389,7 @@ The configuration offers methods through which the execution strategy can be con
389389
* `haltOnAnyFailure` — This defaults to `false`. If set to `true`, the execution fails-fast when it encounters a failure.
390390
* `haltOnFailureOfTypeExcept` — This accepts pairs of `ExeType` and a `PostTxnStepPick` which are used to check if a Step can be ignored for failure for a specific failure type
391391
* `runOnlySteps`, `skipSteps` — All these accept a `predicate` of type `ExeStepPick`, which is invoked passing the current `Step` instance to decide whether to execute or skip a step.
392-
** There are some `ExeStepPick` predicates bundled with ReṼoman under `ExeStepPick.PickUtils` e.g `withName`, `inFolder` etc. You can write a custom predicate of you own too.
392+
** There are some `ExeStepPick` predicates bundled with ReṼoman under `ExeStepPick.PickUtils` e.g `withName`, `inFolder` etc. You can write a custom predicate of your own too.
393393

394394
[#_pre_and_post_hooks]
395395
=== Pre- and Post-Hooks
@@ -428,9 +428,8 @@ which can be populated and picked-up by subsequent steps.
428428
For example, you may want some `xyzId` but you don't have a Postman collection to create it.
429429
But instead, you have a Java utility to generate/create it.
430430
You can invoke the utility in a pre-hook of a step and set the value in `rundown.mutableEnv`,
431-
so the subsequent steps can pick up value for `{+{xyzId}+}` variable from the environment.
431+
so the later steps can pick up value for `+{{xyzId}}+` variable from the environment.
432432

433-
[#_response_validations]
434433
==== Response Validations
435434

436435
* Post-Hooks are the best place to validate response right after the step.
@@ -439,13 +438,11 @@ so the subsequent steps can pick up value for `{+{xyzId}+}` variable from the en
439438

440439
=== Pre-req and Tests scripts
441440

442-
[.lead]
443-
Pre-req and Tests scripts support makes sure that the Postman collection used for manual testing can be used *as-is* for the automation also, without any resistance to modify or overhead of maintaining separate versions for manual and automation.
444-
445-
* This tool can execute JavaScript written under the https://learning.postman.com/docs/writing-scripts/script-references/test-examples/[Pre-req and Tests tabs of Postman].
441+
* Postman lets you write custom javascript in https://learning.postman.com/docs/writing-scripts/script-references/test-examples/[Pre-req and Tests tabs] that get executed before and after a step respectively. When you export the collection as a template, these scripts also come bundled.
442+
* ReṼoman can execute this javascript on JVM. This support ensures that the Postman collection used for manual testing can be used *as-is* for the automation also, without any resistance to modify or overhead of maintaining separate versions for manual and automation.
446443
** Pre-req JS is executed as the first step before Unmarshall request.
447444
** Tests JS is executed right after receiving an HTTP response.
448-
* ReṼoman supports using of any `npm` modules inside your Pre-req and Tests javascript. You can install `npm` modules in any folder and supply in the Kick config, the relative path of the parent folder that contains the `node_modules` folder using `nodeModulesRelativePath(...)`. Use those `npm` modules inside your scripts with `require(...)`, for example:
445+
* ReṼoman supports using `npm` modules inside your Pre-req and Tests javascript. You can install `npm` modules in any folder and supply in the `Kick` config, the relative path of the parent folder that contains the `node_modules` folder using `nodeModulesRelativePath(...)`. Use those `npm` modules inside your scripts with `require(...)`, for example:
449446

450447
[source,javascript,indent=0,options="nowrap"]
451448
----
@@ -454,12 +451,12 @@ pm.environment.set("$currentDate", moment().format(("YYYY-MM-DD")));
454451
var futureDateTime = moment().add(365, 'days');
455452
pm.environment.set('$randomFutureDate', futureDateTime.format('YYYY-MM-DD'));
456453
457-
pm.environment.set("$quantity", _.random(1, 10)); // lodash doesn't need require
454+
pm.environment.set("$quantity", _.random(1, 10)); // lodash doesn't need `require`
458455
----
459456

460457
[TIP]
461458
====
462-
* `node_modules` adds a lot of files to check in. You may replace them with a single distribution file
459+
* `node_modules` Adds a lot of files to check in. You may replace them with a single distribution file
463460
464461
image::node_modules.png[]
465462
@@ -479,11 +476,12 @@ Each StepReport also has a `pmEnvSnapshot` to assert if a step has executed as e
479476

480477
=== Compose Modular Executions
481478

482-
* You don't have to squash all your steps into one mega collection. Instead, you can break them into easy-to-manage modular collections. `revUp` accepts a list of collection paths through `templatePaths`
483-
* But that doesn't mean you have to execute all these templates in one-go.You can make multiple `revUp` calls.
479+
* You don't have to squash all your steps into one mega collection. Instead, you can break them into easy-to-manage modular collections. `ReVoman.revUp()` accepts a list of collection paths through `templatePaths()`
480+
* But that doesn't mean you have to execute all these templates in one-go. You can make multiple `ReVoman.revUp()` calls for different collection.
484481
* If you wish to compose these executions, you can do so by adding the previous execution's `mutableEnv` to current execution using `dynamicEnvironment` parameter. This also comes in handy when you wish to execute a common step (e.g. `UserSetup`) inside a test setup method and use that environment for all the tests.
485482

486483
==== Custom Dynamic variables
484+
487485
If the in-built dynamic variables don't fit your need, you can plug your own dynamic variable generator
488486
to be invoked to generate a value for your custom variable-key in the template at runtime.
489487

@@ -517,10 +515,10 @@ The above test doesn't just have low code, but also low in Cognitive Complexity
517515

518516
== Perf
519517

520-
This entire execution of **~70 steps**, which includes **10 async steps**, took a mere *122 sec* on localhost.
518+
This entire execution of **~75 steps**, which includes **10 async steps**, took a mere *122 sec* on localhost.
521519
This can be much better on auto-build environments.
522520

523-
image:pq-revoman-test-time.png[Localhost Test time on FTest console]
521+
image:pq-revoman-test-time.png[Localhost Test time on FTest console for ~75 steps]
524522

525523
WARNING: ReṼoman internally is very light-weight, and the execution times are proportional
526524
to how your server responds or your network speed.

buildSrc/build.gradle.kts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,5 @@ dependencies {
1717
implementation(libs.kotlin.gradle)
1818
implementation(libs.spotless.gradle)
1919
implementation(libs.detekt.gradle)
20-
implementation(libs.spotbugs.gradle)
2120
implementation(libs.testLogger.gradle)
2221
}
-14.5 KB
Loading

libs.versions.toml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ jetbrains-annotations = "24.1.0"
1010
okio = "3.9.0"
1111
kover = "0.7.6"
1212
kotest = "5.8.1"
13-
spotbugs = "6.0.10"
1413
testLogger = "4.0.0"
1514
truth = "1.4.2"
1615
assertj-core = "3.25.3"
@@ -75,7 +74,6 @@ mockk = { module = "io.mockk:mockk", version.ref = "mockk" }
7574
kotlin-gradle = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" }
7675
detekt-gradle = { module = "io.gitlab.arturbosch.detekt:detekt-gradle-plugin", version.ref = "detekt" }
7776
spotless-gradle = { module = "com.diffplug.spotless:spotless-plugin-gradle", version.ref = "spotless" }
78-
spotbugs-gradle = { module = "com.github.spotbugs.snom:spotbugs-gradle-plugin", version.ref = "spotbugs" }
7977

8078
[bundles]
8179
kotest = [
@@ -92,7 +90,6 @@ kover = { id = "org.jetbrains.kotlinx.kover", version.ref = "kover" }
9290
kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
9391
detekt = { id = "io.gitlab.arturbosch.detekt", version.ref = "detekt" }
9492
spotless = { id = "com.diffplug.spotless", version.ref = "spotless" }
95-
spotbugs = { id = "com.github.spotbugs", version.ref = "spotbugs" }
9693
testLogger = { id = "com.adarshr.test-logger", version.ref = "testLogger" }
9794
moshix = { id = "dev.zacsweers.moshix", version.ref = "moshix" }
9895
kapt = { id = "org.jetbrains.kotlin.kapt", version.ref = "kotlin" }

settings.gradle.kts

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* http://www.apache.org/licenses/LICENSE-2.0
66
* ************************************************************************************************
77
*/
8-
plugins { id("com.gradle.enterprise") version "3.17" }
8+
plugins { id("com.gradle.develocity") version "3.17" }
99

1010
dependencyResolutionManagement {
1111
versionCatalogs { create("libs") { from(files("libs.versions.toml")) } }
@@ -21,12 +21,10 @@ dependencyResolutionManagement {
2121
}
2222

2323
gradleEnterprise {
24-
if (System.getenv("CI") != null) {
25-
buildScan {
26-
publishAlways()
27-
termsOfServiceUrl = "https://gradle.com/terms-of-service"
28-
termsOfServiceAgree = "yes"
29-
}
24+
buildScan {
25+
publishAlways()
26+
termsOfServiceUrl = "https://gradle.com/help/legal-terms-of-use"
27+
termsOfServiceAgree = "yes"
3028
}
3129
}
3230

src/integrationTest/java/com/salesforce/revoman/integration/restfulapidev/RestfulAPIDevTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ void restfulApiDev() {
3131
.environmentPath(PM_ENVIRONMENT_PATH) // <3>
3232
.nodeModulesRelativePath("js")
3333
.off());
34-
assertThat(rundown.stepReports).hasSize(3);
34+
assertThat(rundown.stepReports).hasSize(3); // <4>
3535
}
3636
// end::revoman-simple-demo[]
3737
}

0 commit comments

Comments
 (0)