TDD is the practice to write tests before code and it should reduce failure rates and defects in your software.
In this blog-post I want to demonst...
For further actions, you may consider blocking this person and/or reporting abuse
Technically you didn't follow the tight TDD loop of only writing as much test code as necessary to produce a failing test. Instead you wrote multiple test cases and proceeded to fix them all at the same time (multiple being each of your 'convertedDates').
This is still way better than writing tests after the fact, or worse still not writing tests.
Yes you are right, thank you for the comment.
I could have splitt the test cases more. E.g. first test a year conversion, then a month conversion, then a day. And fix the problems between the tests. Also more scientifically correct would have been to test a single date only, fix it, test an other date, etc.
On the other hand one could argue I have only tested correct dates. Next iteration should test incorrect Gregorian dates, the one after that, dates that are outside of the provided table, etc.
It's actually very important that you write one test as a time, make it pass and then refactor.
Doing large chunks is how a lot of people get in to a mess.
Your example of TDD is poor for many reasons, but I'm going to focus on just two
REFACTORING
Refactoring is the soul of TDD; it's the space where we think about what we've done and what it means, what is my code trying to say about the problem. We get to be creative, we think of algorithms, we think of better ways of expressing the solution.
What we don't do is immediately pivot to writing a table and then using the tests to 'debug' it. Maybe we will have a table at the end of our iterations, maybe it'll be a big switch statement - or maybe there really is an algorithm. Who knows? But we should build up slowly, one test case at a time, as we discover and learn more about our domain and the code we've written.
ONE TEST AT A TIME
But what's worse is that you're essentially writing code to a specification written by someone else. That someone else is you. Just grinding through until a specification is fulfilled removes the space for reflection about the spec (is it right?, can I improve how it's expressed) that would come with refactoring.
What you're doing isn't TDD - it's writing all your unit tests first. You need to go slower, much slower, write less tests up front, and place refactoring at the heart of your practice.
Agree about the less tests.
I could have tested one date at a time.
I would also argue I did refactoring. The first approach of the algorithm was to add 56 years. It did not worked, but not in all cases, so I made it smarter.
By now I found an other edge case where the algorithm does not work, so I will add a test and refactor the algorithm till it works correctly.
Or do you mean something else by "refactoring"
"But what's worse is that you're essentially writing code to a specification written by someone else."
I don't quite understand what the problem is with that. There is a requirement ans I try to solve it with the code.
Refactoring means changing the code without changing behaviour.
Every example you gave of refactoring there changed the way the system worked (so not refactoring)
This might help quii.dev/The_Tests_Talk
hmm OK, I see. But for that I first need some code that does work and where the tests pass. After the tests pass with my (ugly, not optimized, not perfect) code I can start refactoring in the sense of changing code without changing the behaviour.
Where in TDD does that step come?
From the link I sent you above
If you want a more involved tutorial read github.com/quii/learn-go-with-tests
I know some Go but I usually code in .NET core, Python and Javascript so have to say that I find Go's handling of DDT (data-driven testing) pretty poor if you need to simulate it with a for loop. Is there another way of doing it? The code looks dirty, you got a loop inside a test method when unit tests in general (that means, applicable even if you are not using TDD) shouldn't have any logic, they should be atomic, with a single set of data and a single set of asserts per execution, which means no conditions, and a for loop includes one.
Not sure if it's a limitation of Go testing framework or not, that's why I ask if there's another way of implementing DDT.
Regards,
I think the loop is the way to do it in go see github.com/golang/go/wiki/TableDri...
Basically what you are doing in to multiple test runs by calling
t.Run()
An other useful principle in software development is BDD (Behavior-driven development), it emerged out of TDD and uses its general principles but focuses not on defining and testing a single unit (function) but on describing the behaviour of the system and by that improving the communication between different stakeholders of the project. I've written a post about BDD using the same project and taking it further: dev.to/jankaritech/demonstrating-b...