When it comes to testing, the simplest explanation I have for tests is:
Users use our code through the web, console, and other user interfaces. Tests are another interface just for the developers.
Tests provide the developers confidence that things are working the way they should.
What does it mean to be red then green?
I always remember “red, green, then refactor” when I write a test.
An assertion (in the test) was made on the code’s behavior. It is failing on an assertion test.
Write the code to make that tests pass. Now you have something in a working state. Commit it!
Now that you know things are in a working and deliverable state, can you refactor your code?
Do you need to do this each time? No.
It helps me narrow down the scope of a test and have a criteria for when I am done with it.
Is your test testing just your test or your code?
Imagine this a situation while programming.
There is a test, some code was written, and everything is green. Someone comes back, edits some code, all the tests are still green.
This is great! Tests should have to change with a different implementation of code, just as long as the assertions of the behavior is the same.
When you comment out your code, your test should fail. Yet it is still passing. Why is that?
Sometimes our tests are just testing our tests, not our code. Ee might be testing a mock implementation of something.
Tests should fail when I comment out the code I believe to be testings. It may not be the tests I wrote, but something should break, so we know something changed.
How do you start writing tests?
When writing tests, I like to think of the happy path first, “If everything was working perfectly, what would I expect to happen?” Allowing you to write tests free from the distractions of errors and side effects. It can help with test setup the behavior you want the tests.
The next step is a sad path – errors, side effects, and other paths. For example, “If we cannot connect to the API, what should we do?” It helps test the branching (conditions) of your code.
Thinking about your tests in discrete chunks will help produce understandable tests. Tests are another means to document your code, similar to commenting.