Learning Test - How to test adapters with behaviour?
Tags: programming, testing
Published: 2024-01-02 14:21:35

"Learning Tests" is a kind of "Characterization Test" for third-party API.

---

## My learning journey

I had a dilemma:

I need to be confident about the logic of a database “Adapter”, with test, but this kind of test are slow. There are not “plumbing test” as they test a behaviour. And this behaviour is a behaviour of a third-party API.

### And I had many questions

- How to name the test suite that holds “Adapter” behaviour?
- How to keep “Unit Test” ran very fast?
- How to keep “Integration Test” focus on plumbing, without behaviour?
- How to keep a sense between test suites?

### I read some

1. I read again the part talked about
  - “Learning Test” on chapter 8. Boundaries on “Clean Code” book wrote by Robert C. Martin
  - “Integration Test” on chapter 8. Testing Strategies on “The Clean Code” book wrote by Robert C. Martin
  - “Humble Objects” on chapter 4. Test Design on “Clean Craftsmanship” book wrote by Robert C. Martin
4. https://www.google.com/search?q=Jim+Newkirk+learning+test
5. https://martinfowler.com/articles/practical-test-pyramid.html
6. https://martinfowler.com/bliki/IntegrationTest.html
7. https://martinfowler.com/bliki/ContractTest.html
8. https://testing.googleblog.com/2010/12/test-sizes.html?m=1
9. https://martinfowler.com/bliki/SelfInitializingFake.html

## The result of my learning

The technic I built need to be experimented on real life code base. It is not something that can be done on a "Kata".

### What is the technic?

We want that a detected behaviour change on the third party API force us to propagate this changes to all dependent code. In other words, the "Unit Test" suite must fail.

Steps:

1. Make "Learning Tests" to characterize the behaviour of a third party API, as we expect to use it in our application.
2. Make "Fake" to implements behaviour of "Learning Tests"
This "Fake" is a kind of cache for behaviour.
3. On the "Adapter" "Unit Test" inject the "Fake"
4. Execute "Learning Tests" periodically to check the "Fake" validity.

### How to make a "Learning Test"?

We’re essentially doing controlled experiments that check our understanding of that API.

It is common to experiment to learn about a library by:

- reading the documentation examples
- checkout the code and execute in the console using debug tools.

This kind of things should be done on controlled environment. And each learning are saved inside a test case that characterize one behaviour.

### When to use this technic?

- The "Adapter" have a bit of behaviour
We want that our "Adapter" to be an "Humble Object", it is too simple to bother testing.
For example, when the "Adapter" need to transform third party API response.
- When the third party API is stateful, two different responses for the same request.

### In practice

One kind of "Fake" for a database like service have many versions.

Why?

Ours applications should be resilient to failure.
The "Adapter" layer is subject to failure.

- The database may be unavailable => `OutageFakeDatabase`
- Access may be denied => `AccessDeniedFakeDatabase`

## Glossary

- "Learning Tests" - look at the @taylorsilva's [post](https://dev.to/taylorsilva/learning-tests-11fe).
  He did a nice in practice example.
- "Characterization Test"
- “Adapter”
- “plumbing test”
- “Unit Test”
- “Integration Test”
- “Humble Objects”
- "Fake"