Behavior Driven Development vs Unit Testing

Поделиться
HTML-код
  • Опубликовано: 25 окт 2024

Комментарии • 66

  • @gruttewibe76
    @gruttewibe76 3 года назад +6

    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.

  • @bryanfinster7978
    @bryanfinster7978 3 года назад +11

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

    • @ContinuousDelivery
      @ContinuousDelivery  3 года назад +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.

  • @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.

  • @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. :)

  • @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.

  • @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
      ruclips.net/video/EZ05e7EMOLM/видео.html

  •  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 3 года назад +20

    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  3 года назад +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.

  • @MrAnandml
    @MrAnandml 3 года назад +1

    This channel is Gold ..

  • @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.

  • @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.

  • @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 2 года назад +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.

  • @dev_taco
    @dev_taco 3 года назад +2

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

  • @josefd8
    @josefd8 4 месяца назад

    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?

  • @krishnakrmahto97
    @krishnakrmahto97 Год назад

    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,

  • @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".

  • @alirezaRahmanikhalili
    @alirezaRahmanikhalili 2 года назад

    Awsome man

  • @LarryRix
    @LarryRix 3 года назад

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

    • @PMA65537
      @PMA65537 3 года назад +1

      6:35 not the only typo

  • @Axesurvey
    @Axesurvey 3 года назад

    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  3 года назад +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 3 года назад +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.

  • @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.

  • @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.

  • @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?
    ruclips.net/video/EZ05e7EMOLM/видео.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 2 года назад

      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.