5 ms·
TDD isn't concerned with how your program works. In fact, implementation details leaking into your tests can become quite problematic, including introducing the
by randomdata 4y ago
TDD isn't concerned with how your program works. In fact, implementation details leaking into your tests can become quite problematic, including introducing the problems you speak of. TDD is concerned with describing what your program should accomplish. If you don't know what you want to accomplish, what are you writing code for?
- giantrobot 4y agoThe issue is what you want to accomplish is often tightly coupled with how it is accomplished. In order to have a test for what it needs to contain the context of how. As a made up example. The "what" of the program is to take in a bunch of transactions and emit daily summaries. That's a straight forward "what". It however leaves tons of questions unanswered. Where does the data come from and in what format? Is it ASCII or Unicode? Do we control the source or is it from a third party? How do we want to emit the summaries? Printed to a text console? Saved to an Excel spreadsheet? What version of Excel? Serialized to XML or JSON? Do we have a spec for that serialized form? What precision do we need to calculate vs what we emit? So the real "what" is: take in transaction data encoded as UTF-8 from a third party provider which lives in log files on the file system without inline metadata then translate the weird date format with only minute precision and lacking an explicit time zone and summarize daily stats to four decimal places but round to two decimal places for reporting and emit the summaries as JSON with dates as ISO ordinal dates and values at two decimal places saved to an FTP server we don't control. While waiting for all that necessarily but often elided detail you can either start writing some code with unit test or wait and do no work until you get a fully fleshed out spec that can serve as the basis for writing tests. Most organizations want to start work even while the final specs of the work are being worked on.
- randomdata 4y ago> Most organizations want to start work even while the final specs of the work are being worked on. Is that significant? Your tests can start to answer these unanswered questions before you ever get around to writing implementation. Suppose you thought you wanted to write data in ASCII format. But then you write some test cases and realize that you actually need Unicode symbols. Now you know what your implementation needs to do. Testing is the spec. The exact purpose of testing, which in fairness doesn't have the greatest name, is to provide documentation around what the program does. That it is self-verifying is merely a nice side effect. There is no need for all the questions to be answered while writing the spec (a.k.a. tests). You learn about the answers as you write the documentation. The implementation then naturally follows.
- giantrobot 4y ago> But then you write some test cases and realize that you actually need Unicode symbols. Now you know what your implementation needs to do. If your customer decides they want/need ASCII your test is immaterial. The same is true for writing any tests before you've got a meaningful specification. You're just writing code to write code. At that stage it makes more sense to write a scaffold in the general shape of the task than a bunch of tests defining precise but made up requirements. Aspirational tests are great if you know exactly what you need to do. They tell you when you get there. If you don't know exactly what you need to do they're just wasted effort that get thrown away with nothing having been gained.
- randomdata 4y ago> If your customer decides they want/need ASCII your test is immaterial. Not at all. First, if your customer doesn't know upfront that ASCII is necessary, showing the customer how the program will work will help them realize that. The lesson gained from your test was useful in getting to get to that point. Second, your failed attempt at an interface that provides UTF-8 (or whatever) during exploration is convertible to a negative case that will fail if ASCII isn't used, documenting the customer's requirement for future developers. If the customer originally required UTF-8 and years later a changing landscape forced them to require ASCII instead, again your spec can be negated to help you ensure that you made the correct modifications to meet the new requirements. > Aspirational tests are great if you know exactly what you need to do. Whereas I would argue that TDD isn't all that useful if you know exactly what you need to do. In that case you can simple write the code along with unit/integration/acceptance tests that validate behaviour. TDD is about exploring the unknowns and answering questions – showing the customer how the program will function on the outside – before you waste time implementing all the internal details of a full program around UTF-8 only to be told when you demo it that the customer actually requires ASCII, potentially requiring massive rework. The latter is where you waste effort.
- wvenable 4y ago> If you don't know what you want to accomplish, what are you writing code for? Often times you write to find what you want to accomplish. It sounds backwards, perhaps it is backwards, but it's also very human. Without something to show the user, they often have no idea what they want. In fact, people are far better at telling you what's wrong with what's presented to them then enumerating everything they want ahead of time. TDD is great but also completely useless for sussing requirements out of users.
- randomdata 4y agoIt does not sound backwards at all. That is what TDD is for: To start writing the visible portions of your program to see how it works and adjust accordingly as user needs dictate. Once your program does what the user wants, all you have to do is backfill the "black box" implementation, using test cases created during the discovery phase to ensure that the "black box" provides what the user came to expect. The scenario you present is exactly what TDD was envisioned for. If you know the exact requirements upfront, you don't really need TDD. You can simply write the code to those requirements and, perhaps, add in some automated acceptance testing to help catch mistakes. TDD shines when you are unsure and exploring options.
- deleted 4y ago[deleted]