Types and features of Mule connector testing


    Mule connector testing is a necessary step of its implementation. The following different types of testing are considered here:

    Functional tests, which purpose is to verify whether the connector’s behavior is right (the work of processors and methods that work with metadata, operations with WSDL, etc.) in various Mule versions. Therefore, these tests are needed to verify compatibility with other Mule versions.

    System tests are necessary to test connector methods, which establish connecting to external services, and to test the work of the connector in case of an incorrect configuration. These can be the following test cases: invalid password or login, invalid server of authorization, etc. Within these tests all classes with configurations should be tested.

    Unit tests are not obligatory ones, but are recommended to be used for testing of separate pieces of code, that have left uncovered after performing system and functional tests.

    Load tests are not obligatory for complete certification, but can be implemented for studying the behavior of the connector under conditions of heavy use.

    System and functional tests are obligatory for certification of the Mule connector. According to Mule connectors certification rules, the tests covering of the code should be more than 70%. If system and functional tests do not cover the code by 70%, unit tests can be used to increase coverage.

    An example of system and functional tests implementation can be found in the reference project for the implementation of the Mule connector to the social network VK.

    Organization of tests at the packages level

    A strictly defined package structure should be used to complete certification:

    1. org.mule.modules.<сonnector-project>.automation.runner contains all TestSuites (FunctionalTestSuite, SystemTestSuite).
    2. org.mule.modules. <сonnector-project> .automation.functional contains all functional tests.
    3. org.mule.modules.<сonnector-project>.automation.system contains all system tests.
    4. org.mule.modules.<сonnector-project>.automation.unit contains all unit tests.

    For various utility classes org.mule.modules<Connector-project>.automation.utils.
    package can be used.

    Tests configuration

    A file with properties should be created to run tests and perform connection to an external service. This file should be situated in src/test/resources directory. By default, this file is called automation-credentials.properties. Also, this file can be set at test start using the -Dautomation-credentials.properties = FILENAME option.

    Functional tests

    Functional tests should be carried out to complete certification. These tests should cover the code for all processors, classes working with metadata, operations with WSDL and methods marked with @Source and @Paged annotations. For this purpose, Mule provides Connector Testing Framework (CTF).

    The structure of the class, that uses CTF

    Names of the functional tests should have TestCases ending. For example, CreateEntityTestCases.

    All classes with tests that use CTF should be inherited from AbstractTestCase<ConnectorName> class and call a parent class constructor.

    Also, a separate class that will be inherited from AbstractTestCase<ConnectorName>, will call a parent class constructor and create data for tests, can be created. Then this class will be a parent for classes with various test cases.

    In the setup() method, marked with @Before annotation, creation of the necessary data is performed. To generate test data, TestDataBuilder.java class should be created in org.mule.modules.<connector-project>.automation.functional package, which will return the necessary data:

    Reset of sandbox takes place in tearDown() method, marked with @After annotation.

    Processors testing

    If it is possible, each processor of connector should be covered with tests.

    A class with tests for processors should have the same structure as all classes that use CTF.

    The test case for processor is as follows:

    To call operation of connector, the connector object should be got with the help of getConnector() method, which is given by CTF.

    DataSense testing

    Dynamic DataSense was used during development of connector for MDM system. DataSense testing has been performed in the following way:

    Each DataSenseResolver of connector should be covered by tests if it is possible.

    The class with tests for DataSense should have the same structure as all classes that use CTF.

    DataSenseResolver test class should have <DataSenseResolverName>MetaDataTestCases name and contain two tests: testMetaDataKeys and testMetaData.

    CTF provides getDispatcher() method that allows to get CTF dispatcher object. In turn, this dispatcher has fetchMetaDataKeys() and fetchMetaData(keyName) methods. The first method retrieves all metadata keys, the second method retrieves metadata for the particular key.

    An example of this testing :

    TestMetaDataKeys and testMetaData methods should be marked with @MetaDataTest annotation.

    Adding tests to TestSuite

    All functional tests should be added into TestSuite named FunctionalTestSuite. If there are several TestSuites (for example, tests are logically divided into different TestSuites), then they should to be merged into FullFunctionalTestSuite.

    An example of FunctionalTestSuite :

    All classes with tests (CPU, metadata, etc.) should be listed in @SuiteClasses annotation. Initialization of connector context and CTF as a whole takes place in initialiseSuite() method. Release of CTF resources takes place in shutdownSuite() method.

    System Tests

    These tests are obligatory for certification. This type of tests includes all tests that are not functional, but at the same time they require connection. For example, this is testing with an incorrect password or login, an incorrect address of authorization server, etc.

    To conduct system tests, the valid properties are taken from the automation-credentials.properties file, which is used in the functional tests, and after that some correct data are changed to incorrect ones.

    Each class with connection configuration should be tested. The class for testing the configuration should have the name <ConfigName>TestCases. All system tests should be added to SystemTestSuite in the same way as functional tests.

    System test example:

    Unit tests

    Unit tests are not obligatory for connector certification. However, if there remain sections of code that should be covered with tests after completing the functional and system tests, unit tests are used for this purpose.

    Names for unit tests should be chosen according to JUnit naming conventions (class name should have endings Test or TestCase). It is not necessary to combine unit tests into TestSuites.

    Running tests

    Tests can be run using Maven from the command line or in Anypoint Studio.
    An example of a command to run system tests from Maven:

    Mvn surefire: test -Dest = SystemTestSuite

    Result of the command:

    Press right mouse button on the test or TestSuite, Run As -> JUnit Test to run tests in Anypoint Studio.

    The result of tests in the studio is as follows:

    Load tests

    Load tests also are not required for connector certification, but they can be used for studying connector’s behavior in the case of heavy usage and its efficiency. Apache JMeter can be used as one of the tools for conducting load tests. In this case Mule flow, that uses connector and has HTTP listener connector as an entry point to application, can be built:

    In this case JMeter will make calls to the address set in the http-connector.

    JMeter work results:

    Also there can be made a comparison of connector working time with working results of components which are part of Mule (for example, the Http or Database connector). Based on these results, efficiency of connector is evaluated and conclusions are drawn about the need to optimize performance of connector.

    An example of flow for connector testing:

    The number of operations that connector should perform is specified in this flow. A runtime for these operations and average runtime for one operation are measured next.