As an indie hacker and iOS developer, I think it is important to ship an app/product and accompanying features quickly to the market. However, this may come at the cost of future refactoring and accumulation of bugs.
It may also come at the cost of not writing unit tests to solidify your own faith in the code you write, keeping in mind code changes in the future. Here I believe a trade-off exists between sinking time into writing units tests for your code versus focusing that time on new features, bug fixes and marketing for your product.
Personally I write code for the core functionality of my code base, as features might fall away or appear quickly when iterating through ideas to try in a product.
I would love to hear your feedback on the test coverage for your products keeping in mind that the consumer only sees features, bug fixes and surface-level changes to the app.
When it comes to personal projects I generally write tests only for code/features I do not yet fully know how to implement. The test runner offers a handy execution env without needing to code a UI. Also, I tend to write integration tests when connecting to 3rd party services. Also to have some actual execution against your code and verify the integration. Generally, this leads to about 30-40% coverage, which includes the hard bit by default. That's my sweet spot for personal projects.
WARNING: if someone is paying you to code, write the freakin' tests, and DO NOT follow my initial advice.
WARNING 2: if you or your team is tasked with long-term dev on the system, also write the freakin' tests! :-)
Ha ha thanks for the input @fluxmatix.
"Eat your veggies and write your tests".
Many people think that writing tests will make you go slower. But that's simply not true. Yeah, you can ship something faster if not a single test is written, but that initial speed will eventually (in a few weeks) be blocked by the technical debt left behind. And getting up to speed again will be painfully slow and expensive.
On the other hand, writing tests for absolutely everything is not practical, specially for a bootstrapped company or indie hacker with limited resources. So the key is to know what to test and at what stage. Some rules I follow to decide if I need to write tests:
1) Critical functionality. Core, high-usage parts or the ones that would cause a big disruption of the users workflow if broken.
2) Complex parts. If certain functionality was difficult to write today, it'll be at least 5 times harder to fix if broken in a few months. Multiply that by at least 3 if it's a different person that has to fix it.
3) Time sensitivity. How long can the user wait for a resolution if broken? If your "Reports" page is not loading, no big deal. Worst case scenario, your user can live without reports for a few days. Other parts cannot wait because users interact with them frequently.
4) Major / Critical bugs. You fixed it, now you write a regression test to make sure it doesn't happen again. Not the trivial ones, but the ones that impact the system in a bad way.
As you get more resources and the product matures, you can slowly increase your test coverage as you augment the different parts of the system.
@typologist I think you hit the nail of the head with this comment. Awesome stuff. I agree that overtime writing test does speed up development. It is the same as writing great code. In the beginning, it may be slow but after the fundamentals and architecture are laid out, things speed up. Having to not to go back and refactor again and again is also a factor to consider.
I’d say write rather E2E tests. That makes sure the user gets what you announce on your landing page. Plus when it’s Running with your CI you make sure you didn’t break a function while developing a new feature
IMO tests are an investment in your product.
I can't count the number of times an obscure unit test written 6+ months ago has saved me from deploying a complex bug.
Definitely not, only for complex/ critical parts where a test is actually appropriate. I know a lot of devs who get bent out of shape about testing every little thing because "it's the right thing to do", but I don't buy it.
I think basic smoke tests (one for each page that ensures the page will render) are enough for most situations.
The term technical debt implies to me you can avoid paying for it up front out of cashflow/time/money (writing tests), or pay for it later at an interest rate (pile on more debt). If the trade off to writing unit tests are slower initial development with the goal of avoiding long term technical debt, then you have to figure out the appropriate balance of rapid development VS stable product for your product. For pre-product/market fit, I think incurring technical debt you may never have to pay off if your product fails makes sense. The trick would be if your product is successful, balancing whether you'll need massive refactoring later or an entire rewrite (technical debt default).
Here is another perspective.
Although there is some ambiguity around test categories, unit testing usually means testing the smallest possible units of code, and directly testing the code itself.
I rather not do that, because it is easy to fall into the trap of testing the implementation details when writing unit tests. You should not care how your app works. You should care that it works, from a user's perspective. Especially at the early stage. Let's unwrap that.
By not testing the "how", I mean that you should not test if calling the
create_the_product()function executes aINSERT INTO products ...query to your database. That's called testing an implementation detail.What's 100x better -in my experience- is this:
POST /productswith the expected input.GET /products.POST /productswith wrong input.GET /products.Write tests as if you were a user, and assert what you expect the app to do. Your users don't care what SQL you execute, or which cache mechanisms you use. So shouldn't your tests.
Test the core features first. Don't forget to write some integration tests as well to test a module as a whole.
Do you feel yourself loosing control over your codebase? Are you scared to introduce changes? Do you feel that your app is a house of cards that can fall apart any second?
Write tests.
Are you cofident that your application works well (in general)? Do you see only small bugs appearing? Do you know what is going on in the whole codebase and it's easy to manage?
Don't write tests.
It's more the fact that I have to switch to other work and can only approach the code base again after a certain amount of time. Here I do believe that units test also help in keeping some logic quality.
When I'm being too lazy to write tests for everything, I follow one simple rule:
If I broke something in production, I absolutely must write a test to simulate the issue, fix the issue and effectively ensure I never have to waste my time fixing it again.
On the "oh crap" stuff, yes. Things like making sure you don't charge someone the wrong thing or incorrectly write some complex data to the database.
I like DHH's take on this (paraphrasing): just write tests for the stuff that you're not certain will work as you expect every single time. Or, refactor that stuff if you think you can get it close to that point.
It depends what kind of your product. One of reason for unit test is prevent unexpected error made by others who didn't know the code he wrote will make error on another place wrote by another person. If you develop everything by yourself, you will know what's will be happened.
In fact, the most of error occurred while developing an app is about UI and logical mistake. The unit test can not 100% guarantee for that. You still need to use and try every features of your app to made it perfect.
I agree with a case by case senario.
Testing costs time and never guarantees that everything works. I was red a good article (can't find it) but the gist was: I rather have good monitoring then good testing. And I agree with that.
Yes, here I think that backend development versus frontend development (iOS development) may differ, in terms of testing. I think backends should often have more test coverage. I also agree with your point, a team and multiple developers may require more tests than individual developers that have had full knowledge of the codebase.
Well I do E2E tests in iOS, if the app breaks it can be something inside the app or the backend.
Because I have a distributed environment it is hard to test the whole platform and you would need something like kind for k8 and run the whole cluster. But that would be overkill for now!
I am pretty much doing it like you, for my project I didn't want to waste time writing tests and wanted to get the product out there as quickly as possible. As a result I broke some stuff several times...
I once broke the very home page, and I was seeing several new user sign up and then hit the error, to never come back again.
Now that the product is out I take time to write extensive tests, especially for core features that I really don't want to break. If I were to do it again, I would probably write a minimum amount of unit tests to avoid breaking stuff very early in the product's life.
Yes, hindsight is always the best. I always envision doing some test-driven development, as I want to iterate my product over a long period, but it often doesn't work out that way. I agree on core features and functionality for tests.
This comment was deleted 6 years ago.