Documentation Index
Fetch the complete documentation index at: https://platform.docs.zenoo.com/llms.txt
Use this file to discover all available pages before exploring further.
Testing
Tests should be part of all user stories for a hub instance or a connector. For a quick start take a look at Instance template and Connector template. Full example with non-trivial tests can be found in Connector tutorial OTP. The best practice is to keep anything that calls 3rd party services inintegration folder instead of test, because
you don’t have control over these services, and they can be down or calling them can incur costs. Tests in test folder should be
as complete as possible and they should use mocks for connectors to external services. Running tests in test folder should be part
of build/release action, while tests in integration folder should be run manually by developer as needed.
Another best practice is to split your workflow into smaller bits, ideally the main workflow should be just a chain of calls to
one-purpose sub-workflows and functions with occasional updates of attributes. It is much more readable and easily testable
than one huge workflow of hundreds of lines. Also, whenever possible you should first create tests for each individual
sub-workflows and sub-functions.
Example of a workflow that is split into smaller better testable parts:
Configuration of your project
The Zenoo Hub provides extensive support for testing, and you should definitely make as much out of it as possible. Addhub-test-starter dependency to your project’s build.gradle to access the whole testing support part of the Zenoo Hub:
test and integrationTest tasks:
Setup of the Zenoo Hub for Tests
You will need a separate hub configuration for tests. Usually you should setComponentConfigurer to be an empty list because you will register
components as needed for individual tests. HubConfigurer should have all necessary connectors - mocked for test folder tests
and real ones for integration folder tests.
Example of TestConfig class:
Writing a test
Tests in the Zenoo Hub utilize Spock as test framework, you can learn basics in a tutorial on Baeldung. The easiest way to write a test is to extendWorkflowTestSpecification. It has all the necessary methods for you to test a DSL workflow or function.
1. Prepare mocks
Use Spock’sgiven block to set up mocks as needed. The Zenoo Hub provides MockConnectorExchange class to easily create connector mocks ([see below](/technical-specification/hub-backend/testing#Mocking connectors)).
MockConnectorExchange class implements withResult, withError and withDelay methods that you can configure a connector mock with.
Example:
2. Register components and start workflow or function
WorkflowTestSpecification contains testBuilder attribute that helps with registering and configuring components for a test.
testBuilder implements several methods to serve that end:
setWorkflow- workflow that will be called to run the test.setFunction- similar as above but for function, not workflow. There can be either setWorkflow or setFunction but not both.setInput- sets an input for function or workflow upon its call. See DSL workflow or DSL function for details.setConfig- sets config for the component of function or workflow. See component configuration for details.addDependency- adds a component dependency for the test. Don’t forget to add the component where the workflow or function is located itself.
build will generate a testing component, then it will register it and its dependencies,
and finally it will start a testing workflow from the testing component.
Example of testBuilder usage to set up the test:
3. Check workflow steps and results
Once the workflow has started it will pause on eachroute DSL command waiting for Hub Client to submit user input.
There is a simple-to-use function submit inherited from WorkflowTestSpecification that you can use to simulate user data entry.
You should also check that workflow stopped on the right route at each step, for that you can check route part of response function.
Example of checking route and submitting user data:
response method returns WorkflowTesterResponse which
depending on the state of execution can become one of these types:
-
route - workflow execution is paused and awaits user input. See RouteResource. Available attributes:
- uuid,
- uri - the identifying location from route definition,
- terminal - whether the route is terminal,
- backEnabled - whether back is enabled at this route,
- export - object or list of exported attributes for the Hub Client,
- payload.
- result - workflow/function has finished and result of the execution is returned. See ResultResource. There are no attributes, it just contains the object that was returned from the callable.
-
error - there has been an error while executing a DSL code or a connector. See ErrorResponseResource. Available attributes:
- code,
- message.
-
validation error - when a DSL code fails to be validated. This can be either invalid DSL, missing attribute or invalid input.
See ValidationResult.
There is just one attribute,
errorsthat contains list of ValidationError.ValidationErrorhas just one attribute,message.
WorkflowTestSpecification is upload. It allows you to simulate user uploading
file through the Hub Client. The methods itself uploads a file to the test hub instance and returns a FileDescriptor
that you can use as parameter for submit method.
Example:
Mocking connectors
In most cases it should be enough to useMockConnector class to create a new bean in your TestConfig and pass them on to hubConfigurer.
In this way you configure the Zenoo Hub to work with mocks instead of the real connectors.
Example of bean creation:
hubConfigurer
MockConnector contains an attribute mockExchange of type MockConnectorExchange that is meant to be used to set mock responses for the connector.
-
withConfigConsumer(Consumer<CustomConnectorConfig> consumer)allows you to add consumer for connector config which is useful to verify configuration that was passed on to the connector. -
withError()sets a simpleConnectorException("Error")as the mocked response of the connector. -
withResult(Object result)- sets return value of the mock. -
withDelay(int delay)adds delay in seconds before response is returned from the mock when executed. You can take advantage of this method to check behaviour of your flow when a response from a connector takes some time.