Test Driven Development vs Behavior Driven Development

  Рет қаралды 147,670

Continuous Delivery

Continuous Delivery

Күн бұрын

TDD vs BDD, Test Driven Development vs Behaviour Driven Development which is most important to get right? Most people think of BDD and TDD as having distinctly different focusses in an effective automated testing strategy. In fact they are more closely related than many people think.
In this episode on the Continuous Delivery channel, Dave Farley, who was involved in the creation of BDD, explains his slightly more unusual take on the real value of this approach to creating automated tests. Dave believes that TDD and BDD are at the foundations of a sound software engineering approach to software development and explores these ideas with some real-world examples of good and bad automated tests.
-------------------------------------------------------------------------------------
LINKS:
The original BDD wiki that Dave helped to write ➡️ www.behaviourdriven.org/
The 1968 NATO Software Engineering Conference ➡️ homepages.cs.ncl.ac.uk/brian.r...
🎓 CD TRAINING COURSES 🎓
If you want to learn Continuous Delivery and DevOps skills, check out Dave Farley's courses ➡️ bit.ly/DFTraining
📚 BOOKS:
📖 Dave’s NEW BOOK "Modern Software Engineering" is now available on
Kindle ➡️ amzn.to/3DwdwT3
(Paperback version available soon)
In this book, Dave brings together his ideas and proven techniques to describe a durable, coherent and foundational approach to effective software development, for programmers, managers and technical leads, at all levels of experience.
📖 "Continuous Delivery Pipelines" by Dave Farley
paperback ➡️ amzn.to/3gIULlA
ebook version ➡️ leanpub.com/cd-pipelines
📖 The original, award-winning "Continuous Delivery" book by Dave Farley and Jez Humble
➡️ amzn.to/2WxRYmx
📖 "Extreme Programming Explained: Embrace Change", Kent Beck ➡️ amzn.to/2GpQRjE
📖 "Growing Object Oriented Software Guided by Tests", By Nat Price & Steve Freeman ➡️ amzn.to/2Lt3jho
(Please Note some of these are 'Affiliate Links' meaning that we will make a small amount of money if you buy one of these books, without it costing any more to you.)
📧 JOIN MY MAIL LIST 📧
Keep up to date with the latest discussions, free "How To..." guides, events and online courses.
AND get Dave Farley’s FREE “Beginners’ Guide to TDD” here
➡️ www.subscribepage.com/cd-guid...
-------------------------------------------------------------------------------------
CHANNEL SPONSORS:
Equal Experts is a product software development consultancy with a network of over 1,000 experienced technology consultants globally. They increase the pace of innovation by using modern software engineering practices that embrace Continuous Delivery, Security, and Operability from the outset ➡️ www.equalexperts.com/
Harness helps engineers and developers simplify and scale CI/CD, Feature Flags and Cloud Cost Management with an AI-powered platform for software delivery. ➡️ bit.ly/3Cfx3qI
Octopus are the makers of Octopus Deploy the single place for your team to manage releases, automate deployments, and automate the runbooks that keep your software operating. ➡️ octopus.com/
SpecFlow Behavior Driven Development for .NET SpecFlow helps teams bind automation to feature files and share the resulting examples as Living Documentation across the team and stakeholders. ➡️ go.specflow.org/dave_farley

