Behavior Driven Development vs Unit Testing

Поділитися
Вставка
  • Опубліковано 9 лют 2025

КОМЕНТАРІ • 68

  • @krishnakrmahto97
    @krishnakrmahto97 2 роки тому +1

    Could you please give an end-to-end example where in we would write a BDD scenario to specify what the system we are building does and then write TDD tests when we start implementing the behaviour? From some of the other videos from your channel, I understood that BDD is just a way to think about/organize a test/scenario that we are writing code for - so BDD and TDD are two different things in the sense that BDD allows you to do TDD efficiently and with the right mindset.
    This video confused me a bit - it appears as if BDD is done before you start TDD, they are two different stages where in TDD comes after BDD.
    Please forgive me if I have fallen into some kind of stupid confusion,

  • @MrAnandml
    @MrAnandml 3 роки тому +3

    This channel is Gold ..

  • @marna_li
    @marna_li 3 роки тому +6

    I have been thinking a lot about it. As developers, we get to code-centric sometimes. We either treat out program as fetching or storing data, while our clients see it in terms of behavior. I would love to be more behavior-centric, and I’m constantly working on it. However, it requires that you are committed to it by applying certain structures from the beginning of a project. I have found that using CQRS is a good way to reason about software.

    • @BboyKeny
      @BboyKeny 3 роки тому

      Aside from synchronizing language of all stakeholders with the development of the product/software.
      I also think there is a desperate need for a software development map like the channel Domain of Science.
      Just a big overview of all the different paradigms, philosophies, patterns, domains, languages, code standards etc.
      This would stop many needless discussions of what is better than what. The use-cases would be quickly identifiable and comparable
      It would also show blind spots of the field since programming as a craft isn't nearly fully explored.

  • @bryanfinster7978
    @bryanfinster7978 4 роки тому +11

    Awesome as always. Made me LOL. "Test all the F***ing time!". People optimizing for reducing keystrokes drive me crazy.

    • @ContinuousDelivery
      @ContinuousDelivery  4 роки тому +7

      Thanks! The optimising to limit typing is a real (and dumb) thing in our industry.

    • @fenegroni
      @fenegroni 3 роки тому

      I noticed the biggest obstacle to overcome is unlearning a process and learning another. In Go TDD is very easy and natural. The built in tool is simple. there’s support for mocking through GoMock, but I’m still looking for a decent BDD tool.
      Having said that, I now have a less religious approach to the problem: especially since I do TDD and mocking in embedded systems, I now prefer the mantra ‘better to have one test in red, than 100 green tests’ I don’t care so much for how small or big the SUT is, I don’t care much whether it’s expressed in BDD or uses mocks, what I care is that I have a correctly written test, that is red. That by itself is enough to get started. Don’t get me wrong, I don’t think that means ‘job done’ on the testing front, but it means I took enough care to prove that I haven’t finished yet. Once that’s achieved, it’s easier to embark on the rest of the testing journey. I basically adopt a TDD-ish approach: can I prove there’s still work to be done?

    • @ponypapa6785
      @ponypapa6785 3 роки тому

      I optimize to reduce keystrokes ALL THE TIME. Best example: to avoid constantly having to manually type "import org.junit.Test; @Test public void should[behaviorHere] throws Exception{}" i have a shortcut that does all that for me. The same goes for setup methods, extracting local variables... =)
      (note: I am well aware that that is not what this is about. I'm just adding the "well, technically" part to this argument :D)

    • @fenegroni
      @fenegroni 3 роки тому

      @@ponypapa6785 IntelliJ based editors already do that for you. And many others.

    • @ponypapa6785
      @ponypapa6785 3 роки тому +1

      @@fenegroni yes. basically *all* IDEs and text editors allow that. That is the point. However, seeing as how many developers are *not* using these shortcuts, I find this point is necessary to be made.

  • @gruttewibe76
    @gruttewibe76 3 роки тому +7

    I agree we should not optimize for least typing, but when writing tests we should also watch out for being too exhaustive with our scenarios. Everything we build (including automated tests) goes in our backpack. We have to carry it around, so we need to be sure it adds value. A test suite, also a BDD one, should have carefully selected test scenarios. We need to watch out for combinatorial explosion. The more scenarios you have, the less care people will take to review them, because a big set will start to become overwhelming to read/maintain. And indeed having too many scenarios can also slow down test execution.

    • @luisrueda6109
      @luisrueda6109 2 місяці тому

      @@gruttewibe76 I also don’t agree with the video. You slave said it more politely than I would have.

  • @blankvoidsea
    @blankvoidsea 3 роки тому

    Never pressed the Subscribe button so fast AND without regrets (notice the caps). Thank you, Dave, you explain everything very elegantly and understandably, keep sharing them knowledge. :)

  • @tadwimmer6225
    @tadwimmer6225 2 роки тому +1

    Reminds me of helping my father-in-law build a railing around a staircase opening in his deck. The ruler and tape-measure defined the specification for spacing the verticals. He measured and placed the first couple, but found it very frustrating. I "refactored" the process by suggesting that we fashion a spacer from a piece of scrap lumber. Things went much more smoothly after that. I have often found that the refactoring process, when done correctly, can lead to duplication in tests if, for no other reason, the refactoring makes the code more DRY. An example of this, I recently needed to write apply, add, get, update, and delete methods for an object model with several different classes. The tests initially verified that the API was called with the correct URI and the correct JSON payload or other parameters for each object. As I refactored, I realized that I could determine the URI from a map, and the payload from an instance method on the object. I may have had multiple different tests exercising the same code, but each test had a slightly different spec. But testing this code uses mocks to avoid making the actual API calls for each test, so I have a functional/integration test to make sure that I'm actually calling the real API.

  •  3 роки тому

    This video answer exactly the question I currently have.
    A few days ago, I think we should write the BDD test only and try to work that way. But I just feel right to write unit tests. It is basically a bunch of duplicated tests and that makes me feels something wrong. Now I understand that it's ok to go that way, as long as it makes people easier understand what's going on.
    Thank you so much for the explanation.

    • @maurojuarez7679
      @maurojuarez7679 3 роки тому +1

      The best way to sell/visualize is by mapping the test activities in the test agile quadrant, there you will see is inevitable to have some test duplication but also that each duplicate test is focused in a different layer/stakeholder

  • @danielschulz7391
    @danielschulz7391 4 роки тому +21

    I would love to have these luxury problems. In the company I work for, there is no testing at all (besides someone clicking around in the UI).
    It's a real pain in the ass xD

    • @ContinuousDelivery
      @ContinuousDelivery  4 роки тому +7

      Yes, a pain, and low-quality, inefficient and expensive - sigh!
      Good luck, and I hope that you get to change their minds.

    • @someguy3176
      @someguy3176 3 роки тому +9

      Unit test anyway. Wait for them to challenge you on it.

    • @adamgardner9421
      @adamgardner9421 3 роки тому +3

      Do we work at the same place? Lol 😓

    • @KeyboardKrieger
      @KeyboardKrieger 3 роки тому +6

      @@adamgardner9421 I did what every responsible employee should do, I switched the company ;)

    • @antoruby
      @antoruby 3 роки тому +3

      @@someguy3176 That's the deal. What I write, I test. You know, given the time constraints. The others will follow. Otherwise, @KeyboardKrieger has the answer.

  • @zpinacz
    @zpinacz 3 роки тому +1

    Great video, please post more on testing if possoble ! Love the very practical and meritoric approach of yours in the videos.

  • @dev_taco
    @dev_taco 3 роки тому +2

    Great video 👏 I really do have to learn how to test better.

  • @josefd8
    @josefd8 8 місяців тому

    I can see this is an "old" video but I hope someone could help me to understand. Here, Dave said that you write your BDD specification and then slowly build your code to meet this requirement with TDD. The thing is, that it may take time for the BDD requirement to fully pass, so, if you're working on small increments (as you should), shouldn't this be a problem for CI? you commit your set of small changes to verify your changes are working alongside everyone else changes, but during that time, the requirement is not completely fulfilled and you will have a failing test in your pipeline. Am I missing something?

  • @eligolin9947
    @eligolin9947 3 роки тому +3

    My personal problem with TDD in regarding to 3 rules that "Bob" has defined (and I qoute -
    "1. You must write a failing test before you write any production code.
    2. You must not write more of a test than is sufficient to fail, or fail to compile.
    3.You must not write more production code than is sufficient to make the currently failing test pass."), is rule #1.
    My problem with it is that it has an implicit assumption that the api you desire to implement is known to you.
    In my case I find it usually hard to grasp the desired api (even the initial one) before starting coding.
    In my case the old saying "coding is designing" is ultimately true throughout my work.
    Now.. the strange consequence of this is that if I want to adhere to TDD rules I have to spend tedious hours with paper and pencil just not to violate an non intuitive rule #1 ( which without, I admit no TDD is possible by definition) , while if I were playing with the code, I would come up with the initial api in 10/15 min.
    The second problem I have with TDD is that if you're out of cycle (wrote some code and the test afterwards, just to get you started) you can not easily get back into the TDD cycle since your whole natural way of progressing becomes just the opposite.

    • @ContinuousDelivery
      @ContinuousDelivery  3 роки тому +3

      Well, I see it completely the other way around. If I write the test first, it focusses me on what I have to learn. The key here is to focus the tests on a "desirable behaviour of the system". If you are writing code that talks to an API, you don't want to surface that API, you want to hide it. What should the code do, how would you tell?

    • @ponypapa6785
      @ponypapa6785 3 роки тому +5

      Bob also says "it is perfectly valid to play around with the code to find out what you need to do. This can be done either by writing learning tests, or by actively playing around with it. If you play around and find a way to do something, then it is important to discard the work you have done and *then* drive it via tests .because then you know what you want to do"
      so basically: do play around, but only use TDD for production changes that will get pushed

    • @yurko-kun
      @yurko-kun 3 роки тому

      There is a misconception that I also had about it. You don’t write tests against API, because API may change and tests will follow. Nobody wants to rewrite tests. You should write tests against business requirements. There is a good 1h talk about where it all went wrong with TDD
      ua-cam.com/video/EZ05e7EMOLM/v-deo.html

  • @HoD999x
    @HoD999x 3 роки тому +1

    i always try to maximize for two things:
    coverage (how much logic does a single test cover, more is better)
    *which makes sense only when combined with*
    feedback usefulness (in case of failure, do i know what's wrong or do i have to invest time to figure it out. obviously, knowing is better)
    the priority is feedback usefulness.
    for example, imagine i have 10000 LOC for an encryption or compression algorithm. there are 500 functions i could test, a bazillion of cases, but do i really need that? if my requirement is "it works", and it does, and a single test proves it by using complex input, then all my tests needs to do is to zip a bunch of files and unzip them again.
    yes, every single line can break, but if i run my simple test after each change, i always know which change broke the logic. no need for 500 individual tests to know which function broke - because i can only be the one i modified.

    • @tiagodagostini
      @tiagodagostini 3 роки тому +1

      The thing I often not be used enough is hierarchical test. In your example you can have a few tests that if they pass everything works. Only if they fail the more detailed tests need to be run (automatically) to find where. Before anyone screams with me.. real world is not always web development, there are systems where some tests take HOURS because they operate over a Terabyte of data each time. It is important to not waste time and server costs to run something that is not needed.

  • @synaesmedia
    @synaesmedia 3 роки тому +1

    Hmmm ... well more tests aren't "waste". But they are redundancy.
    The tests / specs are part of your code-base and surely DRY principles should apply there too.
    What happens when you come to evolve your system? The first thing you want to do is change your tests to reflect the new changed requirements. But if you have a huge amount of redundancy in your tests/specs then a) it will be more work to change them. but b) more importantly, there's a danger of getting inconsistencies within your test/spec suite ... as different tests are asking the code to do inconsistent things. And you might find yourself desperately trying to figure out why your code "isn't working", while in fact, it's impossible for the code to be working, while inconsistent tests are demanding different things from it.
    Of course, inevitably multiple tests / specs will cover the same functionality of the code. And there's always some scope for test inconsistency. But I don't think it's something to be blasé about. I think you should aim as far as possible for a smaller set of orthogonal tests that still cover everything, rather than a huge rambling test suite full of old, redundant extra tests.

  • @alirezaRahmanikhalili
    @alirezaRahmanikhalili 2 роки тому

    Awsome man

  • @yossiyaari3760
    @yossiyaari3760 3 роки тому

    since I'm a software engineer and do some woodworking as a hobby, I would say the tape measure and ruler example is not fair.
    When milling wood, you need to resize a board and end up with a smooth and flat board.
    using the correct tools, in the correct order is important. as is minimizing the time spent using each tool and moving from step to step. wasted wood, and wasted time, are important.
    this is true of testing as well.
    we had a case where black box tests were used to run too many variations of scenarios, exercising logic branches deep in the business logic. it was wasteful, redundant, and caused more work when the requirements changed.

    • @ContinuousDelivery
      @ContinuousDelivery  3 роки тому +1

      I think that that is what the example says, almost exactly - or at least that is what I meant to say with that example. "Use the correct tools in the correct order" and in testing 'black box functional tests don't serve as a replacement for good unit tests".

  • @tddtv
    @tddtv 5 днів тому

    Your lower level tests also need to speak behavior, not implementation. It's not just your highest level tests. You could use Gherkin even lower, or just write test names in well written prose, either way, ALL your tests should speak domain, even lower level tests. Your lower level unit tests should still speak behavior, not 'someMethod' in the test name where that's an implementation detail that could change anyway. Don't put implementation details in your method names in ANY layer.

  • @Axesurvey
    @Axesurvey 4 роки тому

    Great video as usual! Mostly I see a need to have a test structure to optimize, especially for big organization, something like test level concept (unit, integration, system, acceptance, terms from istqb?), with BDD introduced, what is your view of this test level concepts, should they be updated or there should be a new way to describe test structure?

    • @ContinuousDelivery
      @ContinuousDelivery  4 роки тому +6

      I find it helpful to think about this from two angles:
      1) What does it take for you to feel ready to release?
      2) How long does it take to get that confidence?
      I am then going to optimise for those two things, speed & confidence. I advise people to divide their deployment pipeline into, effectively, two stages, a fast-feedback stage and a higher-confidence stage.
      You want developer-focussed feedback in the fast stage, I generally advise people to aim for tests that can give about 80% confidence that if they all pass, every other kind of test will be fine, and also pass. The aim is to achieve that 80% confidence in the shortest time possible, I advise in under 5 minutes.
      That immediately rules out some kinds of tests, most of these tests, tests that can run really fast, but give high confidence, are going to be unit tests - best created via TDD.
      Then you need to do whatever else it takes to improve your confidence to the point where you are comfortable to release - Acceptance tests, Perf tests, Security tests - whatever. These will take longer to run, so we run them after the commit-stage (fast-cycle) tests.
      The last nuance, that this video describes, is to use the Acceptance Tests (BDD scenarios) to capture the behavioural intent of the change so that you can use that as an "Executable specification" to guide your lower-level testing, and so the development of your features.
      There are several other videos on the channel that explore these ideas in more depth, looking at some of the different kinds of testing.

    • @Axesurvey
      @Axesurvey 4 роки тому +1

      @@ContinuousDelivery Indeed! And a very good point that "fast-feedback stage" should also aim for developers, in my organization, we also have similar "fast-feedback stage (gating loops)" and "higher-confidence stage (Release assessment loops)" concept, but they are mainly considered as means to support different release levels/requirements (bare minimal and other higher requirement customers). This (sometimes) leads to "bare-minimal" is not really "fast-feedback" since it only defines from customer angle.
      Thanks for the explaination!

  • @researchandbuild1751
    @researchandbuild1751 3 роки тому

    Wny do we waste time running unit tests on code that hasnt changed?

    • @martinbakker7615
      @martinbakker7615 3 роки тому

      Because the code might use code that has changed?

    • @researchandbuild1751
      @researchandbuild1751 3 роки тому

      @@martinbakker7615 a unit test doesnt interact with the outside world it only tests itself and everything else gets mocked

  • @workn4evr
    @workn4evr 3 роки тому

    Before asking the Us vs. Them question, you have to compare equivalent concepts. BDD vs. UT is a false equivalency because BDD is a collaboration framework that drives toward better testing. BDD is having a hard enough time gaining traction with the business, vis a vis IT, without muddying the waters further. Also, WE (as individuals) never write BDD specs in isolation. So, your description starts with a false premise, "When should you write a BDD specification and when a Unit Test?." The answer NEVER because they are not the binary answer to a testing question.

  • @LarryRix
    @LarryRix 3 роки тому

    GivenWhenTheWithStyle has a typo. :-)
    Video editor needs a unit test.

    • @PMA65537
      @PMA65537 3 роки тому +1

      6:35 not the only typo

  • @MarcusPereiraRJ
    @MarcusPereiraRJ 3 роки тому +1

    Hi, I've been watching your videos (and I am enjoying a lot). However, I must say you publish some typos that seem to be sloppy or some kind of disorder. Please take it as a constructive criticism, because people sometimes link this carelessness with low-quality content.

  • @kennethgee2004
    @kennethgee2004 Рік тому

    This should not even be a thing. whatever is driving the development should always including testing. Testing always includes behavior. Both include program structure. This is not a fight for the best paradigm, but how all paradigms can work together to form a solution to a roadmap and finished product. It is the same when using SOLID or Gang of Four concepts in functional design. Just because an idea starts in one place does not man that elements cannot be used else where. The best fit of an idea should always win no matter which paradigm it comes from.

  • @gronkymug2590
    @gronkymug2590 2 роки тому

    Wonderful video as always. Thank you!
    I also really like below video of Ian Cooper's panel. I like how he thinks about unit testing. It is the kind of thinking which I usually use. Though I also do more granular unit tests for single classes when there is a great number of combination of test cases required to test something (and 0, 1, multiple is not enough).
    I wonder if you have watched it and what you think about the way of writing unit tests proposed there?
    ua-cam.com/video/EZ05e7EMOLM/v-deo.html
    BTW, unit tests of the hexagonal application core in BDD style described there would be very similar to acceptance tests with concrete adapters attached (or exactly the same if we just changed the implementation of the tests' DSL slightly to use real driving adapter and driven adapters). So for hexagonal architecture it looks like BDD tests usually do not need to be repeated but instead their DSL should be a bit different for unit and acceptance tests, while everything else would stay the same.
    Some good thoughtful video about this would be useful as I am quite sure I still don't understand a lot of things related to these tests types (acceptance vs unit).

  • @WesFanMan
    @WesFanMan 3 роки тому

    A carpenter will use the proper tool to do the work once. For example, he wouldn't make three joists and only need one.

  • @enokoner
    @enokoner 3 роки тому

    They are tools. But building and maintaining those tools come at no cost? The carpentry analogy is false because carpenters dont also build their tools.

  • @oldcountryman2795
    @oldcountryman2795 3 роки тому

    You can't write useful unit tests for complex business processes, and if you try you'll waste a lot of time you should be spending on creating shippable product. When the mechanic replaces the brakes in your car he doesn't write a unit test, he drive the car and makes sure it stops when the brakes are applied.

    • @Geza_Molnar_
      @Geza_Molnar_ 3 роки тому +1

      Are you sure the mechanic does not go through some (unit) tests before they start the engine to drive around?
      What if the 'drive around' test fails? ;-)

    • @oldcountryman2795
      @oldcountryman2795 3 роки тому

      @@Geza_Molnar_ I am sure.

    • @tiagodagostini
      @tiagodagostini 3 роки тому

      That said a modern engine has built in self monitoring. That is what unit test would be in that scenario. That said , it is true, You cannot write ALL the tests before you advance a bit in your development, it is as bad as writtign ALL the code before writting any test.