authorjapps / zerocode

A community-developed, free, opensource, automated testing framework for microservices APIs, Kafka(Data Streams) and Load testing. Zerocode Open Source enables you to create, change and maintain your automated test scenarios via simple JSON or YAML files. Visit documentation below:
https://zerocode-tdd.tddfy.com
Apache License 2.0
893 stars 392 forks source link

Improve testability of MultiSteps Scenario Runner #272

Open BartRobeyns opened 5 years ago

BartRobeyns commented 5 years ago

This technical debt issue is a result of a discussion in #263, recognizing the need for testability of the MultiStepsScenario Runner.

To get there, responsibilities should be split out into different classes/methods, and participant classes should become mockable/verifiable.

Objective

Ideally, after refactoring this method, we would be able to unit-test individual responsibilities like:

without having to create json-based scenarios for them.

Only having json-based scenarios to test with have two major drawbacks:

Analysis of the code

As a base for further discussion, it's interesting to see what areas we could improve on. Very much my personal view and very open for discussion.

1. Single method with too many responsibilities

It handles:

At single step-execution level, it takes care of:

For every retry, it:

At the end of the retry-loop, it handles the assertions:

At the end of the scenario, it:

2. Some structural code issues, mostly a result of the many responsibilities:

3. Reduced testability

officiallysameer commented 5 years ago

@BartRobeyns Thanks for putting this together. Do you have solution for this? We can tackle each point separately in different tickets.(One ticket will be too big to handle)

BartRobeyns commented 5 years ago

Where to begin? :)

Indeed it would be too big to handle; and I think we'd need some preparatory work before really diving in. Trying a first split of concerns (between the scenario and the steps), led me to the conclusion that the "lots of local variables" issue mentioned above needs to be handled first.

This is the set of variables that are shared between scenario-processing and step-processing:

Having so much shared state between scenario-handling and step-processing makes it more difficult to evolve and test individually. And it creates a 10-argument method call :) : StepExecutorImpl stepExecutor = new StepExecutorImpl(scenario, step, scenarioExecutionState, notifier, description, reportBuilder, reportResultBuilder, host, port, applicationContext);

Another issue that popped up is the use of logCorrelationshipPrinter's correlationId. It gets assigned a generated UUID in every step-iteration, and the one from the last iteration is used at the scenario-level to name to report-file. That name is important because it's used in the HTML-view to link the scenario to it's step-executions. If we want to split the step-processing from the scenario-handling, this should be changed.

How to solve these issues is very much a design decision, that only the experienced people can make. It requires understanding of the objectives and behaviour of logCorrelationShipPrinter, reportBuilder, reportResultBuilder, scenarioState, ... to be able to decide if and how to change the interaction with them.