I'm frankly still struggling to grasp how to implement tests/TDD effectively in a large, real-world application.
(More specifically, I have trouble with the idea of unit tests; functional tests fit my thinking and understanding better).
I've had a taste of how useful it can be in small side projects, but when I look at the large-scale fintech loan pricing product I develop for a client, while I can INSTANTLY see the value in having a suite of tests that will guarantee adding a new variable doesn't break the pricing algorithm, I just can't picture how to build up the suite of tests around it.
I'm also still "catching up" on general thinking around pure functions and testable code, so I'm sure that's where a lot of the problem lies for me. Poorly written code will never be effectively testable.
So all of that said, I'm working hard towards learning and using TDD.
P.S. - Don't get "comfortable enough" with what you know and stop learning and keeping up with best practices and paradigms, especially not for years "while you focus on the business side." Playing catch up after 15 years in the industry is just. no. fun.
Software developer trying to bring order into his craft. I write about my journey, thoughts, and practices. Currently focused on web frontend with React.
I agree that in real-world applications, it's harder to do TDD. In my opinion, it's due to the increase in the complexity of the domain. So my strategy has been to break features down into degenerate cases that are simple enough for me to know how to write a test for them. After implementing the degenerative case, I then proceed to iterate into the next degenerate case that brings me closer to the full-fledged feature.
This example is a bit too simple, but if I have to develop a table that fetches data and has tons of sort options, my tests will probably go something like this "Shows loading while fetching" -> "Can show an error message when fetching data fails" -> "Show's message to the user if there's no data to show" -> "Can show one row" -> "Can show multiple rows" -> "Can filter rows by 'Property1' " -> "Can filter rows by 'Property2' " -> "Can filter rows by 'Property1' and 'Property2' " -> etc. Some tests might be redundant at the end of the implementation, and I'll probably delete them if that's the case. But going through this process gives me more confidence in what I'm doing and tend to lead to better tests and design.
Testability comes from good design and architecture, I agree.
But starting somewhere is really important. Maybe you can start with a high level test without edge cases like:
Given this input I expect this output. Add a few of them covering different code paths (delta coverage per test) and try to move forward.
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
I'm frankly still struggling to grasp how to implement tests/TDD effectively in a large, real-world application.
(More specifically, I have trouble with the idea of unit tests; functional tests fit my thinking and understanding better).
I've had a taste of how useful it can be in small side projects, but when I look at the large-scale fintech loan pricing product I develop for a client, while I can INSTANTLY see the value in having a suite of tests that will guarantee adding a new variable doesn't break the pricing algorithm, I just can't picture how to build up the suite of tests around it.
I'm also still "catching up" on general thinking around pure functions and testable code, so I'm sure that's where a lot of the problem lies for me. Poorly written code will never be effectively testable.
So all of that said, I'm working hard towards learning and using TDD.
P.S. - Don't get "comfortable enough" with what you know and stop learning and keeping up with best practices and paradigms, especially not for years "while you focus on the business side." Playing catch up after 15 years in the industry is just. no. fun.
I agree that in real-world applications, it's harder to do TDD. In my opinion, it's due to the increase in the complexity of the domain. So my strategy has been to break features down into degenerate cases that are simple enough for me to know how to write a test for them. After implementing the degenerative case, I then proceed to iterate into the next degenerate case that brings me closer to the full-fledged feature.
This example is a bit too simple, but if I have to develop a table that fetches data and has tons of sort options, my tests will probably go something like this "Shows loading while fetching" -> "Can show an error message when fetching data fails" -> "Show's message to the user if there's no data to show" -> "Can show one row" -> "Can show multiple rows" -> "Can filter rows by 'Property1' " -> "Can filter rows by 'Property2' " -> "Can filter rows by 'Property1' and 'Property2' " -> etc. Some tests might be redundant at the end of the implementation, and I'll probably delete them if that's the case. But going through this process gives me more confidence in what I'm doing and tend to lead to better tests and design.
Small steps help a lot.
Testability comes from good design and architecture, I agree.
But starting somewhere is really important. Maybe you can start with a high level test without edge cases like:
Given this input I expect this output. Add a few of them covering different code paths (delta coverage per test) and try to move forward.