Disable autodeployment for unit tests doesn't work

Hey together,

I’ve build a JUnit-test for my spring-boot-process-application and set camunda.bpm.auto-deployment-enabled: false. The project contains an empty processes.xml on src/main/resources/META-INF.

If I run the JUnit test, the spring boot engine starts up and deploys the process.bpmn first, before deploying it again for the deployment annotation. Here are some line from the console:

20:45:26.143 [main] INFO  org.camunda.bpm.container - ENGINE-08024 Found processes.xml file at file:/C:/Users/Ingo%20Richtsmeier/git/spring-boot-klausur/klausur/target/classes/META-INF/processes.xml
20:45:26.145 [main] INFO  org.camunda.bpm.container - ENGINE-08025 Detected empty processes.xml file, using default values
20:45:26.157 [main] INFO  org.camunda.bpm.container - ENGINE-08023 Deployment summary for process archive 'camundaBpmProcessApplication': 

        process.bpmn

20:45:26.441 [main] INFO  org.camunda.bpm.application - ENGINE-07021 ProcessApplication 'camundaBpmProcessApplication' registered for DB deployments [7ffef57c-b8eb-11e7-9a38-8c899f49595d]. Will execute process definitions 

        klausur[version: 1, id: klausur:1:801da10e-b8eb-11e7-9a38-8c899f49595d]
Deployment does not provide any case definitions.
20:45:26.463 [main] INFO  org.camunda.bpm.container - ENGINE-08050 Process application camundaBpmProcessApplication successfully deployed
20:45:26.474 [main] INFO  c.c.c.klausur.InMemoryH2Test - Started InMemoryH2Test in 9.413 seconds (JVM running for 10.826)
20:45:26.499 [main] DEBUG org.camunda.bpm.engine.test - annotation @Deployment creates deployment for InMemoryH2Test.testParsingAndDeployment
20:45:27.349 [main] INFO  o.c.b.e.p.j.r.TestCoverageProcessEngineRule - testParsingAndDeployment(com.camunda.consulting.klausur.InMemoryH2Test) succeeded.
20:45:27.349 [main] INFO  o.c.b.e.p.j.r.TestCoverageProcessEngineRule - testParsingAndDeployment test method coverage is 0.0
20:45:27.427 [main] DEBUG org.camunda.bpm.engine.test - annotation @Deployment deletes deployment for InMemoryH2Test.testParsingAndDeployment
20:45:27.466 [main] DEBUG org.camunda.bpm.engine.test - annotation @Deployment creates deployment for InMemoryH2Test.testHappyPath
20:45:27.847 [main] INFO  o.c.b.e.p.j.r.TestCoverageProcessEngineRule - testHappyPath(com.camunda.consulting.klausur.InMemoryH2Test) succeeded.
20:45:27.849 [main] INFO  o.c.b.e.p.j.r.TestCoverageProcessEngineRule - testHappyPath test method coverage is 1.0
20:45:27.880 [main] DEBUG org.camunda.bpm.engine.test - annotation @Deployment deletes deployment for InMemoryH2Test.testHappyPath

How can I disable the auto-deployment? The setting above doesn’t seem to work.

Here is the code of my example: https://github.com/ingorichtsmeier/spring-boot-klausur/tree/master/klausur

Cheers, Ingo

Hi Ingo

you are mixing two concepts … either you do a rule-based camunda test using teh ProcessEngineRule or you use the full spring “integration” test with a configuration-class/springbootapplication.

I never tried what you do in your test … you have a deployment and a rule-lifecycle managed by junit and a process engine managed by the spring runner … honestly, I am not sure what I would expect here if it was not camunda but any other spring integration test scenario.
What you can try to do is to deactivate the process-application scan for deployables in the test/resopurces/META-INF/processes.xml (<property name="isScanForProcessDefinitions">false</property>). But as I said: not sure what will happen.
I guess its a cleaner test strategy to use ProcessEngineRule based test on a “unit” level and then have an additional springrunner test for the integration level.

Jan

1 Like

Hi Jan.

