Skip to content

Commit

Permalink
Add a section about testing to the Contributor guide, fix #2607
Browse files Browse the repository at this point in the history
  • Loading branch information
ppalaga committed Jun 25, 2021
1 parent e0ac12e commit 31bf0a4
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 3 deletions.
1 change: 1 addition & 0 deletions docs/modules/ROOT/nav.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
** xref:contributor-guide/create-jvm-only-extension.adoc[Create JVM-only extension]
** xref:contributor-guide/extension-metadata.adoc[Extension metadata]
** xref:contributor-guide/extension-documentation.adoc[Extension documentation]
** xref:contributor-guide/extension-testing.adoc[Testing extensions]
** xref:contributor-guide/ci.adoc[Continuous Integration]
** xref:contributor-guide/release-guide.adoc[Release guide]
* xref:reference/index.adoc[Reference]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,9 @@ Check the xref:contributor-guide/extension-metadata.adoc[Extension metadata] pag
8. Review the dependencies in the generated runtime and deployment modules. In case the given library is supported by
Quarkus, you may want to add a dependency on the corresponding Quarkus extension.

9. Complete the integration test module under `integration-tests/foo-abc`. Make sure you test both the consumer and the
producer of the component (if the component supports both). Make sure the tests are passing both in the JVM mode
(`mvn test`) and in the native mode (`mvn verify -Pnative`).
9. Complete the integration test module under `integration-tests/foo-abc`,
following the xref:contributor-guide/extension-testing.adoc[Extension testing] guide.
Make sure the tests are passing both in the JVM mode (`mvn test`) and in the native mode (`mvn verify -Pnative`).

10. In case of problems, consult the https://quarkus.io/guides/extension-authors-guide[Quarkus extension author's guide],
ask for help in the given GitHub issue or via https://camel.zulipchat.com[Camel Quarkus chat].
Expand Down
86 changes: 86 additions & 0 deletions docs/modules/ROOT/pages/contributor-guide/extension-testing.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
= Testing extensions

Testing Camel Quarkus extensions is very similar to xref:user-guide/testing.adoc[testing Camel Quarkus applications].
In both cases, the tests interact with a Camel Quarkus application.
The main difference is in the purpose of the tested application:
when testing extensions, it is there just for the sake of testing.
We use it as a means to indirectly verify the functionality of the underlying extension(s).

== Where are the integration tests?

Here are the the directories containing integration tests:

* `https://github.com/apache/camel-quarkus/tree/main/integration-tests[integration-tests]`
* `https://github.com/apache/camel-quarkus/tree/main/integration-test-groups[integration-test-groups/*]`
* `https://github.com/apache/camel-quarkus/tree/main/extensions-jvm[extensions-jvm/*/integration-test]`

== Anatomy of an extension integration test

=== The application

The application under test lives under `src/main` directory of the test module.
It should typically contain one or more Camel routes that utilize the Camel component brought by the extension under test.
If it helps to avoid additional dependencies, using `@ConsumerTemplate` and/or `@ProducerTemplate` may be favorable over having a full-fledged route.

=== Tests

Because xref:user-guide/testing.adoc#jvm-vs-native-tests[native tests run in a process separate] from the JVM running the tests,
all communication between the tests and the application under test must go over network or some other kind of interprocess communication.
We typically use JAX-RS endpoints (on the application side) and https://rest-assured.io/[RestAssured] (on the test side) for this purpose.

As suggested in the xref:user-guide/testing.adoc#native-tests[Testing user guide],
our native tests typically extend their JVM counterparts using the same test code for both JVM and native mode.
For this reason we abstain from using CDI and direct call of application code in our tests.

Except for https://rest-assured.io/[RestAssured],
we also use http://www.awaitility.org/[Awaitility] for awaiting some state
and https://assertj.github.io/doc/[AssertJ] for more advanced assertions.

[TIP]
====
As mentioned in xref:contributor-guide/create-new-extension.adoc[Create new extension] section,
`mvn cq:create -N -Dcq.artifactIdBase=my-component` generates some testing boilerplate for you.
If you want to add just a new test module for an existing extension,
`mvn cq:new-test -N -Dcq.artifactIdBase=my-component` is there for you.
====

== Minimal set of dependencies

Keeping the set of test module dependencies as small as possible has two main advantages:

* Less code is faster to compile to native image
* Additional code may introduce some side effects, mainly in native compilation.
For instance, an extension A may configure the native compiler in such a way that it causes also extension B to work properly in native mode.
However, if B was tested in isolation, it would not work.

== Grouping

Some of our test modules have very similar sets of dependencies.
While it is important to test them in isolation, running each separately takes quite a lot of time, mainly due to native compilation.
In such cases, it may make sense to create a "grouped" module that unifies (using some tooling) several isolated tests.
The grouped module may then be preferred in a CI job that validates pull requests, while the isolated tests are run only once a day.

== Coverage

When porting a Camel component to Quarkus, we generally do not want to duplicate all the fine grained tests that are often available in Camel already.
Our main goal is to make sure that the main use cases work well in native mode.
But how can you figure out which are those?

The use cases explained in the given components documentation usually give a good guidance.
For example, when writing tests for the SQL extension, you would go to documentation page of the xref:{cq-camel-components}::sql-component.adoc[SQL component]
and try to cover the use cases mentioned there:
xref:{cq-camel-components}::sql-component.adoc#_treatment_of_the_message_body[Treatment of the message body]
xref:{cq-camel-components}::sql-component.adoc#_result_of_the_query[Result of the query],
xref:{cq-camel-components}::sql-component.adoc#_using_streamlist[Using StreamList], etc.

In any case, both consumer and producer of the component (if the component supports both) should be covered.

== Lightweight functional tests

Especially when testing various configuration setups, having a separate integration test module for each configuration set would be an overkill.
`io.quarkus.test.QuarkusUnitTest` may suit well for such situations.

A big advantage of this kind of tests is that they are very lightweight and fast.
But on the other hand, they are executed only in JVM mode.

Please refer to the https://github.com/apache/camel-quarkus/tree/main/extensions/servlet/deployment/src/test/java/org/apache/camel/quarkus/component/servlet/test[Servlet extension] for an examples.
2 changes: 2 additions & 0 deletions docs/modules/ROOT/pages/user-guide/testing.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class MyTest {

An example implementation can be found https://github.com/apache/camel-quarkus/blob/main/integration-tests/bindy/src/test/java/org/apache/camel/quarkus/component/bindy/it/MessageTest.java[here].

[[native-tests]]
== A test running in native mode

As long as all extensions your application depends on are supported in native mode,
Expand All @@ -53,6 +54,7 @@ class MyIT extends MyTest {

An implementation of a native test may help to capture more details https://github.com/apache/camel-quarkus/blob/main/integration-tests/bindy/src/test/java/org/apache/camel/quarkus/component/bindy/it/MessageRecordIT.java[here].

[[jvm-vs-native-tests]]
== `@QuarkusTest` vs. `@NativeImageTest`

JVM mode tests annotated with `@QuarkusTest` are executed in the same JVM as the application under test.
Expand Down

0 comments on commit 31bf0a4

Please sign in to comment.