Honestly, I'm embarrassed to write this one out. I've always known that testing was necessary, but I dread writing tests. So I didn't. Most of the stuff I built was for me and unlikely to be used by others. And it was always okay.
This philosophy has been my mentality for a long time. I started learning Laravel almost seven years ago, coasting by because I wasn't building anything the public would use.
Most of what I developed as one of two things:
Just for fun. Keep up my skills, and learn something new.
For my business, I will likely only use it.
I never really saw the point of spending extra time testing for #1. If no one will ever use what I'm making, why not just enjoy building what I am building?
I saw the point of testing for #2, but building for my business isn't nearly as fun. I want to get these projects done. They are primarily small apps that serve a specific, singular purpose.
Two years ago, I ran a board game consignment at my business. Our registers don't have an easy way to keep track of this. So I built something that would.
In a nutshell, each customer gets a number. That number is attached to each consignment game with a price. During a sale for a consignment game, I enter that game into the app, and it keeps a log of customers' sales so I can pay them out at the end of the sale.
I have used this app for two separate consignment sales. The first one was a very rough but functional app. The errors confused my employees, so I kept track of everything myself and could fix errors as I went.
The second time, I spent a lot of time fixing the underlying code for the app. I made it easier to use, significantly more stable, and added many new features to help manage the sale. I also wrote tests for every part of the app. It was only 26 tests (for five livewire components), but I knew that the code was rock solid at that point. I knew that when my employees sat down to use the app, there wouldn't be confusion from errors.
The biggest lesson I learned was that tests are not that complicated to write past the initial learning curve.
I know what you're thinking; that's not TDD, right?
And the answer is no, but that made me feel confident in TDD.
I find myself regularly thinking, this might be a fun site to build. And to keep improving my skill, I generally try developing a simple app version.
Years ago, one of the first projects I tried to make was an app called Let's Read.
I figured I would try it in my new(ish) toolset a few weeks ago. I've been actively using the TALL stack + Pest + Jetstream, and I enjoy working with it.
I found that I could reliably build out many of the features I struggled with the first time, and I was confident that those features worked because I wrote tests for every new thing I added.
The moment where TDD clicked for me was when I was adding the next & previous buttons for story chapters. Testing in the browser worked fine. I didn't see any issues with the next button (or the previous, so I assumed)
The test for checking the correct URLs of the next button worked perfectly. When I went to build the test for the previous button, it failed. I told myself that it worked perfectly fine in the browser, so there wasn't a reason it shouldn't work in my test. But I needed that test to pass, so I started troubleshooting. I found out that while it did work properly in the browser, it was because of the specific number of chapters I had added to the database. The code didn't correctly reverse the order when finding the previous chapter.
With two chapters, this wasn't a problem at all. But my test relied on four chapters to check that everything worked properly. I thought when I wrote the code; it was overkill. But it's better safe than sorry. But I was wrong. It proved that over-testing is always far better than under-testing.
The story above taught me the most valuable lesson. I will likely never start another project, no matter how large or small, without testing as I go. The confidence I gained from knowing that the next and previous buttons were working drilled this concept into me.
Part 1: Test Driven Development (TDD)