Testing. That word brings up 2 very different feelings for me. On one hand, when I open up a project with a nicely fleshed out test suite, I am very excited. I don’t have to wonder what works and what doesn’t! Fully green tests gives me a greater level of confidence that my fix isn’t going to bring the app crashing down when I push to production. What a great feeling!
On the other hand, the thought of writing quality tests, fills me with absolute dread. I feel like I can barely write quality production code! What makes me think that I can write quality tests that checks my code?! Deep Breath …Let’s talk about tests and what I’m learning.
I am currently apprenticing with Enok Collective and I love it. The company as a whole is a quality organization. My mentor and I identified some of the areas of my work that could use the most work and would give the most return. I chose testing as a skill that would give me the most benefits starting out. I’ve been in software for 2 years at this point, and testing has been a part of every job I’ve worked at. But 2 years in, I still get queasy about the idea of writing a test for my flimsy code (notice, I always write my tests after my code…[more on that later]). Enok strives for Test Driven Development (TDD) in all of the work that they do. TDD is just what it says it is: software development that starts with and is driven by testing. This means starting with testing. Starting with testing is a huge mind shift for me. Testing has always been a secondary priority. If I have time, I will throw in a single test and call it a day. With this being my mindset, my code has suffered and I am constantly concerned about the next feature that might break my fragile code and force me to rewrite it.
This past week I have started a deep dive into best practices of testing and I am attempting to elevate my tests to be “first-class citizens”. Here are the resources that I have taken advantage of:
Blogs and talks
There are so many great blogs and talks out there, but I thoroughly enjoyed these two:
This site allows you to practice coding exercises that are then tested to see if found the correct answer. I have taken the TDD approach to these exercises by first writing failing tests, and then making them pass.
This post is my way of solidifying my learning by forcing me to explain my experience.
What I’ve learned about tests so far:
- Types of tests
There are 3 standard types of tests: Unit, Integration, End-to-End. These vary in the amount of code that is being tested. Unit tests are small tests that check individual objects, methods, functions, or components. Unit tests should be small and ubiquitous. If a single unit test just keeps growing and growing, that might be a code-smell that your object/method/function might need to be refactored and split into multiples.
Integration tests are the next step. These tests ensure that the data is flowing properly between two modules. This should reveal any issues that may arise when you use multiple modules together with each other.
Finally, there’s End-to-End testing. e2e testing is meant to simulate a real user using your application. This provides some more visibility at a higher level by drawing in all of the code from start to finish, dependencies and all, and ensures that everything plays nicely together.
2. Red, Green, Refactor
Before any production code is written, a failing test should be written. This test sets the expectation for what the code should accomplish. After the test is written, the test is run, and you see the red failure, you can now start to write your production code. This code should turn the red test to green, meaning it should fulfill the test’s expectation and nothing else! Be sure to keep your code and tests small and simple. Finally, refactor your production code to ensure that the code is efficient and readable. And repeat!
3. Tests are imperative
Strong, wide-spread tests are the key to writing solid and robust code that can be changed and refactored without the fear of the codebase coming crashing down.
I have so much more to learn and implement in my daily work when it comes to testing and coding in general, but this week has taught me some great lessons and principles.