DEV Community

Cover image for Writing Good Unit Tests: A Step By Step Tutorial

Writing Good Unit Tests: A Step By Step Tutorial

Elena on November 21, 2018

This post was originally published in my blog smartpuffin.com. Let's imagine we just wrote a method calculating distance between two points on ...
Collapse
 
setagana profile image
setagana

Nice post, thanks Elena! Another tactic I like to use when creating unit tests is to scan my code for control flow statements and try think of the possible cases that can come from those. A great example of this is languages that allow you to fall through switch statements, where small code changes can lead to big headaches if they're not thought through.

Collapse
 
ice_lenor profile image
Elena

Thank you!
I absolutely agree with reading the code and looking for tricky places. I mentioned it in the "What's inside" section.
The switch falling-through is a really good example!

Collapse
 
drhyde profile image
David Cantrell

If you're doing Test Driven Development I'd expect to also see tests for short and long distances. That would demonstrate that your first test (the short one) was for a distance you measured with a ruler, then the second was added when you ran your code for two points a long distance apart, got the wrong result, and switched to an algorithm that knows we're not living on a plane.

Collapse
 
ice_lenor profile image
Elena

I'm not sure I understand the argument about the plane. The distance calculated as if the coordinates are on a plane will never match the distance on the globe.

However, I do agree there should be tests for short and long distances! I mention them in the "Corner cases" section:

How about max distance on the planet?
How about a really small distance?
If both points are absolutely the same, are we getting 0 m distance?

Collapse
 
drhyde profile image
David Cantrell

The deviation from a plane is about 20cm per km, or one part in 5000. So provided that you're measuring between two points less than 5m apart (a few millionths of a degree apart) the distances do match, to within 1mm.

Incidentally, people may find this link interesting: ianvisits.co.uk/blog/2018/03/06/ho...

Thread Thread
 
ice_lenor profile image
Elena

No, this is not the case. Here's a simple proof.

Say, we have two points on the equator.
Point 1: latitude 0, longitude 0.
Point 2: latitude 0, longitude 1.

Distance between them, measured as if they were flat coordinates: 1. (Units: degrees.)

Distance between them, measured as if they're on the planet Earth: 111.19 km.

111 (km) != 1 (degree).

Moreover, measuring distance in degrees doesn't make sense because one degree longitude is not equal to one degree latitude; and one degree longitude means different number of kilometres depending on latitude. The closer to the pole you go, the less kilometres "fit" in 1 degree longitude. (Note to self: I need to write an article about that and add pictures. It would be easier to explain with pictures.)


I suspect that you might be talking about specific projections, such as UTM, where for certain subset of coordinates distances between them, measured using the Pythagorean theorem, will roughly match the real on-the-planet-surface distance.

But if you're using such projection, your points' coordinates are also specified in that projection, and not in latitudes and longitudes.

To compare the distances, you'd have to first convert your point latitude and longitude to the coordinate system coordinates and then perform the calculation according to the Pythagorean formula. That's possible, but it complicates tests too much.

 
ice_lenor profile image
Elena

Thank you for the example. This seems like a great "casting net" for all sorts of general bugs and problems.

Still, I'd add some manually-written tests on top of these. I wouldn't rely on randomised tests more than I would rely on my domain knowledge. For example, a set of randomised tests wouldn't be able to "tell" you about problems you might experience around 180th meridian or around poles. They don't know the reason behind these problems. A human, on the other hand, is able to (re)read the requirements, think critically and figure out all sorts of problems using a creative systematic approach.

Collapse
 
casperns profile image
Zelimir Stefanovic

Good post and notes. Also, I like always to use naming standards: test+methodName+situation

Collapse
 
ice_lenor profile image
Elena

Oh nice! Yes, I too believe that the name should be long and descriptive.

I wrote about more "mundane" things, such as naming or placing tests, in here:
dev.to/ice_lenor/unit-testing-best...

Collapse
 
jafuentest profile image
Juan A. Fuentest Torcat

Thank you. This is pure gold <3

Collapse
 
ice_lenor profile image
Elena

I am struggling a bit to apply property-based testing in this case. Can you give me an example, please?

Collapse
 
pjmantoss profile image
PJ Mantoss

Nice. Even though I didn't understand much due to my zero knowledge in Java.
Please, could you make another tutorial on Unit Testing react components (like a SignIn/SignUp form) using jest? Thank you