I like how these recent videos solidify my understanding of the Modern Software Engineering book you wrote. TDD could be seen as a tool to apply science engineering practical concepts based on iteration (which could be done by empiricism and continuous experiments)
The last point about TDD not being used took me back to Y2K work, when I had to deal with a PERL program made up of one module over 2000 lines long. The contractor who wrote it was not used again, I complained about it and when questioned about his approach his response was that it was “‘his baby”, as if doing work like that gave him job security.
Thanks for this! I agree with the approach in general, but my problem with TDD is that it often requires a framework for executing it, and that often requires an extra resource for just keep things running smoothly. It can be worth it for larger projects but it's a trade off. That being said. I practiced TDD for a couple of years I after a while I realized I started to write the code as if I was to be tested anyway, but just without the tests itself :-) . So, I would still recommend to practice TDD, but more for the reason to practice in designing better code (as you also explain in the video). Then you can almost remove them if they start to get in the way too much. :-) Actually, I write temporary test code sometimes. If you have the right integration/API (black box) testing from the outside it will anyway catch efficiently if something is wrong, in my experience. Also, if you have too many tests, even if small and simple, and you need to refactor your code it can be a mess sometimes. Sure, the reason for the refactoring might be that you misunderstood the system completely, but it can also be that the customer changed their mind, or don't know what they want (happens all the time), but still we have to deal with this problem all the time, it's a challenge. Thanks for sharing you experience, you put a new light on it that I think is inspiring!
I understand that for many codebases, this is a suitable way forward. I wonder how to properly apply these testing guidelines in quantitative image processing code where runtime is a problem in the first place. The only solution I found so far is to run the processing once and test the results of the analysis in isolated test methods. Repeat for different images (high exposure, low exposure, noise, other camera etc). Feels like a component test to me. If your algorithm is on the edge of what is possible with the given input images, there is often little to no choice to optimize the code for isolated testability of features.
What happens to me when I’m writing a new feature is that I don’t fully know what the feature will involve until I start developing it. For example, if the feature is 'create a cron task that expires all licenses after 30 days of being created,' I might start with that idea, but as I code, I realize I need additional information or steps. Maybe I discover that I need data that isn’t in the database, so I’ll have to fetch it from another service. This is something I wouldn’t have considered when initially setting up TDD, and I wouldn’t have that external service mocked in my test’s givens. This kind of thing can happen multiple times while developing, making it hard to anticipate everything beforehand in TDD. So, clearly i am missing something. I am not approaching it correctly, but how can i?
It is a design approach more than a technology, so it can certainly be applied to any general purpose programming system. I know of teams that have used it for SAP and SalesForce, I don't know about the products that you mention. What you need is enough flexibility to modularise your code sufficiently to test it in pieces. Most programming systems, but not all, will allow that.
In regard to the car/engine example. I see this kind of advice a lot. But to me, now you're making the users of this class do more work to use it, just for the sake of making it easier to test. I don't agree with the flexibility argument. Until its a requirement that you need different parameters, you've made the code more complex. So if anything, now there is more to go wrong. I think I would be more inclined to add readonly properties that make it easier to test. In this example, an IsEngineStarted property. Curious to hear peoples thoughts in this regard.
ETC - Easy to change - guiding principle. KISS - keep it simple stupid, and YAGNI - you ain't gonna need it, DRY - don't repeat yourself. When I see all those Java crazy abstractions that people create nowadays, crazy. And totally unneeded. A logging library that is so complex it takes a lot of time to understand it; but actually you only need 5% of it.
I disagree. I think that "Separation of Concerns" is not just about "making things easier to test", it is about good design! and the fact that TDD encourages us to do a better job of Separating the Concerns is a good thing not a bad. I disagree that the code is more complex in any meaningful way, each part is individually simpler.
@ContinuousDelivery but I want to create a Car. Why am I needing to pass in an engine? If you want to test the wheels, are you going to inject those too? You mentioned about not breaking encapsulation. But you've essentially done exactly that, under the disguise of 'making it flexible'. You're just exposing internals in a different way.
@SirBenJamin_ If your "engine" is internal property to the "car" then DI won't make much sense. But then, "engine" shouldn't be its own class since no encapsulation necessary when it is internal to the car. I.e there's no distinct behavior that can differentiate between both. Making engine a separate class is useful in the same way real world car use "dependency injection" to so that broken engine can be replaced and tyre can be swapped for use in different terrain.
@@bepamungkas You're missing the point though. The Car class was fine before. Its only when it needed testing that the author decided to now pass in extra parameters just so it could be tested. There is a big difference between using composition or injection because you need the flexibility .....verse using them just so you can test it. I see it all the time. Something which used to be a simple class with the necessary parameters, turned into something that now has to take lots of other bits JUST so it can be tested.
Not once, in 30 years of software development, have I seen TDD achieve anything other than waste time and money. BDD has it's merits, but where I've had to deal with TDD, all it managed to do, was create environments where the product became writing tests, rather than delivering usable, stable, reliable systems.
I think a lot of people have the same exact comment. To stand out, would you help out by describing why that seems to be the case? Especially if you consider that a common way to do BDD is to do TDD.
if writing a test takes more than 30 min - you are the problem (; in a well done framework - writing a test IS writing the code, you just make sure it works with 1 line to trigger it and several lines to assert it works... ever occur to you you have no idea what you are doing? did you ever try to ask for clarifications from experts?
@@retagainez To be honest, the name gives the problem away: Test-Driven-Design/Development. The primary concern becomes making sure the system is testable, rather than making sure the system is functional. i.e. You end up with a system that is testable, when your aim should be a system that is fit for purpose. The hype-machine also contributes to the miss-use and abuse of TDD, and its intended use within the context of Software Engineering. The same happened with design patterns, exception handling and even HTML tags. Engineers became so obsessed with showing off that they know design patterns, that they started making problems fit a chosen pattern, rather than applying the correct pattern for the problem at hand. When exception handling hit the hype-train, some started using it as glorified if-statements, causing business rules to become dependant upon exception handling. Which causes dramatic processing time increases, across entire systems. With HTML, it was wanting to show off that they know how to use the latest tag arising from the browser wars. Rather than focusing on delivering a good user experience. i.e. The focus becomes showing off, rather than delivering something fit for purpose, with good user experience. Then there is also something I call P.M.E.S for: Perpetual-motion-engine-syndrome. On paper, it looks possible. There is always just that one little thing, that one tiny thing that: If we solve it, makes it work. TDD, looks great on paper, the idea is beautiful, it promises so much and it looks like it should work. It is an Engineer's panacea. But then reality hits. Solving the problem in a way that is testable, by definition, takes longer than just solving the problem. TDD promises to make up for this during the maintenance phase of a system. But it simply does not deliver. It can't. Because the scope of problem domains, change during the life-span of a system. Meaning that you put yourself in a situation, where you have to maintain both the solution, the tests for the solution, as well as keeping the solution testable. Again, it boils down to chasing the dragon: If we can only fix this one little thing, it will work. With TDD, that one little thing, is never one little thing. Personally, I prefer Data-Driven-Design. Defining the data required by a system, and doing fully normalised data-structure design, results in the data structures telling you what the software should be, do and have. By the time you are done defining your data structures, writing the code for the system becomes a joy-ride. I have literally ended up in situations, where the CRUD for systems could be auto-generated, repeatedly, over the entire life-time of a system. When you get good at it, you end up in situations where adding/removing/re-defining data fields, becomes an exercise measured in minutes. Altering entire data-structures becomes a fun game, dealt with in a day or two. Development speed is also through the roof, because all the miss-communication and miss-understandings are dealt with, while exploring what data the business requires, how it needs to be represented, and why. If you properly document the WHY of it, your system becomes infinitely maintainable. All that remains after that, is business processes. And by the time you get to that, its a walk in the park. Even if processes are documented incorrectly, re-designing and re-implementation is way less of a problem, than with strategies like TDD. Distilled down to brass tacks: DDD has a natural fit within the agile process. TDD does not. DDD does have have one huge problems though: You can not be lazy with it! As a Software Engineer, DDD will save you mountains of aggravation, but it means you have to push yourself to not only know the business you are solving problems for, but also understand the business from the perspective of ALL the stake holders. i.e. You have to be in the business, for the business. Not for the code/tech/engineering. Meaning that you have to be far more of a people person than most of us like to be. You have to become what I call: A Business-First developer. Most software developers are Tech-First developers, they go after what ever the hype-train dictates. A business-first developer, endeavours to think on behalf of the business first. For those like us, having fun or showing off with the technical solution, is a distant second to having the latest buzz-word on our C.V. Meaning that we elect solid stable solutions over what ever the hype-train is screaming for. The second problem with DDD is, very few people grasp that: Relationships between data structures are senior to both data and meta-data. e.g. The relationship an account-data-structure has, to something like an invoice-data-structure, is more important to the data being facilitated in either structure. The relationships between your data structures, tell you what your system will look like. It even helps define your system infrastructure requirements. But you have to THINK! You have to actually put effort into THINKING ABOUT THE BUSINESS. Unfortunately, I find very few people in Software Engineering, ever manage to make the transition from "love-of-tech" to "love-of-solving-problems-with-tech". I know it sounds like semantics, but in practice it makes the world of difference.
@@xlnt2new Did it ever occur to you that talking about TDD and talking about writing a single test, are orders of magnitude apart? Also: Top-Tip, implying incompetence often displays incompetence. Enjoy meditating on that. 🙂
@@retagainez To be honest, the name gives the problem away: Test-Driven-Design/Development. The primary concern becomes making sure the system is testable, rather than making sure the system is functional. i.e. You end up with a system that is testable, when your aim should be a system that is fit for purpose. The hype-machine also contributes to the miss-use and abuse of TDD, and its intended use within the context of Software Engineering. The same happened with design patterns, exception handling and even HTML tags. Engineers became so obsessed with showing off that they know design patterns, that they started making problems fit a chosen pattern, rather than applying the correct pattern for the problem at hand. When exception handling hit the hype-train, some started using it as glorified if-statements, causing business rules to become dependant upon exception handling. Which causes dramatic processing time increases, across entire systems. With HTML, it was wanting to show off that they know how to use the latest tag arising from the browser wars. Rather than focusing on delivering a good user experience. i.e. The focus becomes showing off, rather than delivering something fit for purpose, with good user experience. Then there is also something I call P.M.E.S for: Perpetual-motion-engine-syndrome. On paper, it looks possible. There is always just that one little thing, that one tiny thing that: If we solve it, makes it work. TDD, looks great on paper, the idea is beautiful, it promises so much and it looks like it should work. It is an Engineer's panacea. But then reality hits. Solving the problem in a way that is testable, by definition, takes longer than just solving the problem. TDD promises to make up for this during the maintenance phase of a system. But it simply does not deliver. It can't. Because the scope of problem domains, change during the life-span of a system. Meaning that you put yourself in a situation, where you have to maintain both the solution, the tests for the solution, as well as keeping the solution testable. Again, it boils down to chasing the dragon: If we can only fix this one little thing, it will work. With TDD, that one little thing, is never one little thing. Personally, I prefer Data-Driven-Design. Defining the data required by a system, and doing fully normalised data-structure design, results in the data structures telling you what the software should be, do and have. By the time you are done defining your data structures, writing the code for the system becomes a joy-ride. I have literally ended up in situations, where the CRUD for systems could be auto-generated, repeatedly, over the entire life-time of a system. When you get good at it, you end up in situations where adding/removing/re-defining data fields, becomes an exercise measured in minutes. Altering entire data-structures becomes a fun game, dealt with in a day or two. Development speed is also through the roof, because all the miss-communication and miss-understandings are dealt with, while exploring what data the business requires, how it needs to be represented, and why. If you properly document the WHY of it, your system becomes infinitely maintainable. All that remains after that, is business processes. And by the time you get to that, its a walk in the park. Even if processes are documented incorrectly, re-designing and re-implementation is way less of a problem, than with strategies like TDD. Distilled down to brass tacks: DDD has a natural fit within the agile process. TDD does not. DDD does have have one huge problems though: You can not be lazy with it! As a Software Engineer, DDD will save you mountains of aggravation, but it means you have to push yourself to not only know the business you are solving problems for, but also understand the business from the perspective of ALL the stake holders. i.e. You have to be in the business, for the business. Not for the code/tech/engineering. Meaning that you have to be far more of a people person than most of us like to be. You have to become what I call: A Business-First developer. Most software developers are Tech-First developers, they go after what ever the hype-train dictates. A business-first developer, endeavours to think on behalf of the business first. For those like us, having fun or showing off with the technical solution, is a distant second to having the latest buzz-word on our C.V. Meaning that we elect solid stable solutions over what ever the hype-train is screaming for. The second problem with DDD is, very few people grasp that: Relationships between data structures are senior to both data and meta-data. e.g. The relationship an account-data-structure has, to something like an invoice-data-structure, is more important to the data being facilitated in either structure. The relationships between your data structures, tell you what your system will look like. It even helps define your system infrastructure requirements. But you have to THINK! You have to actually put effort into THINKING ABOUT THE BUSINESS. Unfortunately, I find very few people in Software Engineering, ever manage to make the transition from "love-of-tech" to "love-of-solving-problems-with-tech". I know it sounds like semantics, but in practice it makes the world of difference.
First you do a prototype, then TDD for the real implementation. Never just TDD without a prototype. Never start with a test. Test target - specifications - can not be envisioned prior prototype, since prototype is kind of final - viable - specification. That's why you see all those Jira tickets, that evolve during the years, all tweaking the same functionalities. TDD is extremely hard to do really right. Nowadays people think 100% code coverage is TDD. And also, all sorts of frameworks are not TDD compatible, for example, Unity, Oracle Apex, and most GUI just mock all crucial dependencies - is that a real test anyway?
@@ivanbolcina we do also write tests for database schemas, types, views, udfs and procedures ... beforehand... red/green/refactor. If that does in any way cover your mention of oracle (RDBMS?)
@@ContinuousDelivery most of the problems comes from not 100% defined contracts: interfaces, data transfer objects, sequence diagrams, use cases. After the prototype, you get much more robust and tuned picture. At that point, TDD is a good approach- after all, you throw prototype away and start coding from scratch. So you can first write test, then implantation.
@@jurgenzornig6382 curious. I understand tests for a stored procedure, but for a table definition? Do you create a table and introspect it if it has a column in it? For Oracle Apex I have no idea how one does TDD.
@@ivanbolcina Or you can just simply architect stuff in higher view with people, then codify it with tests. Hence why TDD does not say enough HOW to design stuff when doing TDD :)
Dziękujemy.
I like how these recent videos solidify my understanding of the Modern Software Engineering book you wrote. TDD could be seen as a tool to apply science engineering practical concepts based on iteration (which could be done by empiricism and continuous experiments)
The last point about TDD not being used took me back to Y2K work, when I had to deal with a PERL program made up of one module over 2000 lines long. The contractor who wrote it was not used again, I complained about it and when questioned about his approach his response was that it was “‘his baby”, as if doing work like that gave him job security.
Thanks
First! Great Series btw. really insightful videos on TDD, CD and SE topics.
Thanks for this! I agree with the approach in general, but my problem with TDD is that it often requires a framework for executing it, and that often requires an extra resource for just keep things running smoothly. It can be worth it for larger projects but it's a trade off. That being said. I practiced TDD for a couple of years I after a while I realized I started to write the code as if I was to be tested anyway, but just without the tests itself :-) . So, I would still recommend to practice TDD, but more for the reason to practice in designing better code (as you also explain in the video). Then you can almost remove them if they start to get in the way too much. :-) Actually, I write temporary test code sometimes. If you have the right integration/API (black box) testing from the outside it will anyway catch efficiently if something is wrong, in my experience. Also, if you have too many tests, even if small and simple, and you need to refactor your code it can be a mess sometimes. Sure, the reason for the refactoring might be that you misunderstood the system completely, but it can also be that the customer changed their mind, or don't know what they want (happens all the time), but still we have to deal with this problem all the time, it's a challenge. Thanks for sharing you experience, you put a new light on it that I think is inspiring!
I understand that for many codebases, this is a suitable way forward. I wonder how to properly apply these testing guidelines in quantitative image processing code where runtime is a problem in the first place.
The only solution I found so far is to run the processing once and test the results of the analysis in isolated test methods. Repeat for different images (high exposure, low exposure, noise, other camera etc). Feels like a component test to me. If your algorithm is on the edge of what is possible with the given input images, there is often little to no choice to optimize the code for isolated testability of features.
What happens to me when I’m writing a new feature is that I don’t fully know what the feature will involve until I start developing it. For example, if the feature is 'create a cron task that expires all licenses after 30 days of being created,' I might start with that idea, but as I code, I realize I need additional information or steps. Maybe I discover that I need data that isn’t in the database, so I’ll have to fetch it from another service. This is something I wouldn’t have considered when initially setting up TDD, and I wouldn’t have that external service mocked in my test’s givens. This kind of thing can happen multiple times while developing, making it hard to anticipate everything beforehand in TDD.
So, clearly i am missing something. I am not approaching it correctly, but how can i?
can TDD apply to proprietary corporate software, i.e Guidewire InsuranceSuite? Duck Creek?
It is a design approach more than a technology, so it can certainly be applied to any general purpose programming system. I know of teams that have used it for SAP and SalesForce, I don't know about the products that you mention.
What you need is enough flexibility to modularise your code sufficiently to test it in pieces. Most programming systems, but not all, will allow that.
Isnt it a necessary step for when theres things like compliance, if you want to be a successful tech org?
Maybe we should start calling it Test Driven Design?
In regard to the car/engine example. I see this kind of advice a lot. But to me, now you're making the users of this class do more work to use it, just for the sake of making it easier to test. I don't agree with the flexibility argument. Until its a requirement that you need different parameters, you've made the code more complex. So if anything, now there is more to go wrong. I think I would be more inclined to add readonly properties that make it easier to test. In this example, an IsEngineStarted property. Curious to hear peoples thoughts in this regard.
ETC - Easy to change - guiding principle. KISS - keep it simple stupid, and YAGNI - you ain't gonna need it, DRY - don't repeat yourself.
When I see all those Java crazy abstractions that people create nowadays, crazy. And totally unneeded. A logging library that is so complex it takes a lot of time to understand it; but actually you only need 5% of it.
I disagree. I think that "Separation of Concerns" is not just about "making things easier to test", it is about good design! and the fact that TDD encourages us to do a better job of Separating the Concerns is a good thing not a bad. I disagree that the code is more complex in any meaningful way, each part is individually simpler.
@ContinuousDelivery but I want to create a Car. Why am I needing to pass in an engine? If you want to test the wheels, are you going to inject those too? You mentioned about not breaking encapsulation. But you've essentially done exactly that, under the disguise of 'making it flexible'. You're just exposing internals in a different way.
@SirBenJamin_ If your "engine" is internal property to the "car" then DI won't make much sense. But then, "engine" shouldn't be its own class since no encapsulation necessary when it is internal to the car. I.e there's no distinct behavior that can differentiate between both.
Making engine a separate class is useful in the same way real world car use "dependency injection" to so that broken engine can be replaced and tyre can be swapped for use in different terrain.
@@bepamungkas You're missing the point though. The Car class was fine before. Its only when it needed testing that the author decided to now pass in extra parameters just so it could be tested. There is a big difference between using composition or injection because you need the flexibility .....verse using them just so you can test it. I see it all the time. Something which used to be a simple class with the necessary parameters, turned into something that now has to take lots of other bits JUST so it can be tested.
I thought this was a brand new TDD episode, not just glued together other videos :/
@@danielwilkowski5899 same! lame…
first 🙂
😂
Not once, in 30 years of software development, have I seen TDD achieve anything other than waste time and money. BDD has it's merits, but where I've had to deal with TDD, all it managed to do, was create environments where the product became writing tests, rather than delivering usable, stable, reliable systems.
I think a lot of people have the same exact comment. To stand out, would you help out by describing why that seems to be the case? Especially if you consider that a common way to do BDD is to do TDD.
if writing a test takes more than 30 min - you are the problem (;
in a well done framework - writing a test IS writing the code, you just make sure it works with 1 line to trigger it and several lines to assert it works... ever occur to you you have no idea what you are doing? did you ever try to ask for clarifications from experts?
@@retagainez To be honest, the name gives the problem away: Test-Driven-Design/Development.
The primary concern becomes making sure the system is testable, rather than
making sure the system is functional.
i.e. You end up with a system that is testable, when your aim should be a system
that is fit for purpose.
The hype-machine also contributes to the miss-use and abuse of TDD, and its
intended use within the context of Software Engineering.
The same happened with design patterns, exception handling and even HTML tags.
Engineers became so obsessed with showing off that they know design patterns,
that they started making problems fit a chosen pattern, rather than applying the
correct pattern for the problem at hand.
When exception handling hit the hype-train, some started using it as glorified
if-statements, causing business rules to become dependant upon exception handling.
Which causes dramatic processing time increases, across entire systems.
With HTML, it was wanting to show off that they know how to use the latest tag
arising from the browser wars. Rather than focusing on delivering a good user
experience.
i.e. The focus becomes showing off, rather than delivering something fit for
purpose, with good user experience.
Then there is also something I call P.M.E.S for: Perpetual-motion-engine-syndrome.
On paper, it looks possible. There is always just that one little thing, that
one tiny thing that: If we solve it, makes it work.
TDD, looks great on paper, the idea is beautiful, it promises so much and it
looks like it should work. It is an Engineer's panacea.
But then reality hits.
Solving the problem in a way that is testable, by definition, takes longer than
just solving the problem. TDD promises to make up for this during the
maintenance phase of a system. But it simply does not deliver. It can't. Because
the scope of problem domains, change during the life-span of a system.
Meaning that you put yourself in a situation, where you have to maintain both the
solution, the tests for the solution, as well as keeping the solution
testable.
Again, it boils down to chasing the dragon: If we can only fix this one little
thing, it will work.
With TDD, that one little thing, is never one little thing.
Personally, I prefer Data-Driven-Design. Defining the data required by a system,
and doing fully normalised data-structure design, results in the data structures
telling you what the software should be, do and have. By the time you are done
defining your data structures, writing the code for the system becomes a joy-ride.
I have literally ended up in situations, where the CRUD for systems could be
auto-generated, repeatedly, over the entire life-time of a system.
When you get good at it, you end up in situations where adding/removing/re-defining
data fields, becomes an exercise measured in minutes. Altering entire
data-structures becomes a fun game, dealt with in a day or two.
Development speed is also through the roof, because all the miss-communication
and miss-understandings are dealt with, while exploring what data the business
requires, how it needs to be represented, and why. If you properly document
the WHY of it, your system becomes infinitely maintainable.
All that remains after that, is business processes. And by the time you get to
that, its a walk in the park. Even if processes are documented incorrectly,
re-designing and re-implementation is way less of a problem, than with strategies
like TDD.
Distilled down to brass tacks: DDD has a natural fit within the agile process. TDD does not.
DDD does have have one huge problems though: You can not be lazy with it!
As a Software Engineer, DDD will save you mountains of aggravation, but it means
you have to push yourself to not only know the business you are solving problems
for, but also understand the business from the perspective of ALL the stake
holders.
i.e. You have to be in the business, for the business. Not for the code/tech/engineering.
Meaning that you have to be far more of a people person than most of us like to be.
You have to become what I call: A Business-First developer.
Most software developers are Tech-First developers, they go after what ever
the hype-train dictates.
A business-first developer, endeavours to think on behalf of the business first.
For those like us, having fun or showing off with the technical solution,
is a distant second to having the latest buzz-word on our C.V. Meaning that we
elect solid stable solutions over what ever the hype-train is screaming for.
The second problem with DDD is, very few people grasp that: Relationships between
data structures are senior to both data and meta-data.
e.g. The relationship an account-data-structure has, to something like an
invoice-data-structure, is more important to the data being facilitated in either
structure.
The relationships between your data structures, tell you what your system will
look like. It even helps define your system infrastructure requirements.
But you have to THINK! You have to actually put effort into THINKING ABOUT THE
BUSINESS.
Unfortunately, I find very few people in Software Engineering, ever manage
to make the transition from "love-of-tech" to "love-of-solving-problems-with-tech".
I know it sounds like semantics, but in practice it makes the world of
difference.
@@xlnt2new Did it ever occur to you that talking about TDD and talking about writing a single test, are orders of magnitude apart?
Also: Top-Tip, implying incompetence often displays incompetence. Enjoy meditating on that. 🙂
@@retagainez To be honest, the name gives the problem away: Test-Driven-Design/Development.
The primary concern becomes making sure the system is testable, rather than
making sure the system is functional.
i.e. You end up with a system that is testable, when your aim should be a system
that is fit for purpose.
The hype-machine also contributes to the miss-use and abuse of TDD, and its
intended use within the context of Software Engineering.
The same happened with design patterns, exception handling and even HTML tags.
Engineers became so obsessed with showing off that they know design patterns,
that they started making problems fit a chosen pattern, rather than applying the
correct pattern for the problem at hand.
When exception handling hit the hype-train, some started using it as glorified
if-statements, causing business rules to become dependant upon exception handling.
Which causes dramatic processing time increases, across entire systems.
With HTML, it was wanting to show off that they know how to use the latest tag
arising from the browser wars. Rather than focusing on delivering a good user
experience.
i.e. The focus becomes showing off, rather than delivering something fit for
purpose, with good user experience.
Then there is also something I call P.M.E.S for: Perpetual-motion-engine-syndrome.
On paper, it looks possible. There is always just that one little thing, that
one tiny thing that: If we solve it, makes it work.
TDD, looks great on paper, the idea is beautiful, it promises so much and it
looks like it should work. It is an Engineer's panacea.
But then reality hits.
Solving the problem in a way that is testable, by definition, takes longer than
just solving the problem. TDD promises to make up for this during the
maintenance phase of a system. But it simply does not deliver. It can't. Because
the scope of problem domains, change during the life-span of a system.
Meaning that you put yourself in a situation, where you have to maintain both the
solution, the tests for the solution, as well as keeping the solution
testable.
Again, it boils down to chasing the dragon: If we can only fix this one little
thing, it will work.
With TDD, that one little thing, is never one little thing.
Personally, I prefer Data-Driven-Design. Defining the data required by a system,
and doing fully normalised data-structure design, results in the data structures
telling you what the software should be, do and have. By the time you are done
defining your data structures, writing the code for the system becomes a joy-ride.
I have literally ended up in situations, where the CRUD for systems could be
auto-generated, repeatedly, over the entire life-time of a system.
When you get good at it, you end up in situations where adding/removing/re-defining
data fields, becomes an exercise measured in minutes. Altering entire
data-structures becomes a fun game, dealt with in a day or two.
Development speed is also through the roof, because all the miss-communication
and miss-understandings are dealt with, while exploring what data the business
requires, how it needs to be represented, and why. If you properly document
the WHY of it, your system becomes infinitely maintainable.
All that remains after that, is business processes. And by the time you get to
that, its a walk in the park. Even if processes are documented incorrectly,
re-designing and re-implementation is way less of a problem, than with strategies
like TDD.
Distilled down to brass tacks: DDD has a natural fit within the agile process. TDD does not.
DDD does have have one huge problems though: You can not be lazy with it!
As a Software Engineer, DDD will save you mountains of aggravation, but it means
you have to push yourself to not only know the business you are solving problems
for, but also understand the business from the perspective of ALL the stake
holders.
i.e. You have to be in the business, for the business. Not for the code/tech/engineering.
Meaning that you have to be far more of a people person than most of us like to be.
You have to become what I call: A Business-First developer.
Most software developers are Tech-First developers, they go after what ever
the hype-train dictates.
A business-first developer, endeavours to think on behalf of the business first.
For those like us, having fun or showing off with the technical solution,
is a distant second to having the latest buzz-word on our C.V. Meaning that we
elect solid stable solutions over what ever the hype-train is screaming for.
The second problem with DDD is, very few people grasp that: Relationships between
data structures are senior to both data and meta-data.
e.g. The relationship an account-data-structure has, to something like an
invoice-data-structure, is more important to the data being facilitated in either
structure.
The relationships between your data structures, tell you what your system will
look like. It even helps define your system infrastructure requirements.
But you have to THINK! You have to actually put effort into THINKING ABOUT THE
BUSINESS.
Unfortunately, I find very few people in Software Engineering, ever manage
to make the transition from "love-of-tech" to "love-of-solving-problems-with-tech".
I know it sounds like semantics, but in practice it makes the world of
difference.
First you do a prototype, then TDD for the real implementation. Never just TDD without a prototype. Never start with a test. Test target - specifications - can not be envisioned prior prototype, since prototype is kind of final - viable - specification. That's why you see all those Jira tickets, that evolve during the years, all tweaking the same functionalities. TDD is extremely hard to do really right. Nowadays people think 100% code coverage is TDD.
And also, all sorts of frameworks are not TDD compatible, for example, Unity, Oracle Apex, and most GUI just mock all crucial dependencies - is that a real test anyway?
It's not TDD if you don't start with a test! How do you "Drive Development" after you have done the development?
@@ivanbolcina we do also write tests for database schemas, types, views, udfs and procedures ... beforehand... red/green/refactor. If that does in any way cover your mention of oracle (RDBMS?)
@@ContinuousDelivery most of the problems comes from not 100% defined contracts: interfaces, data transfer objects, sequence diagrams, use cases. After the prototype, you get much more robust and tuned picture. At that point, TDD is a good approach- after all, you throw prototype away and start coding from scratch. So you can first write test, then implantation.
@@jurgenzornig6382 curious. I understand tests for a stored procedure, but for a table definition? Do you create a table and introspect it if it has a column in it? For Oracle Apex I have no idea how one does TDD.
@@ivanbolcina Or you can just simply architect stuff in higher view with people, then codify it with tests. Hence why TDD does not say enough HOW to design stuff when doing TDD :)