In this quick post, I hope to explain with some common math abstraction how I perceive Unit testing and Integration testing.
Disclaimer: This is post is only meant to provide the notions behind testing, is not meant to be an in-depth testing explanation 😛
Okay, you must be asking yourself, why? I mean, not all coding is created equal, and let's be honest - you don't really need to understand math to code. However, I do believe that - and this comes from someone who flunked calculus and algebra numerous times in college - math is fascinating and a great tool to explain concepts in a simple manner.
First of all - what is a function? 📦
A function is a process or a relation that associates each element x of a set X, the domain of the function, to a single element y of another set Y
I can't find a better definition than to look at it as a black box. A function is a black box that, when given a value, will return something else.
Reference: Wikipedia
Okay, cool - that's as much math as you need to know for what's next!
So here's the thing, we want to test functions. We want to make sure they return the correct value each time they're called. We have this first function f(x)
which returns the given number x
plus one. Then, we have g(x, y)
which does a bit more, it returns the sum of x
plus the result of f(y)
.
What's going on here? we have one function f(x)
that we can test by itself as it has no dependency on another function. This is what we can consider something that can be tested as a unit.
Then, there's another function g(x, y)
which implements f(x)
. It needs f(x)
to produce a value. It is directly dependant and therefore needs this other function to live. Nothing like a math love story. 💙
Coding the functions 💻
So in order to actually test this, we would have to, you know, code these functions. You can use your language of choice but as the JavaScript fan I am, I highly encourage you to use js 💛
So for both functions, we will end up having something like this:
Getting into the tests 🧪️
Now that we have coded our functions, we want to test this first function f(x)
and make sure that it returns the correct value for x = 1
We also want to test that g(x, y)
returns a correct value for x = 2 ; y = 1
I will be using Jest for these examples, if you still don't know about Jest, give it a shot, it's an amazing testing framework for js!
So for the following test suite We will be expecting that when we call these functions with the params described above, they should actually return what we expect.
One thing to highlight here is that by testing g(x, y)
we are implicitly testing f(x)
.
Mocking 🃏
Can we test g(x, y)
as a unit? Up until now we now that g(x, y)
depends on f(x)
, so its result will be bound to the result of f(x)
.
...or will it? 🤔
Mock is a very interesting concept when it comes to testing. For some controversial, for some a helpful tool. I am not here to discuss this, but rather give you the notion of what mocking is, and how we could use it to test g(x, y)
without any dependencies.
With mocking you can override, substitute, manage things that should be out of your control. In this example, because of how g(x, y)
is built, we should not be able to look inside our black box
and replace f(x)
with something else.
This is where mocking comes in. In an uncontrolled environment, it allows you to open up the black box
and substitute parts of how the system behaves to your will.
It would be the equivalent to doing something like this:
Now, because we have tampered with g(x, y)
's black box, it will produce a new output.
Compare that to the example above, in which we don't have access to the black box
These are not equal scenarios, hence why researching how to mock properly is something worth investing some time in!
So then - can we test g(x, y)
in isolation? as a unit?
Yes! - Jest offers a lot of functionality for mocking
⚠️ Should you test g(x, y)
in isolation?
It depends - are you testing edge cases? is f(x)
an external dependency out of your control? There are a lot of things to keep in mind before mocking.
So that's it! A basic introduction to testing explained with math functions.
Hope you liked this post - keep hacking! 🔥
Top comments (3)
In FP hard-coded dependencies are avoided most of the time, because we can easily pass the dependency as a function argument, which converts the function into a higher order one. Additionally, HOFs are more general than first order functions.
You're totally right! I think FP is quite a broad subject in itself and when it comes to testing it makes it very easy not having to mock dependencies. For people wondering, it might end up looking a bit like this:
Thanks for your feedback! 💙
Hello,
could you describe the relationship between a boolean function in math and the user acceptance testing(UAT) as well? e.x. i use an automatic framework (Robot framework) for system and UAT testing of WebPages or XML files. i have keywords (functions) like click element, Input Text, Wait until page contains Element, etc for web page testing. how can i associate it correctly with Math functions?
Thanks