> ## Documentation Index
> Fetch the complete documentation index at: https://docs.activeviam.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Testing

This section explains how to set up and run integration tests for
bookmarks, provides samples for custom integration tests, and outlines
unit tests.

There are a number of unit and integration tests across the project in
each module.

Unit and integration tests related to the `mr-application` module can be found in the separate module `mr-application-tests`, as they are not required by clients and would slow down the installation process.

## Integration Tests

By default, the integration tests will not get executed when you build
the project, as they have a severe impact on build
time.

There is a separate Maven profile called `IT` that you can run with the
following command when you want to execute the integration tests:

`mvn install -P IT`.

### Bookmark Tests

The application uses a test harness library, which has been developed to regression
test Atoti Server projects. This library enables us to start up a cube,
execute MDX queries and assert the values match.

By default, the Atoti Server instance will load data
from */src/test/resources/data*.

#### Creating/Replacing Expected Results

There are several test classes used for integration tests present in the `com.activeviam.mr.regression` package in the `mr-application-tests` module:

<table><thead><tr><th>Class name</th><th>Purpose</th><th>Remarks</th></tr></thead><tbody><tr><td><code>ReferenceRegressionDatabricksTestIT</code></td><td>Check results of queries against a Databricks database compared with results in the folder <code>src/test/resources/test-bookmarks</code>.</td><td>Used for internal AcitveViam tests</td></tr><tr><td><code>ReferenceRegressionMSSQLTestIT</code></td><td>Check results of queries against an MS SQL database compared with results in the folder <code>src/test/resources/test-bookmarks</code>.</td><td>Used for internal AcitveViam tests</td></tr><tr><td><code>ReferenceRegressionMSSQLTestIT</code></td><td>Check results of queries against a Snowflake database compared with results in the folder <code>src/test/resources/test-bookmarks</code>.</td><td>Used for internal AcitveViam tests</td></tr><tr><td><code>ReferenceRegressionTestCombinedScalarIT</code></td><td>Check results of queries against in-memory data in the combined cube with scalar sensitivities compared with results in the folder <code>src/test/resources/test-bookmarks-combined</code>.</td><td /></tr><tr><td><code>ReferenceRegressionTestDashboardsIT</code></td><td>Check results of queries against in-memory data compared with results in the folder <code>src/test/resources/test-dashboards</code> containing the MDX queries executed in the dashboards delivered with the application.</td><td /></tr><tr><td><code>ReferenceRegressionTestDepthIT</code></td><td>Check results of queries against in-memory data to check the configuration of the depth of parent/child hierarchies compared with results in the folder <code>src/test/resources/test-depth</code>.</td><td>Used for internal ActiveViam tests</td></tr><tr><td><code>ReferenceRegressionTestProductControlIT</code></td><td>Check results of queries against in-memory data for product control compared with results in the folder <code>src/test/resources/test-bookmarks-product-control</code>.</td><td /></tr><tr><td><code>ReferenceRegressionTestScalarIT</code></td><td>Check results of queries against in-memory data with scalar sensitivities compared with results in the folder <code>src/test/resources/test-bookmarks</code>.</td><td /></tr></tbody></table>

For most of the use-cases you want to test, you will need to use the `ReferenceRegressionTestScalarIT` class.
Run the class `com.activeviam.mr.regression.ReferenceRegressionTestScalarIT` as a
Java application - This will start up an Atoti Server instance, execute
the queries in */src/test/resources/test-bookmarks* and store the
results in files ending with *.csv*.

#### Executing Bookmark (MDX) Tests

Run the class `com.activeviam.mr.regression.ReferenceRegressionTestScalarIT` (or any of the other classes mentioned in the previous section if needed) as a
JUnit test - This will start up an Atoti Server instance, execute the
queries in the files ending with .*query* and assert the results against
the corresponding file ending with .*csv*.

### Custom Integration Tests

Integration tests can be defined fully in code, this includes things
such as sample data being injected into the Atoti Server instance, the
query being executed together with the expected values.

There are a number of sample integration tests in the reference
implementation that have been defined as examples.

Example implementations of this class can be found in the reference
implementation.

## Unit Tests

By default, unit tests are executed when you run `mvn install`. Some
example tests can be found in the `mr-application-tests` module, where
datastores have been created and mocked in order to test certain
functionalities.

