[erlang-questions] Looking for practical testing advice

Sölvi Páll Ásgeirsson solvip@REDACTED
Wed Mar 28 15:18:38 CEST 2018


Hi all

I'm wondering about various different approaches to writing testable
Erlang and I'd be super interested in hearing about how you approach
this.

As a concrete example, let's assume that we're building software that
talks to financial exchanges.
When submitting orders, you might need to map symbols to/from order
book ids, so you run a named gen_server that:

- Knows how to map an order book id to symbol (i.e., 1234 -> ERIC)
- Knows how to map symbol to id (ERIC -> 1234)
- Knows how to refresh it's map periodically from an external service,
such as a database or whatever

Then you want to test your protocol handler, which depends on this id
mapping server, but you don't want to make an expensive call to an
external service for every test you run, so you want to provide fake
data.

I see a few different possible approaches to orchestrate testing of
this, but I'm having a hard time figuring out which of these I should
follow in general:

1. You can start the protocol handler with a parameter, IdMapMod ::
module(), and implement a stub_idmap module that knows how to map
to/from certain ids to use in your tests.
The downside of this is that all calls from the protocol handler to
the id map must extract a dynamic module name from the state, and then
you lose dialyzer, xref, ...
Another downside(or upside?) is that you won't actually perform any
actual calls to your id mapping server.

2. You can start the id mapping server with a parameter,
ExternalServiceMod :: module(), and fake out the external service call
only.
Then your tests of the protocol handler would actually exercise the id
mapping server; but it's calls to an external service would be
answered with a fake stub.
This way you get the benefit of dialyzer + xref as your protocol
handler simply calls id_map:symbol_to_id/1 or whatever.

3. You can use a mocking library such as meck to do something very
similar to either of the two above things.
In past lives using other languages, I've generally developed a
distaste for mocking, as I've felt that it can create brittle tests.
Generally, I think I'd prefer to be able to test things in terms of
interfaces, but I might be swayed otherwise.

Is there anything else I'm missing?  How do you write testable Erlang?
 Is there a general approach you follow?

Thanks & regards
Sölvi Páll Á



More information about the erlang-questions mailing list