Es geht weiter mit unserer Blogreihe “Treat your processes like code – test them!“. Heute wollen wir uns ein häufig diskutiertes Thema genauer anschauen - Testabdeckung. Doch welche Rolle spielt die Coverage beim Testen von BPMN-Modellen und wie kann die Abdeckung gemessen werden?
In diesen Post werden wir dazu die folgenden Fragen behandeln:
Dazu werden wir das Beispiel aus den vorherigen Posts erweitern. Dieses ist in GitHub verfügbar. Außerdem gibt es einen kleinen Einblick in die Weiterentwicklung der Camunda BPM Process Test Coverage.
Doch warum ist die Testabdeckung eine wichtige Kennzahl für die Entwicklung automatisierter Prozesse? Die kurze Antwort ist: Aus technischer Sicht ist die BPMN eine Programmiersprache, deshalb sollte sie wie Code behandelt werden. Eine hohe Testabdeckung bringt viele Vorteile mit sich, zum Beispiel:
Dafür gibt es eine Community Erweiterung: die Camunda BPM Process Test Coverage. Diese visualisiert und überprüft den Abdeckungsgrad des Prozessmodells. Das Ausführen von JUnit-Tests erzeugt html-Dateien im Build-Ordner. Diese sehen wie folgt aus:
Die Erweiterung bietet dabei folgende Features:
Erweitern wir dazu unser Beispiel. Hierfür brauchen wir zunächst die Branch 02_process_dependencies
aus unserem GitHub-Repository. Für den ersten Setup sind lediglich 3 Schritte notwendig:
pom.xml
die folgende Dependency hinzu:<dependency> <groupId>org.camunda.bpm.extension</groupId> <artifactId>camunda-bpm-process-test-coverage</artifactId> <version>0.3.2</version> <scope>test</scope> </dependency>
camunda-cfg.xml
anpassen<bean id="processEngineConfiguration" class="org.camunda.bpm.extension.process_test_coverage.junit.rules.ProcessCoverageInMemProcessEngineConfiguration"> ... </bean>
WorkflowTest
an und ändern unsere @Rule
wie folgt:@Rule @ClassRule public static TestCoverageProcessEngineRule rule = TestCoverageProcessEngineRuleBuilder.create() .excludeProcessDefinitionKeys(DELIVERY_PROCESS_KEY) .build();
Wichtig ist, dass wir den Delivery Process
von der Coverage ausschließen. Denn dieser wird im Test lediglich als Mock bereitgestellt und steht somit nicht zur Verfügung.
Nun können wir den Test ausführen. Die Testergebnisse landen unter ./target/process-test-coverage
.
Wir sehen, dass 95% Coverage erreicht wurden, obwohl alles erfolgreich getestet wurde. Dies liegt jedoch an einem Bug in der Coverage-Library, die Compensation-Events nicht richtig nachverfolgt.
Schauen wir uns nun an, wie wir ein Coverage-Minimum definieren können, das automatisch geprüft wird. Hierfür haben wir zwei Möglichkeiten:
Diese sind ebenfalls miteinander kombinierbar. Auf Klassenebene können wir die Coverage wie folgt definieren:
@Rule @ClassRule public static TestCoverageProcessEngineRule rule = TestCoverageProcessEngineRuleBuilder.create() .excludeProcessDefinitionKeys(DELIVERY_PROCESS_KEY) .assertClassCoverageAtLeast(0.9) .build();
Eine Coverage von 1.0
ist auch aufgrund der vorhandenen Bugs nicht zu empfehlen. Auf Methodenebene können wir eine Coverage-Assertion wie folgt hinzufügen:
@Test public void shouldExecuteHappyPath() { Scenario.run(testOrderProcess) .startByKey(PROCESS_KEY, withVariables(VAR_CUSTOMER, "john")) .execute(); verify(testOrderProcess) .hasFinished(END_EVENT_ORDER_FULLFILLED); rule.addTestMethodCoverageAssertionMatcher("shouldExecuteHappyPath", greaterThanOrEqualTo(0.5)); }
Dabei stehen uns verschiedene org.hamcrest.Matchers
zur Verfügung, für diesen Anwendungsfall sind folgende sinnvoll:
greaterThan
greaterThanOrEqualTo
lessThan
lessThanOrEqualTo
Die Camunda BPM Process Test Coverage bietet noch ein paar weitere Features, wie das Ausschalten der Coverage auf Klassen- oder Methodenebene. Es lohnt sich somit einen Blick in das GitHub-Repository zu werfen.
Die grafische Darstellung der Testabdeckung in Form von HTML-Dateien ist für die lokale Entwicklung ausreichend. Es gibt jedoch speziell zwei Bereiche in denen die Library an ihre Grenzen stößt:
Die Testabdeckung ist eine großartige Kennzahl, wenn wir sie messen. Aber messen bedeutet auch, dass wir die historischen Daten im Auge behalten. Es geht darum, Verbesserungen oder Verschlechterungen transparent zu machen und damit für Motivation und Nachvollziehbarkeit zu sorgen. Dies bedeutet, dass wir eine Lösung brauchen, um die erstellten Reports zu sammeln und grafisch aufzubereiten.
Auf der einen Seite haben wir die lokale Entwicklung. Dort wird zunächst der Prozess angepasst, dann der dazugehörige Test implementiert und ausgeführt, das Testergebnis geprüft und anschließend beginnt alles von vorn. Ist das Modell und der Test fertiggestellt, wird der entsprechende Code ins Git-Repository gepusht.
In der Build-Pipeline wird dann der Test erneut durchgeführt. Doch wie werden bspw. bei einer Pull-Request die Ergebnisse visualisiert? Wie kann eine Veränderung der Coverage zum vorherigen Stand nachvollzogen werden? Mit der Camunda BPM Process Test Coverage ist das nicht out-of-the-box möglich.
Unter anderem aus diesen Gründen haben wir FlowCov entwickelt – eine Plattform, die genau diese Anforderungen abdeckt. Sie ermöglicht es, im Rahmen der eigenen Build-Pipeline die generierten Reports hochzuladen, um sie grafisch aufzubereiten und allen Stakeholdern zugänglich zu machen. Wer mehr darüber erfahren möchte, dem empfehlen wir unsere Docs.
Momentan wird die Camunda BPM Process Test Coverage neu entwickelt. Dabei werden verschieden Anpassungen und Features umgesetzt:
Falls du Lust hast mitzuwirken und eigene Ideen einbringen möchtest, würden wir uns über Contributions und Diskussionen freuen! Die Neuentwicklung findet in diesem Fork statt: https://github.com/holunda-io/camunda-bpm-process-test-coverage/tree/develop/extension
Rechtliches