This is an automated email from the ASF dual-hosted git repository.
oscerd pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-kamelets.git
The following commit(s) were added to refs/heads/main by this push:
new c62880b30 chore: rewrite the Kamelet testing guide for Citrus (was
YAKS) (#2905)
c62880b30 is described below
commit c62880b3036e390bcd08053ab0b15ef58c01f4a1
Author: Andrea Cosentino <[email protected]>
AuthorDate: Fri Jul 3 14:44:39 2026 +0200
chore: rewrite the Kamelet testing guide for Citrus (was YAKS) (#2905)
The "Testing" section of the developer guide documented YAKS + Gherkin
.feature files run against a Kubernetes cluster, but the repository's tests
are Citrus tests under tests/camel-kamelets-itest that drive Kamelets with
Camel JBang. Rewrite the section to describe the actual workflow: a Pipe
that
wires the Kamelet, a *.citrus.it.yaml test that runs it via camel jbang and
verifies it, and a *IT.java factory that registers it -- with a worked
log-sink example and the mvn -Denable.integration.tests run commands.
Signed-off-by: Andrea Cosentino <[email protected]>
Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
---
docs/modules/ROOT/pages/development.adoc | 186 +++++++++++++------------------
1 file changed, 76 insertions(+), 110 deletions(-)
diff --git a/docs/modules/ROOT/pages/development.adoc
b/docs/modules/ROOT/pages/development.adoc
index 606e03d15..ecfe22129 100644
--- a/docs/modules/ROOT/pages/development.adoc
+++ b/docs/modules/ROOT/pages/development.adoc
@@ -1422,154 +1422,120 @@ This will create a new integration that forwards the
Apache Camel logo to your p
The most obvious way to test a Kamelet is via an e2e tests that verifies if
the Kamelet respects its specification.
-https://github.com/citrusframework/citrus[Citrus] is the framework of choice
for such e2e tests. You can find more information and
-documentation starting from the
https://github.com/citrusframework/citrus[Citrus GitHub repository]. Here we'll
provide examples for the Kamelets above.
+https://github.com/citrusframework/citrus[Citrus] is the framework of choice
for such e2e tests. Integration tests live
+under `tests/camel-kamelets-itest/src/test/resources/<feature>/`: each one is
a Citrus `+*.citrus.it.yaml+` test that
+drives the Kamelet with https://camel.apache.org/manual/camel-jbang.html[Camel
JBang] -- it runs a Camel `Pipe` that
+wires the Kamelet under test and then asserts the resulting behaviour.
-=== Testing a source
-
-YAKS allows writing a declarative
https://cucumber.io/docs/gherkin/reference/[Gherkin] file to specify the
behavior of the Kamelet.
-
-Let's try to test the earthquake Kamelet above, a Gherkin file for it should
look like:
-
-.earthquake-source.feature
-[source,gherkin]
-----
-Feature: Kamelet earthquake-source works
-
- Background:
- Given Disable auto removal of Kamelet resources
- Given Disable auto removal of Kubernetes resources
- Given Camel K resource polling configuration
- | maxAttempts | 60 |
- | delayBetweenAttempts | 3000 |
-
- Scenario: Bind Kamelet to service
- Given create Kubernetes service test-service with target port 8080
- And bind Kamelet earthquake-source to uri
http://test-service.${CITRUS_NAMESPACE}.svc.cluster.local/test
- When create Pipe earthquake-source-uri
- Then Pipe earthquake-source-uri should be available
- And Camel K integration earthquake-source-uri should be running
-
- Scenario: Verify binding
- Given HTTP server "test-service"
- And HTTP server timeout is 120000 ms
- Then expect HTTP request header:
Content-Type="application/json;charset=UTF-8"
- And receive POST /test
- And delete Pipe earthquake-source-uri
-----
-
-As you see this is a declarative test that is materialized into something that
actually checks that the service generates some data.
-Checks can be also more detailed than this one, but checking that it generates
some JSON data is enough for a "smoke test" that verifies that the Kamelet
-can be actually used.
-
-The test requires that you're connected to a Kubernetes cluster and have also
YAKS installed (refer to the
https://citrusframework.org/yaks/reference/html/index.html[YAKS documentation]
for more information).
-We're also going to use the CLI:
-
-[source]
-----
-# We assume the Kamelet is already installed in the namespace
-yaks run earthquake-source.feature
-----
+The building blocks of a test are:
-When testing a source, the backbone of the Gherkin file that you'll write is
similar to the one above.
-Depending on the source under test, you may need to stimulate the production
of some data using additional Gherkin steps
-before verifying that the data has been produced
-(in our case, it's better not to try to stimulate an earthquake :D).
+* a `Pipe` YAML that binds the Kamelet under test (a source is bound to a
verifiable sink; a sink is fed by a source);
+* a `+*.citrus.it.yaml+` test that runs the `Pipe` and verifies it;
+* a `+*IT.java+` class that registers the resource folder with a Citrus test
factory.
-=== Testing a sink
+=== A worked example
-A test for a sink is similar to the one for the source, except that we're
going to generate data to feed it.
+The simplest sink to assert against is `log-sink`, whose output can be matched
with a `logMessage`. The `log` suite
+tests it by feeding it with `timer-source`.
-To send data to the Kamelet we may think to bind it to another Kamelet of type
`webhook-source`, that allows us to
-send data to it via HTTP. Let's create a parameterized binding like the
following one:
+First, the `Pipe` that wires the Kamelets together:
-.webhook-to-telegram.yaml
+.log/log-sink-pipe.yaml
[source,yaml]
----
apiVersion: camel.apache.org/v1
kind: Pipe
metadata:
- name: webhook-to-telegram
+ name: log-sink-pipe
spec:
source:
ref:
kind: Kamelet
apiVersion: camel.apache.org/v1
- name: webhook-source
+ name: timer-source
properties:
- subpath: message
+ period: 10000
+ message: "{{message}}"
sink:
ref:
kind: Kamelet
apiVersion: camel.apache.org/v1
- name: telegram-sink
+ name: log-sink
properties:
- authorizationToken: "${telegram.authorization.token}"
- chatId: "${telegram.chat.id}"
+ loggerName: "test-log-sink"
+ showHeaders: false
----
-This will expose an HTTP endpoint that we can use to forward a message to
Telegram. It requires that two parameters are set
-in the YAKS configuration before creation. Those can be set in a simple
property file:
+Then the Citrus test that runs the `Pipe` and verifies the message reaches the
sink:
-.telegram-credentials.properties
-[source,properties]
+.log/log-sink-pipe.citrus.it.yaml
+[source,yaml]
----
-telegram.authorization.token=your-own-token
-telegram.chat.id=your-own-chat
+name: log-sink-pipe-test
+variables:
+ - name: "message"
+ value: "Hello from the log-sink test!"
+actions:
+ # Run the Pipe as a Camel JBang integration
+ - camel:
+ jbang:
+ run:
+ waitForRunningState: false
+ integration:
+ file: "log/log-sink-pipe.yaml"
+ systemProperties:
+ properties:
+ - name: "message"
+ value: "${message}"
+
+ # Verify the message reaches the sink
+ - camel:
+ jbang:
+ verify:
+ integration: "log-sink-pipe"
+ logMessage: "${message}"
+----
+
+Finally, register the resource folder in a `+*IT.java+` factory method so
JUnit runs it:
+
+.CommonIT.java
+[source,java]
----
-
-Then we're ready to define the feature we want to test, i.e. the ability to
send a message via the Telegram API.
-
-An example of "smoke test" can be the following one:
-
-.telegram-sink.feature
-[source,gherkin]
+@CitrusTestFactory
+public Stream<DynamicTest> log() {
+ return
CitrusTestFactorySupport.factory(TestLoader.YAML).packageScan("log");
+}
----
-Feature: Kamelet telegram-sink works
- Background:
- Given Disable auto removal of Kamelet resources
- Given Disable auto removal of Kubernetes resources
- Given Camel K resource polling configuration
- | maxAttempts | 60 |
- | delayBetweenAttempts | 3000 |
+=== Testing a source
+To test a *source*, put the Kamelet under test on the `source` side of the
`Pipe` and bind it to a verifiable sink:
+`log-sink` when a log assertion is enough, or the Citrus HTTP server for a
stricter check on the emitted payload -- the
+`timer` and `earthquake` suites bind their source to an HTTP endpoint and
assert the received request. When the source
+consumes from an external system (a broker, a cloud service, ...), start it
with
+https://java.testcontainers.org/[Testcontainers] through the matching Citrus
module, as the `aws`, `kafka` and
+`mongodb` suites do.
- Scenario: Bind webhook to Kamelet sink
- Given load variables telegram-credentials.properties
- And load Pipe webhook-to-telegram.yaml
- Then Pipe webhook-to-telegram should be available
- And Camel K integration webhook-to-telegram should be running
+=== Testing a sink
+To test a *sink*, feed it from a source that generates data -- usually
`timer-source` -- and assert the effect the sink
+produced: a `logMessage`, an HTTP request received by the Citrus HTTP server,
a row written into a Testcontainers
+database, and so on. The `log`, `http` and `slack` suites are good starting
points.
- Scenario: Send a message to the Telegram Chat
- Given URL: http://webhook-to-telegram.${CITRUS_NAMESPACE}.svc.cluster.local
- And HTTP request timeout is 60000 milliseconds
- And wait for GET on path / to return 404
- Given HTTP request headers
- | Content-Type | text/plain |
- And HTTP request body
- """
- Hello from YAKS!
- """
- When send POST /message
- Then receive HTTP 200 OK
- And delete Pipe webhook-to-telegram
+=== Running the tests
-----
+Run the whole integration suite from the repository root:
-This test will only check that the Telegram API accept the message created by
the test.
+[source]
+----
+mvn verify -pl :camel-kamelets-itest -Denable.integration.tests
+----
-This can be run with the following command:
+or a single factory while iterating on one Kamelet:
[source]
----
-# We assume that both the webhook-source and the telegram-sink kamelet are
already present in the namespace
-yaks run telegram-sink.feature --resource webhook-to-telegram.yaml --resource
telegram-credentials.properties
+mvn verify -pl :camel-kamelets-itest -Denable.integration.tests
-Dit.test=CommonIT#log
----
-If everything goes well, you should receive a message during the test
execution.
-
-For a more specific test that checks also the content sent to Telegram, you
should add additional Gherkin steps
-to get and verify the actual message via other Telegram APIs. We're not going
in so much details for this example,
-but the Gherkin file highlighted above is a good approximation of the backbone
you'll find in tests for Kamelets of type "sink".
+A Kamelet whose behaviour test passes should carry the
`camel.apache.org/kamelet.verified: "true"` label.