DEV Community

loading...

What Makes a Good Test?

Aniket Kadam
An android dev with ~8 years of experience. I consult and may join fulltime for the right company.
・2 min read

You write your code, run it to go have a peek if it does what it expected, what if you wrote a test for that? The few seconds you spent checking it are now possible to do in milliseconds and available to anyone without even looking at your code! Who wouldn't want that!

Once you're a few tests deep, you might run into a problem.
As your functionality evolves, you find that you have to constantly keep re-writing your earlier tests.
Suddenly, the weight of older tests is slowing you down! 😱

Could we have avoided this?
Pretty simply actually! There's just one element of discipline you need to add.

Start by asking what you care about?

  1. For a certain input, you expect a certain output. Which means, given a public function on your presenter/viewmodel, test only that the public effects it's supposed to have, happen.
  2. If it's only result is something in your repository, then you could verify that too.

As long as you test only your presenter/viewmodel, not the functions within, you're keeping your tests at the boundaries, you're free to change your internal implementation as you like.

Keep tests to the outermost layers of your architecture isn't something new, it's a part of Clean Architecture, where the author recommends that tests wrap around the outside of your app and know nothing about the inside.

There are two exceptions (that I know of) to this,

  1. If the test was for some module that, if modified, can be thrown away entirely along with its tests. For example if you're using the Room database and want to test its migrations, go ahead! If you decide to switch away from Room for Realm or such, you can throw away those tests entirely and still don't need to rewrite.
  2. If you're using UseCases, it's practical to have tests that check out some internals of those, again throwing them away if the usecase is no longer needed. In this case, you're at the boundary of one entire unit of functionality.

Happy testing! Please ask questions if something isn't clear!
If you'd like an Android example of this, take a look at my app

Discussion (0)