So, what is the purpose of unit tests?
So, what is the purpose of unit tests?
1. When writing tests before the code, the tests can help you wrap your head around what the code should and should not do.
2. Forces distinct functionality/algorithms to be broken out into their own functions for easier testing.
3. Forces algorithms to be broken away from other, less testable, code (ie, read from data base, algorithm, write to database... the piece in the middle there should be in it's own function for testing)
4. When refactoring, gives (more) confidence that the changes being made aren't breaking anything. The corollary to this is it makes refactoring more common because you can feel braver about doing so.
5. Proves the code is doing what you say it's doing (with the tests). Note that this doesn't mean the code is right, just that it isn't wrong in the ways you're testing. Learning to write tests with good coverage and how to partition input data for that is a skill learned by experience.
6. Documents exactly what the code does for someone that comes along later. For much code, this can be determined by looking at the code... but in many cases the tests can say it cleaner.
7. Documents what the code DOESN'T do, and this is an important one that can't really be understood by just looking at the code. If the tests don't say the code does something, it could change later. If the tests only exercise negative number inputs but the code happens to do something useful with positive numbers... user's shouldn't rely on the positive number behavior.
8. Confirm that, when a bug is found, the fix actually fixes it. When finding a bug... a) find a way to reproduce is, b) write a test that does so and fails, c) fix the code and see the test pass... d) the bug never returns without being caught by the test.
* I'm of a functional persuasion, I like to think about types before code, I already tend break things up into testable components (also known as pure functions). What benefits might I find by adopting TDD?
* I understand the there are different benefits to be had from the act of writing tests and the artefact that is produced (ie the test suite). Do you the expect the tests that you write find bugs immediately? Or does the artefact only help to document code/detect regressions?
It also makes sure that if code changes, it's still functioning correctly. Aside from catching initial bugs, this is the biggest addition to maintainability of code.
I find unit tests to be incredibly liberating. Have you ever made changes to some parts of the code, but then worried you might have broken something? With unit tests, you can be confident that your change didn't break any expected behavior.
* To quote Dijkstra, "Testing shows the presence, not the absence of bugs", so presumably, you write tests to build confidence rather than to ensure "that what you think the code does is what it is actually doing". Is this accurate?
* If so, suppose you given a code-base that contains tests. How do you determine how much confidence to place in said software?
* It's very common for the space of possible inputs to be infinite, so you can't possibly test every case. How do you decide which ones are useful to write tests for?
* What is your response to Rich Hickey's depiction of, what he calls, guard-rail programming ("Simple Made Easy" from around 15:30 onwards)?
* Finally, how do know when you've written a good test suite? It's obviously good if it finds bugs, but how do you know that it is good without running it?
Sorry to bombard you, I'm asking because I'm genuinely interested and I want write more robust software.
> Have you ever made changes to some parts of the code, but then worried you might have broken something? With unit tests, you can be confident that your change didn't break any expected behavior.
I must say, I've done every permutation of changing code with/without tests where my changes have broken/have not broken things. Subjectively, I can't say that there has been noticeable correlation in any direction. Perhaps that's because I'm bad at writing tests, but then, how do I write good ones?
I think the real value of tests is exposing expected behavior to teammates, and then providing quick sanity checks against that expected behavior.
The biggest thing new developers miss about testing is that most times you're not writing tests for yourself, you're writing them as a courtesy to your teammates.
Learning to recognize potential edge cases and partition inputs to check as many input categories as possible is a skill learned through experience testing.