The purpose of this document is to augment on the existing Testing Strategy Document (Testing Strategy ). This contains some details and guidelines on the types of tests that we will perform especially in the context of IAM. These details were based on the testing workshop and existing documentations. 

The primary objective of employing these types of tests is for these tests to be complementary and avoid test duplication and over-testing. This would result to faster development and execution of tests.

I. Unit Test

A type of testing where an individual unit is being tested in isolation. In most of our cases, the unit we test here is our class/object. Testing in isolation means that we mock any external dependencies of the class in test. 

When to use and why? 

Utility/Helper classes since these are stateless and most don’t have external dependencies.

How?

  • Do not annotate with @MicronautTest since it does not need a full-pledged Micronaut application/environment. No annotation on the class level and just put @Test annotations on the test methods.

  • If there are any dependencies, manually mock them.

Examples

  • ph.safibank.common.utils.TemplateLibraryTest

  • ph.safibank.cardaggregator.util.HttpUtilsImplTest

In the Context of IAM

Custom utility classes are pretty common in IAM since there are numerous repeated codes for hash/key generation, key verification, generating signatures, etc. Tests for these utility classes should be in the form of unit tests.

II. Component Test

Somewhat similar to unit test in terms of testing the functionalities of the unit in test but the dependencies are not mocked except for those that are complex to set up and those that have no business logic. 

External dependencies like database and Kafka (for some cases like Kafka In-Out Testing) should be spun up using TestContainers that can mirror the real objects.

When to use and why?

Recommended to use for the following:

a. Repository Tests

A good use case for component tests since repository classes have database as a dependency. Running the database in a container provides an easy, reliable and fast way compared to creating a mock or using an actual one.

b. Service Tests

Services usually depend on repository classes. Instead of mocking these repository classes, we can just use the actual repository objects which in turn uses the a test db instance using TestContainers similar in Repository Tests.

How?

Annotate class under test with @MicronautTest and use TestContainers for the dependencies like database and Kafka.

Examples

  • ph/safibank/accountmanager/repository/AccountRepositoryTest.kt

  • ph/safibank/accountmanager/service/AccountServiceTest.kt

III. Integration Test

In this type of test, the dependencies of the class under test are using the actual objects and environments (database, queue, 3rd-party APIs, etc.)

When to use and why?

This is recommended to use for the following:
A. Gateway / Adapter Tests

  • Since it’ll be easier and faster to use the actual environment instead of mocking every possible scenario

B. Controller Tests (To be confirmed and needs clarification)

  • Authentication is being handled on this layer so it’s better to just test controllers via integration tests.

How?

TODO:

Examples

  • ph.safibank.advanceaigateway.controller.OCRControllerIntegrationTest

  • ph.safibank.loanmanager.overdraft.OverDraftPeriodChange

IV. Kafka Tests

A. Kafka In-Out Test

This is a component test that involves the use of Kafka using TestContainers. This is recommended to use if you both control the producers and consumers of the Kafka topic in your test. 

B. Consumers/Listeners Are Controlled (To confirm)

TODO

C. Producers Are Controlled

TODO

Action Items/Questions:

  1. Discuss and agree on the metrics for the tests. How do we guarantee that we have acceptable test code coverage for the whole service?