Skip to main content

Unit testing, explained

Published 2021/04/27 15:30

You’ve heard about it, heard people talk about it, people swear by it. But what is it?

Let's explain…

Let's say you're building an app. An app that needs to know whether a number is even or odd.

The function is quite straightforward for whole numbers:

function oddOrEven(number){
    if (number % 2 == 0){
        return "EVEN"
    }
    else {
        return "ODD"
    }

Now how do you test to see if this works as it should? If you’re like most programmers, you open a console and call the function:

oddOrEven(44)
>> EVEN
oddOrEven(85)
>> ODD

Great! Seems to work fine!

Now there’s a problem with the function. What if the number input is not a whole number? Something like 4.2? In mathematics, decimal numbers are neither even or odd but if we try our function:

oddOrEven(4.2)
>> ODD

That’s not right!

So we add a special case for decimal numbers:

function oddOrEven(number){
    if(number % 1 !== 0){
        return "NONE"
    }
    else if (number % 2 == 0){
        return "EVEN"
    }
    else {
        return "ODD"
    }
}

Again, we do a quick test in our console to check if it's correct:

oddOrEven(4.2)
>> NONE

Excellent!

Now to make sure we haven't broken anything since our last change, we check the function against a whole number again:

oddOrEven(12)
>> EVEN

oddOrEven(501)
>> ODD

Great! Still works!

Now what if the function gets given something other than a number? Say, a string? You need to extend your function so it throws an error if this happens:

function oddOrEven(number){
    if(isNaN(number)){
        throw "Input must be a number"
    }
    if(number % 1 !== 0){
        return “NONE”
    }
    else if (number % 2 == 0){
        return “EVEN”
    }
    else {
        return “ODD”
    }
}

You test and it works fine. Now you need to test your function for all other conditions to make sure nothing is broken:

  • when you give it an odd number

  • when you give it an even number

  • when you give it a decimal

  • when you give it a string

As you may have noticed, the list of checks you need to do for every small change is getting bigger and bigger.

This is when you need something that can automate this for your whole app, which can run several tests with a single command.

🧪 UNIT TESTS do exactly that! 🧪

All languages have what we call "unit testing frameworks". Tools that run tests like the ones I mentioned with a single command.

All you need is to install the tool, write your tests in "test files" and that’s it! Every time you run the appropriate command, all tests are run!

What are these tools called? That would depend on the programming language used. Here are some examples:

  • Javascript: Mocha, Jasmine, Jest

  • Python: PyTest, testing

  • Java: JUnit

  • R: testThat

For details on how to use each one, check the documentation for the language you’re using.

For example this is a test in Jest (Javascript testing framework), which checks if evenOrOdd returns "EVEN" when an even number is given:

test("evenOrOdd returns EVEN when even number is given", () => {
    var result = evenOrOdd(66)
    expect(result).toBe("EVEN")
})

You can run this test plus any other test you write the same way, with the jest command in your console!

With unit testing, your app is more likely to be bug free, because of better, more thorough testing.

🧪 Better testing means

👩‍💻 happier developers,

💻 better apps,

😃 happier users!

Enjoy writing better apps!

Dev, Explained (43 part series)

  1. Javascript Scopes, explained.
  2. Javascript Promises, explained.
  3. Accessibility, explained.
  4. React, explained
  5. Should I use forEach() or map()?
  6. Should I use Flexbox or CSS Grid?
  7. Docker, explained.
  8. Unit testing, explained
  9. Git, explained.
  10. Typescript, explained.
  11. async/await, explained.
  12. The DOM, explained.
  13. Regular expressions, explained
  14. GraphQL, explained.
  15. Vue, explained.
  16. Svelte, explained.
  17. API, explained.
  18. Javascript Hoisting, explained.
  19. Immediately Invoked Function Expressions (IIFE), explained.
  20. ARIA roles, explained.
  21. Test-driven Development, explained.
  22. ARIA live regions, explained.
  23. aria-label in accessibility, explained.
  24. Type coercion in Javascript, explained.
  25. Variables, explained.
  26. if statements, explained.
  27. Arrays, explained.
  28. Currying in Javascript, explained.
  29. Memoization, explained.
  30. For loops, explained.
  31. Javascript Prototypes, explained.
  32. React Hooks, explained.
  33. Graph databases, explained.
  34. MongoDB, explained.
  35. Serverless, explained.
  36. Javascript Callback functions, explained.
  37. HTML, explained.
  38. CSS, explained.
  39. Responsive design, explained.
  40. Javascript, explained.
  41. The CSS Box Model, explained.
  42. CSS Flexbox, explained.
  43. CSS Grid, explained.
2022 Savvas Stephanides
Buy me a coffee
Some icons from Freepik