Пікірлер: 284
@ContinuousDelivery
@ContinuousDelivery Жыл бұрын
Master testing and become an expert in TDD, BDD & ATDD. This comprehensive course bundle gives you sought after skills, ready to tackle the modern world of software engineering 🚀 Find out more about this collection HERE ➡ courses.cd.training/bundles/totally-testing PAYMENT PLANS AVAILABLE TOO.
@Redheadtama1
@Redheadtama1 2 жыл бұрын
"We've ended up testing that the code that we wrote was the code that we wrote." Man this is exactly the trap I fell into when I got started with testing. Finding your channel has totally transformed the way I view and write tests. Great stuff!
@ContinuousDelivery
@ContinuousDelivery 2 жыл бұрын
Thanks
@ImmaterialDigression
@ImmaterialDigression 2 жыл бұрын
Yes! Love this so much
@bartholomewtott3812
@bartholomewtott3812 2 жыл бұрын
Tautological testing.
@robotempire
@robotempire 2 жыл бұрын
@@bartholomewtott3812 Tautology Driven Development 😸
@aldob5681
@aldob5681 2 жыл бұрын
The most common acronym you can find in project blueprint is TBD
@tyronfoston7123
@tyronfoston7123 2 жыл бұрын
Lol
@sunils2111
@sunils2111 2 жыл бұрын
ha ha ha too good !!!
@AbcDef-kv7zc
@AbcDef-kv7zc Жыл бұрын
😃
@colinmaharaj
@colinmaharaj 9 ай бұрын
To be determined ?!
@aldob5681
@aldob5681 9 ай бұрын
@@colinmaharaj more or less. to be defined
@RageBasterd
@RageBasterd 2 жыл бұрын
and we on our team thought BDD stands for Bug Driven Development.
@porky1118
@porky1118 2 жыл бұрын
When you write your code as fast as possible, and then fix bugs most of the time until all the obvious bugs are gone, I guess.
@TheMsksk
@TheMsksk 2 жыл бұрын
You won't believe this but I actually learnt about TDD today, binge watched all your TDD related videos and then typed in exactly the same query as your title on youtube to learn more and magically your video pops up which was upload just a few minutes ago! This is incredible!
@Kamel419
@Kamel419 2 жыл бұрын
he's watching lol
@TheMsksk
@TheMsksk 2 жыл бұрын
@@Kamel419 Haha. Taking Continuous Delivery to the next level
@ContinuousDelivery
@ContinuousDelivery 2 жыл бұрын
Pleased to be of service :)
@validus1684
@validus1684 Жыл бұрын
Something I absolutely love about this video is that you are using real examples of code. Often times in online tutorials you get extremely simple scenarios that you would almost never need, which makes it look easy and then you go to put it into practice and then feel a little lost. Seeing it with a real, complex problem makes it much easier, at least for me, to translate the concepts to my actual work.
@disgruntledtoons
@disgruntledtoons Жыл бұрын
My problem with most tutorials is that the authors tend to forget that they're writing tutorials, i.e. a guide to introduce somebody to something with which they have no experience. Most "tutorials" make assumptions that render them useless to the people who actually need them.
@underdog578
@underdog578 3 ай бұрын
Really great video, love this summation of good code: 1. It works 2. Is modular 3. Is cohesive 4. Appropriate level of coupling - tends to loose coupling 5. Good separation of concerns 6. Hides information
@Proactivity
@Proactivity 2 жыл бұрын
The phrase "I reiterate this once again" made me smile. To iterate means to repeat. So, to reiterate must mean to re-repeat, and therefore to reiterate once again must be to re-re-repeat. I know, I'm weird.
@andyd568
@andyd568 2 жыл бұрын
Iterate means repeat execution on a new set of data. Reiterate means to repeat a piece of communication.
@christianfuchs9750
@christianfuchs9750 2 жыл бұрын
@15:37 write the test against an interface, not the implementation - simply great
@CalebDiT
@CalebDiT Жыл бұрын
I really like the historical insights you add to your descriptions. They add color and give a good answer to "Why?", and not just "How?"
@AnthonyJackman
@AnthonyJackman 2 жыл бұрын
I love that T-Shirt you have on. Several hours of discussions could come from digesting the message it delivers. Please keep teaching!
@juliankandlhofer7553
@juliankandlhofer7553 2 жыл бұрын
Great video! When using BDD it feels a lot like I am writing functional code which is inherently easier to test. Even if "Given" and "Then" from the "Given, When, Then" pattern end up coming from mocked dependencies, I can describe the behaviour in a style that feels a lot like an input to output mapping. Importantly, it leaves the possibility open to connect input to output in any way I like, as long as the tests pass! This makes refactoring really enjoyable!
@modestas3d391
@modestas3d391 Жыл бұрын
Yet another great video and clear explanations. Top class!
@OggerFN
@OggerFN 2 жыл бұрын
Great video as always!
@leandrostoneshop
@leandrostoneshop Жыл бұрын
Amazing! Thank you for sharing your experience.
@vincenzo-zocca
@vincenzo-zocca 2 жыл бұрын
Great stuff on [TB]DD. I tend to solve the meta problem. One creates a language that defines customer object types, internal object types and functions/behaviour. Once these are in place one sees a type of language emerging by which the problem at hand can be expressed. Suddenly the system can be argued and it becomes clear how changes need to be formulated and what the impact thereof may be. And ultimately the behaviour can be tested. Indeed, design well and critically check the implementation. In sort, a well defined system that solves the meta problem will make complex problems seem simple whilst keeping a clear overview which makes further development a delight. [TB]DD is a reflection of a well thought of system.
@ponypapa6785
@ponypapa6785 2 жыл бұрын
It is really good to get confirmation on what I've been telling my colleagues all the time - that BDD is basically a tool to help understand TDD and adopt is in a simpler way. I really like and enjoy your videos, please keep it up, you make understanding some harder problems really simple.
@ContinuousDelivery
@ContinuousDelivery 2 жыл бұрын
Thanks
@DAG_42
@DAG_42 2 жыл бұрын
Excellent guidance.. thank you very much for this
@padaricohora9094
@padaricohora9094 2 жыл бұрын
very informative, and interesting to hear from someone with first hand experience
@anothermouth7077
@anothermouth7077 2 жыл бұрын
I love this. I get to know the philosophy behind why we do what we do.
@gmxmatei
@gmxmatei 6 ай бұрын
Only 3 concepts: Parameters, Subject and Informational Individual! This is the future in software!
@muyewahqomeyour7206
@muyewahqomeyour7206 2 жыл бұрын
This channel is a gem
@luissantos9120
@luissantos9120 2 жыл бұрын
I actually think that gherkin and cucumber created more harm than helped. I haven't seen a project that uses these technologies that delivered value. These tools promote the mindset that quality and development are independent and that using natural language would be better. It helped move the responsibility of testing the systems from development teams to "QA teams". It promotes numerous anti-patterns. I'm sure that there are good examples of systems out there using these tools successfully but most are not good.
@FranzAllanSee
@FranzAllanSee 2 жыл бұрын
It's a tool created by developers that somehow gets pushed to be used by QA. With that comes the paradigm shift. Developers love declarative style (or at least declarative style is seasonal roughly every 4yrs :D ). But QA loves procedural (i.e. go to login page, login, do X, check Y, etc). So pushing them to use BDD is a paradigm shift. And even when they use it, BDD used procedurally (i.e. several when-then in a single scenario) kinda defeats the purpose.
@aveneyer
@aveneyer 2 жыл бұрын
Huge +1. I've had the opportunity to work with Saas companies large and small, a small and large fintech, and now a large MedTech Org. I've seen BDD-tools done well, where global object repositories are shared between the entire org and disciplines in a way that enabled anyone in the value stream to add acceptance criteria. Product, engineering, SDETs, and QAs all speaking the same language on acceptance criteria, where not all acceptance criteria was met with tests in the traceability matrix. When done within scope, it can be quite transformative. But that was an outlier. Every other team I've worked with has employed BDD-tools as a way to "help non-technical individuals write automation." Note: Automation, not tests (sigh) - These create complexity, and the value of that complexity must be scrutinized. Do you need a language that the entire org can speak? Are non-technicals going to actually read the feature files? Is your business logic so complex that the added complexity is worth the cost-benefit? The answer is going to be no for most organizations. The draw of "no/low code!" and "anyone can do automation!" are traps that will continue to capture organizations that haven't nurtured technical excellence.
@FranzAllanSee
@FranzAllanSee 2 жыл бұрын
@@aveneyer curious, in the group that did BDD well, was the interface of the system under test UI or APIs? Thanks!
@aveneyer
@aveneyer 2 жыл бұрын
@@FranzAllanSee Both, actually. Most teams with API interfaces didn't use BDD tools to write their tests. Many teams felt that the complexity of these tools added too much to their simple API tests, and it wasn't worth the value proposition. However, through a combination of property-based testing patterns, supplemented by example-based patterns for acceptance criteria, those teams could still communicate the most important scenarios to the business. For UI Testing, shared object repositories existed for both business keywords and Selenium page objects. Teams utilized BDD tools much more frequently for their UI tests.
@BittermanAndy
@BittermanAndy 2 жыл бұрын
I'm with you. It's not even natural language (obviously, because that would require an AGI natural language processor, which doesn't yet exist). It's just code wrapped in strings to make it look like natural language. It just obscures what is really happening to make it easier for someone to read (I'm not even sure exactly who the target is). Complete waste of time that I've never seen deliver value.
@vuhlko
@vuhlko 2 жыл бұрын
Wow, how did I not find this sooner? Excellent and informative content, you have a dedicated subscriber!
@ContinuousDelivery
@ContinuousDelivery 2 жыл бұрын
Welcome aboard!
@TheGrumpyGameDev
@TheGrumpyGameDev 2 жыл бұрын
Just last week, my team and I started on the journey of learning what a DSL looks like for us. Which means I have some functions with the word "Should" at the front of them, and some extension methods (we are using C#) to make the tests fluent and to reduce the cyclomatic complexity to as close to 1 as we can muster. But we know that this first bit is learning what we have to learn in order to reach our goals, but already we like that we can make these smoke tests part of our devops process. We have even already detected problems with the system BEFORE the PR was reviewed. Also on the plus side, rather than trying to convince my team of what I am learning, I can just post Continuous Delivery videos for them to watch.
@ponypapa6785
@ponypapa6785 2 жыл бұрын
Sadly, just posting videos does not work for me anymore, as my colleagues often respond with "again with these videos?" =) Good job though, keep it up, I found that adopting these practices really does help a LOT
@mrspecs4430
@mrspecs4430 2 жыл бұрын
Im struggling with that too... Its convenient for you to just post a video and say 'watch that'. The other Person though would have to sit through an entire video that they might not understand or like the presenter (and even the subject) and they don't know the value of the video. So they are reluctant to accept it and might easily get annoyed with it and mentally block the entire subject...
@CanalDoRaphaelDeLio
@CanalDoRaphaelDeLio 2 жыл бұрын
Thank you for sharing all this information
@Rodhern
@Rodhern 2 жыл бұрын
If you don't know what to do a video on next, I would like to hear your thoughts on code being 'cohesive'. That is the one of your six properties I think is the least self-explanatory.
@emart017
@emart017 2 жыл бұрын
Very informative video sir. BTW, I love your shirt!
@SaiyanJin85
@SaiyanJin85 2 жыл бұрын
Great video!! The notion that in order to use BDD we need to use gerkins and its tools always bugged me. Like if the tool is the heart of the test instead of the test itself. I'm not very experienced in testing yet but one thing I certainly know is that the key to stay in the testing mindset is to have simple to use tools and not a lot of them. Especially for a newcomer is very big pill to sallow if before i learn to test I have a to learn a plethora of tools.
@alexanderruchkov8440
@alexanderruchkov8440 Жыл бұрын
QA here, uhm, my personal experience with bdd was not a favorable one - i wrote a ton of "scripts" which were backed by a "real" language, in that case - java so why not to write exactly in java in the first place? Cut the middleman so to speak. I did that in my second project - had java + allure - it was a way smoother experience for i could debug things normally and had direct control of what I did.
@benmathews533
@benmathews533 2 жыл бұрын
Sounds great. I definitely don't want to write code that tests whether the code I wrote was the code I wrote. Finding the path from fantasy to reality is difficult. Even in Dave's tests he's already made some concrete decisions about implementation details otherwise "transport" and "TestMessageEncoder" couldn't have been in the tests. So maybe the code was written or partially written in his head rather than typed out prior to tests being written. Dave's tests had less coupling than the open source example so that's good. I don't necessarily know what libraries I'm going to use until later, so I end up writing tests after the fact. If I knew so much of these things first then I'd be testing that the code I'm about to write is the code that I'm about to write which I don't know is much better. Thanks for another great video!
@DodaGarcia
@DodaGarcia 5 ай бұрын
But that's the point he's making with that example, he himself calls it "technical plumbing". It shows that while we do need to test our implementation to get a full view of the health of the system, that doesn't mean that those implementation details can't be well designed. Of course things such as "transport" aren't part of the business domain, but they are a part of the system infrastructure and they can also be written interfaces that allow for easy changes, and easy testing.
@FlaviusAspra
@FlaviusAspra 2 жыл бұрын
Dave, I've been quite criticizing towards some of your videos, but I think that if we'd sit together in a room and try to solve/design a system for a concrete problem/domain, we would agree much more than we'd do it over the internet. Great video! I've always proposed minimizing the number of tools used while maximizing the number of problems solved, and one consequence of that was to write "BDD" with the very same tool/framework with which you write your TDD tests. Yet I've always met resistance, almost to the point where I thought I'm the crazy one. Now I know, I'm not alone.
@Zeuts85
@Zeuts85 Жыл бұрын
Could do without your first sentence--it is irrelevant and seems a bit silly/egotistical to assume he cares whether you've criticized any of his videos or whether you'd agree about anything in person.
@gamingbeast710
@gamingbeast710 2 ай бұрын
Awesome thx a lot . So informative content ❤
@mhcbon4606
@mhcbon4606 2 жыл бұрын
in my understanding the hard thing about writing test first is to be sufficiently experienced to know the api you desire as a result. Sometimes this is easy, sometimes it is harder when fundamental design decision has to be taken at the beginning of the conceptualization of the solution, when you dont have the experience you write the solution to build up experience then write tests to harness the result. Finally when coding for money, if you find a solution that appears to be functionally correct and test harnessed, then, maybe that s good enough....
@EricKolotyluk
@EricKolotyluk 2 жыл бұрын
Great presentation! Neither is better, they are both good... is that the answer to the trick question? Working on a Greenfield project, I find that tests are great, especially when evolving an API design. Sometimes I write the test first, sometimes after, but when I change the API, and all the tests break, in fact, the tests don't even compile, it's a wonderful learning experience. In the beginning, the tests are a great place to experiment with both design and implementation; verification and validation. Sometimes I learn it's better to put white-box hooks into my main code, and I can turn integration tests into unit tests, and more directly to get at the nuanced behavior I am trying to understand. As far as BDD, I have found Cucumber too hard to integrate into my test framework, so often I simply document my test scenario with Given, When, Then in comments and/or 'println' statements to clarify my test thinking. On the other hand, in Scalatest, the spec framework is easier to use than full Cucumber. Some of the most important tests are exception handling tests. If people are not writing exception handling tests... well there's Murphey's Law...
@SteenSchutt
@SteenSchutt 2 жыл бұрын
It was quite obvious to me, when I first learned about testing, that you would ha e to break encapsulation and render the tests useless. For that reason I had largely discarded tests as pointless busy work, until a few years ago when decided to dig into TDD proper, and I found BDD which resonates really well with me.
@lightfeather9953
@lightfeather9953 2 жыл бұрын
How did testing break encapsulation? I'm really confused by this. I always assumed a test involves calling a public method and assert on the result.
@CanalDoFante
@CanalDoFante 2 жыл бұрын
@@lightfeather9953 I think he’s saying that he was doing wrong therefore thought it was bad as he needed to break encapsulation, now, he learned how to do it properly and understood that is not required
@danielferszt6521
@danielferszt6521 6 ай бұрын
Great content! I looking into TDD and BDD as a PM to figure out how to implement them in my team. We also have a lot of legacy code with no testing, and for that I find your videos about Approval Testing very interesting. The problem is how to implement all of this? I am thinking of starting directly with BDD using gherkin for new code, and approval testing for legacy code until we can refactor. I'd love to know what you think of this approach, or if I should just start with TDD with regular unit testing first?
@BryonLape
@BryonLape Жыл бұрын
On a project a few years ago, we used SpecFlow to do integration testing. On most stories, I spent more time writing code in C# to get SpecFlow to work than I did the actual C# code of the system.
@gonzalowaszczuk638
@gonzalowaszczuk638 2 жыл бұрын
It's good to separate the two concerns which are actually independent: testing, and user-level/behavior design. You can do both of these independently: - Only testing: Like mentioned in the video, you can always write tests after the code, or write them at any point. The only thing the test does is either fail or pass, and stand the test of time so you can run them at any point in the future to tell you this information of the future state of your code (if it makes the test pass or fail) - Only user-level/behavior design: You can use a REPL. You can load your code into your REPL and write down a single line of code for the simple case of how you expect the users of your code to call your code (or use your API). The REPL would fail, so you then write that code so the REPL can execute it correctly. Then do the same for a different usage of your API, write the user-level code that would call your API in the REPL, watch it fail, and write the code. Use the REPL to design your API by experimenting how a user would actually use your API. TDD/BDD just does both of the above at the same time. You can design your API, but the design stays still in time in the form of a test, a test you can run later. I believe the above makes TDD very useful, since you kill two birds with one stone. However, there can be cases where it's easier and simpler to to exploratory design with the REPL (or even a statically typed language and a compiler) rather than doing full tests. With tests you have to actually make sure the test passes, that you do proper setup, proper cleanup, and many more. If you only want to design your API and code, that could be too much complexity, in some cases. EDIT: One such case can be when dealing with legacy code that has no tests; you can still use BDD-style design for it, even if you can't afford to do tests for it right now! Also, there can be cases where you just want to create a test without designing code. You may have some test cases or edge cases which do not impact the design of your API at all, and yet you still need to test them. For example, the usual tests that validate inputs. Such test could easily be done after the whole design of your API (and even code) is already done; yes, it tests behavior, but it's behavior that does not impact your design at all, if you add that test after the code is implemented nothing changes, nothing breaks. It can be a good idea to disentangle both concepts and objectives and be aware of them, and use TDD when you acknowledge you need to do both at the same time, but always be mindful of the cases where you may need to do one and not the other.
@yash1152
@yash1152 Жыл бұрын
saving for myself please ignore REPL , TDD two birds
@friendlyfripptit2228
@friendlyfripptit2228 Жыл бұрын
even if I severely think the code design in the video and those unkillable design ideas (separation of concerns, loosely coupled, etc) are misunderstood and overused, I still use TDD and it helps with my designs in my own way. So it's not just to write those insane convoluted java patterns, it can help with most coding! thanks for the vid!
@Greenthum6
@Greenthum6 2 жыл бұрын
I have tried BDD with gherkin language once. After writing the first translation layer to map to an already existing test interface it felt all so wrong. Reading gherkin code still gives me headache because the test code underneath is usually terrible. I write enterprise level test automation code for living and arrange-act-assert pattern is all I need.
@randypatalinghug7909
@randypatalinghug7909 2 жыл бұрын
love it! well explained...
@MrCalyho
@MrCalyho 2 жыл бұрын
Almost everybody I speak to approaches TDD out of the 'mockists' approach. In other words test for implementation details instead of behaviour. The reason for this I think is the examples of most of the courses. I did a course with Ron Jeffries long time ago with the bowling ball game. This approach demonstrates the expanding and adding tests all the time as you add requirements which in part is a good demonstration but falls short of demonstrating the power of proper TDD. What it doesn't demonstrate is the legwork in depth that you can get if you follow the behaviour approach. As an example: Many modern apps is taking a value from a the backend/database/(any other source) and displaying it to the user like e.g. the user name. You start of with only one test displaying the user name at first just as a static text. You continue with adding the layers of getting this value(the username) from eventually the back end or database using only that one test. I think if we rethink how to present these workshops to the new programmers then we will already get quite far with eliminating the misunderstandings.
@jonaskoelker
@jonaskoelker Жыл бұрын
> Because the code already exists, it won't be very testable; it wasn't designed to be. My experience says otherwise. Is my experience non-representative? The code I write on a daily basis is written in a functional style, as far as possible, and with heavy use of dependency injection, especially of single-method interfaces (~= a sigle function pointer / a single first-class function). Let's say that a bit of code is functional if it only changes its own behavior and/or that of the rest of the system if it is given different arguments and/or yields a different return value. By this definition, functional code is testable by construction: there is no setup other than constructing the arguments you want to test with. A system that has side effects by calling another part of the system (or some basic library) is easily testable if that call goes through an interface: construct that system with a mock implementation of that interface in the test suite. It may help that I work on a mostly stateless system.
@rummanchowdhury3807
@rummanchowdhury3807 Жыл бұрын
Fantastic explanation exclamation mark
@chiro5533
@chiro5533 Жыл бұрын
Really for my, the combinetion between TDD, clean Architecture, clean code, and a good practices of unit test in my tdd tests, help me to create very very reliable and easy to change software, but you need a lot of discipline, and that's the key to undestarnd TDD its a discipline.
@farazsalehi9034
@farazsalehi9034 Жыл бұрын
very well explained 👏👏👏
@filipemonteiro1694
@filipemonteiro1694 Жыл бұрын
I find the AAA (Arrange, Act, Assert) pattern for unit tests super useful to improve readability (and that somewhat matches the Gherkin pattern Given, When, Then). Before that I struggled to write readable tests tbh.
@ThugLifeModafocah
@ThugLifeModafocah Жыл бұрын
Dave Astel, before Dan North, have an approach that later was put in RSpec and which is seems now forgotten, about the behavior approach for TDD. His article vanished from the internet, but I have it in my computer. Its name is something like: "A new look at Test Driven Development". Beautiful article. Another important point is to see Kent Beck article "Aim, Fire" to see that since forever TDD was intended to specify behaviors.
@conniedecinko9245
@conniedecinko9245 2 жыл бұрын
Love the shirt!
@mateuszszczecinski8241
@mateuszszczecinski8241 2 жыл бұрын
Thank you for inspiring materials. I will repeat my question from comment of another video. What is missing in almost all tutorials or examples about BDD/TDD is link between acceptance tests and technical tests, for modern, distributed systems. All materials show only how to write separately hight level acceptance test, and integration/unit tests on component/class level, usually for systems created in classical mvc design. I would like to ask, do you have preferable development process for modern, distributed systems, where ui is separate app (or even many apps), one feature could be implemented by many modules (or microservices), all components could be created by different developers/teams? Do think that classical outside in development still have sense? I mean: creating acceptance test, creating unit/integration test for ui app view, implementing ui feature (mocking beckend), creating test for api service, implementing api service, creating test for application core(mocking another modules or externals system, maybe database), creating test for provider modules, etc.., making acceptance test pass, repeating whole process for another test scenario for story or feature. During whole process, which could take many days, acceptance test in pipeline will fail. Do you prefer some kind of consumer driven contract testing, for example that frontend team specify tests for backend api, etc? Are there another approaches, which uses BDD/TDD techniques? I would be grateful for describing whole process.
@yash1152
@yash1152 Жыл бұрын
15:27 the foll part is gold
@PrimalCoder
@PrimalCoder 2 жыл бұрын
Hi Dave, thanks for a fantastic channel, sharing all your precious experience. Would you have any knowledge or experience on design by contract, and if so could you share your thoughts on it please? Thanks.
@ContinuousDelivery
@ContinuousDelivery 2 жыл бұрын
I think that TDD, where you write the test before you have any code, is a form of design by contract. The first step is to define the 'contract' through a test, and then you make assertions that demonstrate that the contract is met. It is not precisely the same, but I think that they are related.
@PrimalCoder
@PrimalCoder 2 жыл бұрын
@@ContinuousDelivery Thank you for your reply. I looked a bit into it, and on the eiffel youtube channel it is presented as BDD + TDD, they actually give a reference to one of your videos.
@Zeero3846
@Zeero3846 2 жыл бұрын
As a functional programmer, I found that unit tests can describe the contract of an interface where the types cannot.
@FranzAllanSee
@FranzAllanSee 2 жыл бұрын
As programmer, i find it easier to write tests if i make my code functional :) Even in his example, though there are mocks, the test is more functional than the open source sample. The sample test of open source code was very procedural in nature.
@juliankandlhofer7553
@juliankandlhofer7553 2 жыл бұрын
@@FranzAllanSee Exactly! That is what's great about "Given, When, Then". Even if the "Given" comes from a mocked dependency, the code feels like a pure fure function with a fixed input to output mapping.
@BosonCollider
@BosonCollider Жыл бұрын
That's because most programming languages don't have dependent types. See F* lang for an example of a language where types truly can describe things that only tests could do otherwise. For procedural equivalents, spec# was a very interesting microsoft product. Of course, giving a proof that your program satisfies a property can be harder (or easier) than writing a good test depending on context and on how good your tools are.
@andik70
@andik70 2 жыл бұрын
Here my suggestion for the next fad: VDD value driven development.
@kahnfatman
@kahnfatman 2 жыл бұрын
CDD - Code Driven Development IDD - Idea Driven Development DDT - no, this is pesticide.
@sujithsukumaran8689
@sujithsukumaran8689 2 жыл бұрын
@@kahnfatman LOL :d
@Parker8752
@Parker8752 Жыл бұрын
I always thought I was missing something in university when learning BDD; I legit couldn't tell the difference between it and TDD done properly (i.e. tests written before code) beyond the nature of the tests. Feels nice to be told that my first instinct (that it's basically the same thing) was actually right...
@ContinuousDelivery
@ContinuousDelivery Жыл бұрын
👍
@brianbutton6346
@brianbutton6346 2 жыл бұрын
If I ever meet you, you will be the first person I have met who can/does write tests first. I spent ten minutes trying to get my head around that and failed. In practice, that wouldn't work for the reasons I list below. I think the value most groups seek is protection against regressions. >New code change breaks existing feature< After your system reaches a degree of complexity, it is super hard to anticipate the - er - unexpected. I am honestly amazed at how sneaky unforeseen consequences can be. A good test suite could theoretically be enormously helpful there. I say 'theoretically' because the test suites I had the privilege to work with cost more than they helped. Builds take a forever and, when they fail, it is likely to be the test suite that needs changing. In the early days of feature development, rapid prototyping is invaluable. That susses out opinions from nosy product managers, tests technical feasibility, etc. "Do I use this utility or that one or should I write a custom tool?" "Ooops! Wrong direction. Start over." That stuff is hard enough without first writing tests. Anyway, my projects are UI intensive and the current one has a ton of outside factors. Examples include: Network behavior, browser behavior, format of user files, permutations of server arrangements. Having test coverage would be a good thing but there won't be much help from test tool packages.
@ContinuousDelivery
@ContinuousDelivery 2 жыл бұрын
I agree with you about the testing tools, I don't have much time for them, other that Unit
@nixonnelson5181
@nixonnelson5181 8 ай бұрын
I am a wanna be juniour game developer i am very interested in learning TDD and BDD and be better at It, and the explanation gives me a clear understanding of the qualities necessary in a TDD environment and what it actually means.
@ContinuousDelivery
@ContinuousDelivery 8 ай бұрын
I am pleased that you found it helpful. In case you haven't seen it I have a free TDD tutorial which you can find here: courses.cd.training/courses/tdd-tutorial
@scarminio
@scarminio 2 жыл бұрын
Dave, a quick question: lets say that I have a function that returns the performance of a machine. In the implementation, it calls a function that reads a table. By BDD, should I write tests for the expected performance, or should I write tests for that function also?
@paragkadam2169
@paragkadam2169 2 жыл бұрын
In my opinion you go outside - in, while writing the BDD test and even before completing it write the test for the function and then continue with your BDD test.
@Alanblumenmkt
@Alanblumenmkt 2 жыл бұрын
Hello, I really enjoy your videos and I'm learning a lot of CD. I would like to implement it in my company but I have a doubt. How do I implement CD for.embedded systems? Regards
@ContinuousDelivery
@ContinuousDelivery 2 жыл бұрын
CD is used a lot for embedded systems. The key is to do a lot of testing in simulation. I did a video on Tesla which talks about their approach, but there are a lot more examples than that. kzbin.info/www/bejne/kH66cp-Gh82crbs
@robertlenders8755
@robertlenders8755 2 жыл бұрын
Are you familiar with Domain-Driven Design (DDD) where you use the type system of the language to constrain the behaviour of code? I'm curious how this should interact with a TDD approach. If the type system makes invalid states or behaviour unrepresentable how would you go about writing a test for it?
@grrr_lef
@grrr_lef 2 жыл бұрын
I think in most cases, the type system is only an internal tool and not part of the behaviour but rather a tool to help with correct implementation. Let's consider the case where your team provides an HTTP API to the outside world. What's the behaviour you want to provide and guarantee to the outside world? It would be that GIVEN some conditions, WHEN a certain http request X is made, THEN Y will be the result. The type system of your implementation language is not relevant at this level. (( Sidenote: One case, where the type system could be relevant in terms of behaviour: A library in a specific language. In this case, you could test the type definitions implicitly by verifying that your library can be used in the indended way. (Technically you could do this by creating a docker container, install your library as a dependency and run all some code you want to enable in there.) Some languages like TS also allow tools to test the actual type definitions directly (This could be relevant, if your library provides generics or dependent types.) )) To sum this up in the DDD language: The behaviour in BDD is concerned with the domain/context level. The behaviour in "code behaviour relative to the type system of a choosen implementation language" is not part of this context. To rephrase it conversely, the DDD-domains/contexts and their behaviour do not rely on the choosen implementation language(s).)
@dtkedtyjrtyj
@dtkedtyjrtyj 2 жыл бұрын
The way _I_ understand it is that the mantra is "test everything that can do wrong". By using the type system to constrain the domain to only valid states, that is a whole category of things that _cannot_ go wrong, so it doesn't need testing. However, now that I think about it, it seems naive. Hopefully someone else will expand more.
@BittermanAndy
@BittermanAndy 2 жыл бұрын
I write tests after writing the code (can't get my head around doing it first) but my tests look very much like your TDD examples, not the bad example. I've said it before and I'll say it again: if the result is good, no-one should care how it got there. It's not anyone's business what order I do things in.
@paragkadam2169
@paragkadam2169 2 жыл бұрын
TDD is not just about writing tests first but about evolving the low level design of the system step by step as your tests evolve, hence design is at the heart of TDD and not the sequence of writing tests.
@BittermanAndy
@BittermanAndy 2 жыл бұрын
@@paragkadam2169 OK, so, I design and write code and evolve the design of the code and then when I think I'm satisfied I write unit tests to validate what I've done, making further changes if necessary. It works for me, I end up with good quality code and tests to prove its correctness, just like TDD promises. I wouldn't call what I do TDD though, and I don't think many others would either. Would you? AFAIK TDD literally says: write (or change) the tests first. Watch them fail. Write code to make the tests pass. That's what TDD is, every time I've ever heard it explained, and exactly what the TDD proponents say to do. It is absolutely about writing tests first.
@asdasddas100
@asdasddas100 2 жыл бұрын
Same
@alirezaRahmanikhalili
@alirezaRahmanikhalili Жыл бұрын
Good job
@blaiseutube
@blaiseutube Жыл бұрын
I love the quote from Alan Perliss, I knew Prof Perliss and I can imagine him saying that.
@ContinuousDelivery
@ContinuousDelivery Жыл бұрын
I do like the way that he thinks about software, from what I have read.
@elanalister1863
@elanalister1863 2 жыл бұрын
I've always thought on TDD as to test functionality (or behaviour) rather than unit testing. I'm still struggling on why the tests should be independant, while funtionalities are not. Is BDD addressing that?
@muhammadfathudzikriaulia8260
@muhammadfathudzikriaulia8260 2 жыл бұрын
well because its agile, the earlier you find bugs the better i think. therefore unit testing is more suitable in regards to this context
@eraclee
@eraclee 2 жыл бұрын
Did he say "Communist arguments" in 11:04 ?
@ContinuousDelivery
@ContinuousDelivery 2 жыл бұрын
🤣🤣 'Commonest”
@Sergio_Loureiro
@Sergio_Loureiro 2 жыл бұрын
If you had turned on captions...
@eraclee
@eraclee 2 жыл бұрын
@@Sergio_Loureiro r u against communist arguments? 🤣
@Sergio_Loureiro
@Sergio_Loureiro 2 жыл бұрын
I was just saying I saw the video with the captions turned on. As I am not a native English speaker, it helps when the spoken language is not intelligible to me.
@glhrmcosta91
@glhrmcosta91 2 жыл бұрын
Hi, Dave. One question, though: what about tests that use mocks? It seems to me that it is impossible to create "malleable" tests when using mocks. However, this is worth the price for the huge possibilities which mocking brings. Do mocks make maintaining tests harder, or is it an issue of how they are being used?
@ottorask7676
@ottorask7676 2 жыл бұрын
Mocks are great for design purposes when you're not 100% sure how a dependency could work. Once you've designed that dependency with mocks, you can replace the mock with the real thing or something that implements an interface the real thing implements as well. But to use mocks to "isolate" your code is foolish in my opinion, just use regular test doubles in those cases.
@glhrmcosta91
@glhrmcosta91 2 жыл бұрын
@@ottorask7676 I agree that using it to simply isolate is wasteful, but in my case, I mainly used it for fault injection. I work with Embedded Systems, and some situations are very tricky to test. For example, let's say I have a code that reads the converted voltage from an ADC. Using mocks I can force many error scenarios to ensure my error handling is robust. These mocks and the expectations are created based on the currently available interface, let's say AdcRead(int p1). However, somewhere down the line, a new requirement shows that that forces us to add a parameter to the previously used interface, which becomes AdcRead(int p1, int p2). Depending on how you are testing, this might implicate changes in several tests. I mean, this is unavoidable, but can we do something so the effort is reduced?
@ContinuousDelivery
@ContinuousDelivery 2 жыл бұрын
This approach works fine with mocks, if you notice the example that I give is using mocks. Mocks are problematic in that they make it too easy to live with bad design. I think that if your test is hard to write that is nearly always a problem with its design, not the test. So if your mocks are too tightly-coupled in your test, what that is really telling you is that your design is too tightly-coupled to the thing that you are mocking - so change the design.
@pchoudhary
@pchoudhary 9 ай бұрын
I was waiting, when will the sarcasm break 🤣
@loc4725
@loc4725 2 жыл бұрын
Yup, I've fallen into this trap as well (writing tests that make sure your code passes the tests). Behaviour driven is definitely a better approach.
@tiagodagostini
@tiagodagostini 2 жыл бұрын
That is the root of my whole problem with a practice that puts TEST as driving the development. Tests are important but are not the DRIVE factor or you deturpe the objective of your development. People start to skew the design just so they can get better Test coverage numbers and not solve the client problem in the best way.
@duckydude20
@duckydude20 2 жыл бұрын
i don't want to be that guy but what i understand is people failing to understand what TDD actually is. what it actually says. they never listened to it carefully. never paying attention just wanting to get the sweetness of it. tests should never rely on implementations. implementations should be encapsulated. tests shouldn't know if i am using hashmap or list or something else. doing tdd means asking right questions. like what i want from this code. how i want it to behave. and always thinking assert first... TDD by Examples by Kent Beck, is one of the best books which says these things again and again. i read only 5 books, but i read them line by line, repeating hundred times even a single line, each chapter multiple time till i get what the author is trying to understand. they are holy books for me. TDD is always about behavior. how else then you can write a test without knowing the implementation. i am thankful i got to know mentors like you, like kent, like martin, like steve, like nat, like james, in starting of my career. i am so thankful... else i would have gotten it wrong too... :) btw, gonna read CI/CD in the very near future, finding a deployment strategy they are a must...
@oussamaziani6422
@oussamaziani6422 2 жыл бұрын
You said Quality code have appropriate levels of coupling, we all agree with that, but it sounds a bit subjective how can you objectively identify what an appropriate level of coupling is and what an appropriate level of coupling is not.
@ContinuousDelivery
@ContinuousDelivery 2 жыл бұрын
Not easy to describe in a comment or a video, there is a whole chapter on this topic in my upcoming book though :)
@MarioVapenik
@MarioVapenik 2 жыл бұрын
There are two problems. First is, software systems evolve. They are long term runs. What was good for yesterday, is not good for tomorrow. You have to change structure, because you realise that your previous approach is not perspective. Second. On what level should tests be written? There are many levels of abstraction in systems. From the top most to the detailed one on the level of unit tests. Unit tests are not useful much. The higher level the more interesting the test is. But more complex and even more fragile then from the perspective of modifications of the model.
@ponypapa6785
@ponypapa6785 2 жыл бұрын
For the first problem: This exists no matter what way you test, as long as you write tests. In fact, the more the tests are coupled to the actual implementation details, the worse it gets, so writing tests from a behavioral perspective should reduce the problem. The only other way to avoid this is to ty and create the data structures directly with extensibility in mind. This can also fail, currently, I had to rip apart a REST-API I wrote as the initial specification that laid the foundation to it was miscommunicated, and all ideas presented were no longer viable. So a lot of work had to be done to change it. However, as I wrote all my tests behaviorally, I merely needed to change one part of the API layers, as the persisted data structures still contained the required data, so adopting the changes was relatively simple, as the behavioral tests merely needed to be modified to check the new properties on the new objects - the rest still remained as before and gave a lot of security during this modification process. For the second problem: basically, you want every "unit" tested. The problem is in defining, what a "unit" is. Depending on the object in question, it CAN be everything, from a single method (although that presents a whole lot of other problems) up to an entire DAO-structure requiring an embedded database. However, there is no strict need to test everything in isolation AND in joined tests. For example: Given a spring web project that uses jackson serialization to create JSON-Objects, it is likely that the default ObjectMapper is reconfigured to reflect the requirements of the projects code. While it is now possible to test the ObjectMapper in isolation (which will make it easier to reconfigure) this is not strictly necessary, as the configured objectMapper is also required to test the response conversion that happens when the controller is called to return the mapped objects. In this case, testing the object mapper in isolation binds the code to this specific implementation, while testing it "passively" along with the controller makes the tests less fragile, as they are no longer implementation dependent. The problem with this approach is, however, that changes within the library can lead to failing tests without giving clear indications as to why they fail. I bring this up to show that, despite being a good and loosely coupled solution, it is not perfect and will create other problems. Which brings me to my favorite answer to any given how to question. So, TL;DR: On what level should the tests be written? - It depends.
@dtkedtyjrtyj
@dtkedtyjrtyj 2 жыл бұрын
@@ponypapa6785 > On what level should the tests be written? - It depends. I have to disagree with that. It's not a coherent question, it is fundamentally the same as "On what level should the code be written?" All of them, obviously. If that means you have to throw away some tests when you throw away some code, that's fine, it's expected. The tests are part of the code so all you're doing is throwing away code when you throw away code.
@ottorask7676
@ottorask7676 2 жыл бұрын
Would you prefer attempt evolving a system that has no behavior verification whatsoever providing guard rails for refactoring, or would you deem a well tested code base a well evolvable one? And there are certain tests that are below unit tests in terms of abstraction level, they're called "implementation tests". ;)
@MarioVapenik
@MarioVapenik 2 жыл бұрын
@@dtkedtyjrtyj Then it is in contradiction with expression "such tests are implementation independent". If you have tests everywhere, they all are implementation coupled.
@dtkedtyjrtyj
@dtkedtyjrtyj 2 жыл бұрын
@@MarioVapenik No, they are behaviour coupled. If you delete code, you no longer need the behaviour. If you maintain the behaviour and change the code it's called "refactoring". I just realised it might not be clear that I mean that it is _only_ the api you test. Private things are private, you don't test those. Only the public api. (It is of course permissible to test private things; if it makes it easier to continue. But those aren't part of the _real_ test suite and you should refactor, alter or delete them.)
@JoseYesidBocanegraVasquez
@JoseYesidBocanegraVasquez 2 жыл бұрын
Thanks for your video, I've always thought that TDD is a great tool given to the wrong people. The assumption that a developer knows what it's doing is foolish. You can't have the responsibility of business success into developers. They know their craft and they are amassing at building software. But understanding a business and the reasons behind every decision is key to write valuable tests. BDD takes these assumptions to the frontline where business and value meet and real decisions can be made on the behavior of a given piece of software.
@AlainTrepanier
@AlainTrepanier Жыл бұрын
I prefer to thing it through, experimenting if needed, then I develop while considering how it will be tested. So, I don't really test first, I test as I see fit - no clear general rules.
@nickpll
@nickpll 11 ай бұрын
Hi Dave. I had a disagreement with my manager today about unit tests. He is saying we need to write individual unit tests for each function. When I said this is bad because it couples us to our design he responded by saying that on ad-hoc occasions admins remote into the prod apps and execute functions directly. Therefore, we need to validate that every function works in isolation for these cases. This strikes me as off since we will only execute a few select functions like this. What are your thoughts on this example?
@ContinuousDelivery
@ContinuousDelivery 11 ай бұрын
In general I think that you should test behaviours, not functions. Test for what the SW is supposed to do, not how it is implemented. I think it is bad to organise SW testing by function, but I would expect that every public function was tested as a side-effect of testing the visible behaviours of the code. If you have people accessing functions directly, I'd make sure that my design only exposed the functions that I was happy people calling directly, I'd make anything else, anytihgt that depended on specific sequences of actions for example, private, as far as I could.
@VladimirMinkin
@VladimirMinkin 2 жыл бұрын
You can write the same TDD as part of BDD. And could it be done vice versa?
@LarryRix
@LarryRix 2 жыл бұрын
Having Design-by-Contract removes much of the poor outcomes of "test after". Why? Because the "tests" (assertions) that are brought into the code by DbC are always about the "correctness" of the code they are attached to. They describe how a particular function or method is used in a correct manner by its Clients as a Supplier. Thus, the test code (DbC contracts) is not about your code so much as the relationship between your code as a Supplier function or method and the Client code that calls it. In this Client-Supplier code correctness viewpoint, we don't care about tight-coupling. Any Client can call any Supplier as long as the Client makes the call in a correct state for the needs of the Supplier and as long as the Supplier performs the work it does to the correctness rules of the Client (e.g. did my Supplier code meet the needs of my Client?). TDD without Design-by-Contract is trying to carry the water for DbC without being DbC. TDD cannot perform at the same level as DbC because it is not DbC. TDD is external Client-only and cannot reach inside. Moreover, a programmer stuck in just TDD is not trained to think in terms of Client-Supplier relationships and tends to be wholly ignorant of the relationship. So, as a result, the programmer is not guided into testing this relationship-merely the code. Only when Design-by-Contract is brought into the mix is the Client-Supplier relationship properly handled in the right way within the production code and NOW the TDD test code is simply there to exercise those relationships to see if everyone behaves properly according to the "correctness rules" of the Client-Supplier relationship! Therefore-much of the "test after" pitfalls and gotchas evaporate in the face of DbC + TDD + CI/CD. How this fits with BDD I will leave to you all to decide.
@diononeofyourbusiness8634
@diononeofyourbusiness8634 Жыл бұрын
Interesting. I have always strongly rejected unit testing. I never cared about code. What I wanted to see confirmed is that my software behaves correctly. So I would always only write integration tests, testing customer or stakeholder expectations of my software system directly.
@chiefxtrc
@chiefxtrc 2 жыл бұрын
At 12:23 you say the example displayed is testing behaviour and not implementation. However the assertions are verifying the interactions between the objects instead of verifying the resulting state of the objects. Does this not mean they focus on implementation instead of behaviour then? You ask how the code works to make those tests pass.Seems to me that you could guess something very close to what the actual implementation code looks like just from looking at the tests because the assertions mirror what the objects are expected to do. If you refactor the code you may break the tests if the interactions change, even if the behaviour doesn't change. What am I missing here?
@tongobong1
@tongobong1 7 ай бұрын
I also think his tests are terrible - too coupled with how system works and hard to read because of mocks.
@Pedritox0953
@Pedritox0953 2 жыл бұрын
Very interesting
@gabrielepividori9077
@gabrielepividori9077 22 күн бұрын
Regarding the poor design point, I have a question: how you come up with that design? Did you draw some diagrams before implementation? Or it "naturally" came out of the TDD process. Personally I found that "TDD" more often than not is not promoting any design like that, sometimes you feel you need to extract functionality somewhere else, for testability, but other patterns you need to enforce them upfront, either by doing early analysis or by prototyping the solution you are building.
@dtkedtyjrtyj
@dtkedtyjrtyj 2 жыл бұрын
"Test Driven _Development_"? To me it is supposed to be "design". In fact I thought the issue BDD was supposed to fix was the misinterpretation that the "Test" was the important bit, when it was the "Design" that actually provides utility. That's the way I do it anyway. I think of the next thing I want the code to do, write a test to put my _design_ into words and then implement that design.
@Kamel419
@Kamel419 2 жыл бұрын
as a test architect, what i would do to put that dam pickle back in its jar. people think as long as they halfway format acceptance criteria in gherkin format they are following all best practices.
@christopherboyle2403
@christopherboyle2403 2 жыл бұрын
Pretty much... Given Operator needs pictures for job. When they click the download button Then system returns what they need to do their job. This is syntactically correct and functionally useless to a development team. What is what they need? What are the pictures you speak of? From what page / interface are we talking? Where are you expecting this download button to appear? top / bottom / right menu pane / left menu pane / does it even matter as long as it is there? Is this supposed to be secure / Authorisation / Authentication (perhaps this is implied by context of project, sometimes so)? Either way I have seen many like this. With so much untold and if you have difficulty getting this information you wind up writing the solution first and then testing the solution. Thankfully there are more reasons to use dependency injection then just testing (polymorphic behaviour can be useful).
@berndeckenfels
@berndeckenfels Жыл бұрын
It’s strange that you use reflection to invoke the interface method (unless this was part of the test, which is not obvious)
@ContinuousDelivery
@ContinuousDelivery Жыл бұрын
That is the goal of the code that was being developed here. This is part of some service-mesh framework code that I wrote to support a reactive programming model that I am using. It uses an java interface as an interface description language to define a series of asynchronous messages. It communicates the messeages over pub-sub messaging, and then re-assembles them into function calls, into an automatically generated adaptor that result in a call to the same interface. The key here is that the interface is not part of this code, it doesn't exist at compile time, only at runtime, hence the need for reflection.
@lyingcat9022
@lyingcat9022 2 жыл бұрын
Fiiiiinally… a video where he mentions TDD. I thought he would never bring it up ;)
@ContinuousDelivery
@ContinuousDelivery 2 жыл бұрын
Ah, I see, you think I should talk about TDD more often 🤔…😉
@saritsotangkur2438
@saritsotangkur2438 Жыл бұрын
Tests first means API’s first which is why TDD makes it hard to refactor code. The reason why ppl think TDD is best is because they don’t go through the process of refactoring their code to be “quality code” and TDD forces some planning to occur at the beginning. However if one merely refactors code, API and all until it has all those properties of “quality code” before writing tests, the will find that the tests are just as easy to write. TDD is more of a crutch to get acceptable code out of less experienced coders, and like most crutches, over reliance on them keeps people from developing real strength.
@ContinuousDelivery
@ContinuousDelivery Жыл бұрын
I would argue exactly the opposite, though it is true that if you are good enough, then you can write code that is almost as good as that produced by a good dev using TDD. I taught a friend, who many regard as one of the world's best programmers, to do TDD. He, and I, now think that his code is better. I explain some of my reasons for this in this video: kzbin.info/www/bejne/op-XiKGujZKqqNk
@owensigurdson8610
@owensigurdson8610 Жыл бұрын
12:41 why are you using reflection to call the methods that you are trying to test?
@ContinuousDelivery
@ContinuousDelivery Жыл бұрын
I am not using reflection in the test, I am using reflection in the code that is being tested, because that is what the code does.
@logangraham2956
@logangraham2956 2 жыл бұрын
idk what my development would be called than because technically there really isn't a succeed state and there really isn't a fail state except for it crashing or hanging. but I would call it TDD because i write the code and than see if it works than i write some more code and see if it still works. and the trouble is you really can't write a test for this particular program because the test would have to be nearly infinitely long which doesn't make any sense to do.
@logangraham2956
@logangraham2956 2 жыл бұрын
so basically i'm doing test driven development but I am the test XD
@CodyEngelCodes
@CodyEngelCodes 2 жыл бұрын
I’m not surprised that the example of bad tests is from Jenkins. The project is a marvel but it seems to have fallen to the wayside for things like GitHub Actions and Circle CI.
@LimitedWard
@LimitedWard 2 жыл бұрын
Today I learned I'm already doing 90% of BDD/TDD, I just need to write my tests first.
@JackPinesBlacksmithing
@JackPinesBlacksmithing 2 жыл бұрын
I've been an advocate for BDD for a decade but have never found it in any organization I've worked in. Further, it's been nearly impossible to advocate for it due to an engrained UT or TDD focus.
@ContinuousDelivery
@ContinuousDelivery 2 жыл бұрын
Some of my clients do it, and most places that I used to work, but then I convinced them :D
@l0g1cb0mb
@l0g1cb0mb Жыл бұрын
I need a print of that T-shirt! XD
@BillWright
@BillWright Жыл бұрын
Seriously. Where can we get one of those shirts? A quick search didn't succeed for me. I need one!
@animanaut
@animanaut 2 жыл бұрын
I saw that you used Java’s reflections in order to be able to call methods on a class under test that have not been implemented yet. It always confused me when people just say „write tests first“ but in a semi strong typed language you at least have to have a stub method or extended interface „first“ in order to write a new test. So in your opinion reflections are the solution? Many devs don’t look too kindly on them and view them as cheats to bypass the type system.
@animanaut
@animanaut 2 жыл бұрын
follow up question: once the initial implementation is in place wouldn‘t you want to replace it with the actual, more strongly typed, method call? Imagine a refactoring where you just clean up the wording but not behaviour . This test would break, not because the behaviour changed but a methodname.
@MTonik
@MTonik 2 жыл бұрын
IMAO, the convoluted test for Jenkins is still better than no auto-tests at all. If nothing else, it would still help detecting breaking changes in the pipeline.
@ContinuousDelivery
@ContinuousDelivery 2 жыл бұрын
Yes it is better than no tests, but fails by development grinding to a halt because you can't change the code without changing the tests, meaning that the tests don't provide any protection for changing the code, but the code will be working, which it won't be, usually, without any tests at all.
@nareshtank7430
@nareshtank7430 11 ай бұрын
If I am exclusively writing REST APIs, how can I define the expected behavior for acceptance testing without actual human users, given that my APIs are consumed by a single-page application built with React.
@ContinuousDelivery
@ContinuousDelivery 11 ай бұрын
The people writing the code that uses your API are your users. That is the perspective that you should test from. In your case, the UI for your code is its API. The point here is to test from their perspective, not from yours. Don't test stuff from the perspective of knowing how the internals work, test it as a black box, from the perspective of an API user carrying the kind of task that they would want to perform. If your API is nasty to use, you will find out this way, but not if your goal is to white-box test from the perspective of you the creator.
@ArkhKGB
@ArkhKGB Жыл бұрын
It's not about tests, it's about specification: instant like.
@yash1152
@yash1152 Жыл бұрын
0:43 the logo is super similar to logo of "Captain Disillusion"
@ContinuousDelivery
@ContinuousDelivery Жыл бұрын
Or is just made up of "C" and "D" in both cases 😉I had my logo before I was aware of the Captain, so a case of convergent evolution rather than plagiarism.
@yash1152
@yash1152 Жыл бұрын
@@ContinuousDelivery hehe
@petebrown6356
@petebrown6356 2 жыл бұрын
Biggest failure is almost always poorly written requirements/specifications. Identifying appropriate levels of abstractions is key in the design, making sure (as you do) that functions are small and reference interfaces, not specific (class) implementations. Accomplishing these greatly helps in having effective test cases. You can tell well structured code by seeing the abstractions and the size of functions.
@lepidoptera9337
@lepidoptera9337 2 жыл бұрын
Do yourself a favor and write down well written documentation/specifications for a piece of software called "web browser". When you realize that you can't, then have a drink or two or three, get a good night full of sleep and wake up with a new, deep insight into reality the next morning.
@petebrown6356
@petebrown6356 2 жыл бұрын
@@lepidoptera9337 you've obviously never written software involving functional safety. You'd better have complete and well written requirements that trace both ways to the code that implements them, including multiple tests per requirement. So sorry, that is reality...
@lepidoptera9337
@lepidoptera9337 2 жыл бұрын
@@petebrown6356 So, please, write down the exact kind of documentation that you require for a browser. I dare you. Not for my sake. I already know that it is impossible, but for yours. I am not saying that it's impossible to write exact requirements for _some_ code. The embedded software that I am writing right now has a couple hundred completely orthogonal functions, all of which do some very specific things in a very specific order, which is ensured by hardware interrupts. The thing is... I don't even need specifications for this code. It's a single developer project, the functionality is fluid because I am the designer of the hardware and I determine which function the software will have. If something turns out to be too hard to implement, I will simply remove it from the list of wants and the customer who buys the product will never know that such a function could even have existed. The control flow will be correct by design (it's a state machine) and all memory is allocated statically, hence I don't have to worry about little buggy things like buffer overflows. This is exactly the kind of software that one could fully specify and test. But why in the world would one? Whether a single function works or not can be tested by hand at the time of writing. That's it. Now, your web browser OTOH... that's a totally different beast. Anybody can kill that thing with a piece of crappy javascript that calculates pi to the power of e to a trillion decimal places and there is absolutely _nothing_ that your requirements document and test suite can do about that. Javascript is a requirement and it happens to be a Turing complete language, hence you are up against the halt problem. I would suggest you take a few lessons in computer science before you make claims like the ones you made. They don't reflect well on you. :-)
@jlouzado
@jlouzado 2 жыл бұрын
Is there a recommended way to get started with BDD?
@michaelrstover
@michaelrstover 2 жыл бұрын
Write a test for behavior that doesn't yet exist. Assert the behavior does what it's supposed to do. Run the test and see it fail on that assertion.
@tylerkropp4380
@tylerkropp4380 2 жыл бұрын
You can take it to the extreme: - Create a new test - See that it fails to compile (for the reason you expect) - Make it compile - See that the test fails (for the reason you expect) - Make the test succeed - Refactor if necessary - If tests fail, fix tests or undo changes
@mondovicium
@mondovicium 2 жыл бұрын
The code base I've been working on for the last ten years sort of Works, but otherwise fails all the Good Quality Code principles quite miserably. I do what I can, but the code base was twenty years old when I arrived, and naturally we aren't given the resources to clean it up.
@ContinuousDelivery
@ContinuousDelivery 2 жыл бұрын
I like the "boy-scout rule", always leave the codebase in a bit better state after every change. That adds up over time. Take the "resources to clean it up" make it a small tax on every change.
@shavais33
@shavais33 Жыл бұрын
Let's say you're one guy working on a personal project, like a video game. Let's say as part of that game, you create something like an inventory system. Now, you can write (and later maintain) a whole bunch of code that tests whether or not that inventory system works, or you can just run the program and try it out as a user and just see if it works. Which is easier? Which takes less time? Which is less apt to break and require a bunch of time to fix? Now, let's say you're on a team and you're working on a very large and constantly changing business application used by hundreds of users employed by the company that employs you. You can create and constantly maintain a whole bunch of code that tests everything, or you can just try it out in a development/test environment and see if it seems to be working the way its supposed to, and then hand it off to a QA team that puts the system through a bunch of automated regression tests which They create and maintain that actually go in as a user and try everything out and make sure all the expected results appear. Which is easier? Which takes less time? Which is less apt to break and require a bunch of time to fix? I've tried writing code to test systems I create and maintain in quite a few different circumstances using various approaches, and I am not convinced that writing and maintaining code to test things is anywhere near worth the cost of doing it, unless you're talking about scripts that act like a user of the system, and then only when the system gets large enough that automated regression tests are substantially faster than just manual tests. And I think the point at which that happens, the point at which a project is large enough for automated tests to be worth creating and maintaining, is when the project is large enough to have a dedicated QA team that does that.
@shavais33
@shavais33 Жыл бұрын
Now, that said, I absolutely agree that creating modular systems with clear, minimized, documented interfaces, is critically important. Then when I'm debugging, I can step and trace through those interfaces to see what's going wrong.
@ContinuousDelivery
@ContinuousDelivery Жыл бұрын
I think that you are making a mistake that is common to people who haven't tried TDD, and that is completely understandable mistake... TDD isn't primarily about testing! It's understandable that people think of it that way, because "Test" is in the name. A few of us tried to change that by creating "BDD" which is better, but confuses people in a different way. In exactly the scenario that you describe, working along on my own projects, I practice TDD. That's because it is how I design best. TDD applies a pressure on you to write your code outside-in. You develop it always from the perspective of a user of that code, a person, or often, more likely, some other piece of code. This focus results in better code, in specific, technical ways of measuring quality. The result of this is that you produce better-designed systems, and better-designed systems are easier to work on so that you go A LOT FASTER not slower. TDD isn't a cost, it is an investment in building better software faster.
@shavais33
@shavais33 Жыл бұрын
@@ContinuousDelivery TDD isn't about testing? I'm making a mistake in thinking that TDD involves writing coded tests? I haven't tried TDD? I've read the material, it certainly clearly and definitely says to write tests that fail and then write the code that makes them pass? I have tried doing that? I do remember it talking about designing the interfaces first that you're going to test before writing the tests or the code behind those interfaces. I do actually still do that even though I don't write coded tests anymore, because I have found that doing that helps clearly define what I'm aiming at and makes it easier to hit that target. And it also.. kind of creates a sort of sandbox space where I can iterate and refactor the underlying interfaces until I think I have a sort of optimal set of fairly minimized pieces that can do "things like" what is being facilitated by the interface, which I would agree definitely increases productivity. If I'm writing in C++ (which is what I currently use, for the most part), I actually write out an English paragraph that describes what the piece of work I'm about to do needs to accomplish, and then I break that paragraph into a hierarchical list of bullet points and then I iterate over the bullet point list until I have what amounts to a kind of pseudo code that I believe takes everything into account - it does describe how the consumer(s) of the piece(s) of machinery that I'm about to build see(s) things. Once I'm convinced that my bullet list accomplishes the requirements, I come up with a set of interfaces for classes, that can together accomplish that bullet list, that each attempt to be as generic and small and simple and decoupled as possible and are designed to be able to do "things like" that bullet list without being too "gold plated." I may iterate over those header files (coded interface descriptions) a fair bit before I write any implementation code at all. (re: "gold plating" - I think there's an inverse exponential value vs time curve there that is rapidly asymptotic, or might as well be asymptotic. It pays to go some distance toward being able to do "things like" what you're being called upon to do, without going too far.) I think my process is actually fairly similar to that described in the TDD material that I've read, that I remember, except that I just don't take the time to write or maintain coded tests. (Well, at least not in C++ and not immediately alongside the app or library code.)
@shavais33
@shavais33 Жыл бұрын
And now, having written all that, I just found myself writing a bunch of coded tests. Because I'm doing some work in vc# and there is this nice, easy, super convenient TestExplorer, and I want to make sure the components I'm writing work before I use them. And.. it's convenient to write coded tests to do various experiments to see if the libraries I'm using can be used the way I think they can. Ok, so now you have me looking at TDD all over again once again...
Requirement Specification vs User Stories
17:34
Continuous Delivery
Рет қаралды 72 М.
TDD Is A BROKEN Practice
18:02
Continuous Delivery
Рет қаралды 6 М.
How to open a can? 🤪 lifehack
00:25
Mr.Clabik - Friends
Рет қаралды 3,6 МЛН
M3GAN’s ARMY got my finger! 😱🦾 #shorts
00:10
Adam B
Рет қаралды 19 МЛН
Which one will take more 😉
00:27
Polar
Рет қаралды 36 МЛН
When Behaviour Driven Development Goes WRONG!
15:18
Continuous Delivery
Рет қаралды 21 М.
"Non-Functional Requirements" Are STUPID
15:10
Continuous Delivery
Рет қаралды 41 М.
Test-Driven Development // Fun TDD Introduction with JavaScript
12:55
Are You Chicago Or London When It Comes To TDD?
18:58
Continuous Delivery
Рет қаралды 30 М.
Avoid These Common Mistakes Junior Developers Make!
17:54
Continuous Delivery
Рет қаралды 156 М.
What All New Software Developers Need To Know
27:46
Continuous Delivery
Рет қаралды 131 М.
Thoughts About Unit Testing | Prime Reacts
11:21
ThePrimeTime
Рет қаралды 199 М.
Jim Coplien and Bob Martin Debate TDD
20:59
toalexsmail
Рет қаралды 156 М.
iPhone 19?
0:16
ARGEN
Рет қаралды 4,1 МЛН
Секретная функция ютуба 😱🐍 #shorts
0:14
Владислав Шудейко
Рет қаралды 2 МЛН
Start from 0 at any point on the T1 Digital Tape Measure
0:14
REEKON Tools
Рет қаралды 18 МЛН
All New Atlas | Boston Dynamics
0:40
Boston Dynamics
Рет қаралды 5 МЛН
Нужен ли робот пылесос?
0:54
Катя и Лайфхаки
Рет қаралды 834 М.
🤯Самая КРУТАЯ Функция #shorts
0:58
YOLODROID
Рет қаралды 1,7 МЛН