### Sensitivity module measure testing

The sensitivity module provides a base class for unit tests, called `SensitivityMeasureTestBase`. Extending this class allows a unit test to wire all
non-replaceable beans and beans that can be replaced via qualified `@Primary` custom beans. A `CubeTester` object is provided within the class, directly
accessible in any extending class.

A test extending this class will only require store, reference, measure chain, and dimension configuration to be imported, alongside any beans required by the
calculations. Data shall be provided as a separate `Spring Bean`, and individual `@Test` methods can run queries against the provided `tester` object.

A sample test using this configuration is provided. The following is the test class definition:

```java theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
@SpringJUnitConfig(classes = {
        // Datastores
        SpotMarketDataRetrievalConfig.class,
        CurveMarketDataRetrievalConfig.class,
        MarketDataRetrievalContainerServiceConfig.class,
        CorporateActionMarketDataRetrievalConfig.class,
        AllMarketDataInterpolationConfig.class,
        FxRateMarketDataRetrievalConfig.class,
        MarketDataSetStoreConfig.class,
        TradeSensitivitiesStoreConfig.class,
        SensiLaddersStoreConfig.class,
        CorporateActionStoreConfig.class,
        DynamicTenorsStoreConfig.class,

        // Dimensions
        DateDimensionConfig.class,
        MarketDataDimensionConfig.class,
        RiskDimensionConfig.class,
        DynamicBucketingDimensionConfig.class,
        CurrencyDimensionConfig.class,
        SensitivitiesDimensionConfig.class,
        BookingDimensionConfig.class,

        // Measure parameters
        BaseParametersConfig.class,
        DeltaParametersConfig.class,

        // Measure chains
        BaseSensitivityChain.class,
        BasePnLExplainChain.class,
        DeltaNativeCurrencyChain.class,
        DeltaLadderExpansionChain.class,
        DeltaCurrentDateMarketDataChain.class,
        DeltaPreviousDateMarketDataChain.class,
        DeltaNextDateMarketDataChain.class,
        DeltaPnLExplainChain.class,

        // Formulas
        PnLExplainFormulaProviderConfig.class,
        TaylorVarFormulaProviderConfig.class,

        // FX post-processor translator
        RiskFactorFXPairTranslatorConfig.class,

        // Data
        DeltaPnLExplainScalarPostProcessorTest.TestConfig.class
})
@TestPropertySource(properties = {
        SensiRuleProperties.PREFIX + ".delta.pnl-explain.csr-non-sec.ladder-formula=DerivativeRelative"
})
class DeltaPnLExplainScalarPostProcessorTest extends SensitivityMeasureTestBase {
```

Several stores, all references, and most measure chains available in the application are excluded from this configuration, providing a minimal cube configuration
that lets you calculate Delta PnL Explain values.
Some of the imported dimensions contain levels or hierarchies that would be impossible to create without additional stores being imported, however, the base
configuration uses a `DimensionFilter` object to ignore unbuildable dimensions.

In this particular example, a PnL Explain formula property is set to a given value for the tests.

Data needs to be added to all stores impacting the tested calculations, using the `SimpleTransactionBuilder` object. To couple the data with the test using it,
we recommend static inner classes:

```java theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
    public static class TestConfig {
    @Bean
    public ITransactionsBuilder data() {
        return SimpleTransactionBuilder.start()
                .inStore("yourStoreName")
                .add(tuple, with, all, correct, values)
                .inStore("aDifferentStore")
                .add(different, tuple)
                .end();
    }
}
```

All store additions defined in this test will be applied to the stores imported in the configuration. Other replacement beans can be provided within the static
inner class.

Queries can then be run using the CubeTester API through the `tester` object:

```java theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
@Test
void testDeltaLadderPnLExplain() {
    tester
            .mdxQuery("SELECT NON EMPTY { [Measures].[Delta PnL Explain] } ON COLUMNS, NON EMPTY [Risk].[Risk Factors].[RiskFactor].Members ON ROWS FROM ( SELECT [Risk].[Risk Factors].[ALL].[AllMember].[BRL.OIS_Implied yield] ON COLUMNS FROM [Sensitivity Cube])WHERE [Dates].[Date].[AsOfDate].[2018-09-20]")
            .getTester()
            .hasOnlyOneCell()
            .containingFormattedValue("109,250.00");
}
```