Given the Camunda context, do you think there is a value in a pure in memory “unit” level? Is it worth the effort to have this additional level running a different spring configuration, probably behaving differently?
I think it would be much easier to “just” use a Spring Boot Runner as THE test environment - also used for in memory only scenarios. Especially given the fact that I do not know a lot of test scenarios in the Camunda context not being some kind of integration?

WDYT?

Cheers
Bernd

Not sure if I get what you mean … I tend to still stay close to the pyramid when it comes to testing, so my full SpringBootTest based on application context and component scan is my “last ressort”, before I do a lot of mock tests with the camunda in memory engine and mockito.

Building up a custom spring context just for testing is normally not required, its either mock or integration. But there are shades of gray involved, hard to make a black/white statement …

I am still happy if the customers manage to stick to one kind of testing - and the closer it is too real-life the less extra effort involved - that’s why I typically start with a Spring Boot Starter version (and most process applications I know call some systems via REST, SOAP or JMS/AMQP - where Spring has good abstractions to be used in testing).

I think it’s time for a “testing” webex session again :slight_smile:

I think it depends on the processes in the project. If it’s just a simple, straightforward microservice orchestration like this: https://cawemo.com/shares/c73ab139-8e5c-49ab-935b-aa715879b646, the unit test will only assert the activtity-ids. So it’s OK to skip it.

But if you have a process with gateways, call activities or user tasks, it reduces complexity a lot if do the simple unit test before changing to integration tests.

1 Like

Quick question: When using Spring I think it is best practice to use delegate expressions, resolving to Spring Beans. This will not work without any Spring Container running.

@Jan: What is your best practice of resolving this?
@Ingo: In the current archetype version this is a big showstopper - as soon as you start using Spring beans the unit test cannot access them and you are locked out.

Hi Bernd,

In the unit tests I always use Mocks.register("myDelegateExpression", new LoggerDelegate());.

In the camunda.cfg.xml is <bean class="org.camunda.bpm.engine.test.mock.MockExpressionManager"/> used as expression manager.

That’s a very basic way of mocking, but it works always.

Cheers, Ingo

But it means you have to do it in a “proprietary way”. So I think it is kind of not intuitive for “normal people” as it is not the normal Spring way.

Either way I make sure that we will use a ServiceTask in the Archetype to at least show how it is working. I still vote to delete the in memory unit test - but we can postpone the discussion into some team meeting where it fits.

Have a look at the camunda-bpm-mockito extension. It provides a lot of cool helpers to register mocks. In case of spring expressions, it is enough to call CamundaMockito.registerDelegateMock(Delegate.class)

There also is an autoMock feature that registers mocks for all delegateExpressions, but I have been told it might be buggy … if so, an issue would be a good idea.

But this means you use a different way for your tests than your real code. In my opinion that is too much complexity for most projects and I would prefer just to use the Spring Boot starter without any separate solution just for testing. As I said earlier - in most projects I am happy if the people get some basic tests running. Let’s wait and see (and collect learnings from more real-life projects on the way).

You are aware of Spring Boots “@MockBean”? IF you want to stick to a plain spring “integration-like” test, that would be all you need, just exchange some of your listeners/delegates you defined via delegateExpressions with mocks.

In order to use the @MockBean I think you have to fire up a Spring Boot Application Context - or? That is exactly what is not done in these kind of test cases as currently part of the archetype: https://github.com/camunda/camunda-archetypes/blob/master/camunda-archetype-spring-boot/src/main/resources/archetype-resources/src/test/java/unit/InMemoryH2Test.java

Should we have a phone session? I do not get your requirements … are you looking for a solution that works with camunda in memory (that would be MockExpressionManager and maybe the mockito extension) or do you want to run pure SpringBoot integration tests (in that case, @MockBean would be the way to change the behavior of selected components to simplify the test setup).

I have the impression that Ingo and I agree that using both in a classix test-pyramid way is a good practice … I am confused about what you are trying to achieve …

Bernd wants to get rid of the old fashioned, boring InMemoryH2Test

… and jump directly into the complexity of integration tests.

Let’s keep on trying to save him… :slightly_smiling_face:

1 Like