I asked this question regarding unit tests a couple of weeks ago: Best practices for automated tests
Now I would like to come back to the ESSingleNodeTestCase
-class.
I managed to get it to start an elastic server with the steps mentioned at the end of this post in case anybody is interested.
Now I realized that the Client
provided by the ESSingleNodeTestCase
is from the org.elasticsearch.client.internal
-package. However the regular client that we are using with API version 8 is coming from the co.elastic.clients.elasticsearch
-package. In other words, they are not compatible, even though they have similar interfaces. This means I can not use this base class to e.g. test my queries created using the fluent API from v8. And this is exactly what I would like to do.
So here are a couple of questions:
- Is
ESSingleNodeTestCase
actually something that should be used by external developers or is it only meant for internal purposes? - Are there any plans to migrate
ESSingleNodeTestCase
to version 8? - Is there any (other?) way that an elastic instance can be emulated so it can used in unit tests that can be executed everywhere (locally, build server, etc.)?
Maybe some background on why I believe this would be so powerful:
When writing code that uses an SQL-DB we tend to use h2database for unit tests. This has a lot of benefits:
- Makes development easier as we wouldn't even need a local DB.
- Makes unit tests more meaningful as we need less mocking/faking.
- Or in other words: I guess we should be able to run our unit tests in an as close to a real environment as possible and do it as early as possible ("Shift-left").
- You could argue that writing tests that access a database-like thing (be it an SQL-DB or elastic, etc.) is a no-go as this should rather be done in an integration test. I understand that. But on the other hand I believe you could consider the DB an integral part of the application, that accesses it. Especially queries and co. are very tightly coupled to the database. Hence they should be tested in unit tests.
I'm wondering if there are any official recommendations from elastic on how to deal with all of this?
I found this: elasticsearch-8.5.3.tar.gz: .../TESTING.asciidoc | Fossies (see chapter " How to write good tests?"). However I assume this rather meant for elastic-internal tests.
As mentioned above, here are the steps required to make ESSingleNodeTestCase
work:
It is very important to use junit4 (not 5!), as the base class uses annotations from junit4 (at least at the time of writing).
Add an own policy file (java_policy_tests.policy
):
grant {
permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
permission org.elasticsearch.secure_sm.ThreadPermission "modifyArbitraryThreadGroup";
};
Make sure tests are started using that file:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>
-Djava.security.policy==./java_policy_tests.policy
</argLine>
</configuration>
</plugin>
Then I simply inherited from ESSingleNodeTestCase
and the server was started when executing the tests. By using client()
provided from the base class