Behavior Driven Development vs Unit Testing

preview_player
Показать описание
TDD vs BDD? BDD vs Unit Tests? When should you write a BDD specification and when a Unit Test? Behaviour Driven Development is an effective way to capture a users intent: Test Driven Development is great to check that your code is good, but what if they test the same things? How do you optimise your testing?

In this challenge Gojko poses the question when should you write Unit tests and when BDD tests? For Continuous Delivery the real answer is “All the *&^%$£ Time”. If we want to take a software engineering approach to solving problems we need to work experimentally and verify our results - through automated tests.

--------------------------------------------------------------------------------------

🎓 CD TRAINING COURSES 🎓
If you want to learn Continuous Delivery and DevOps skills, check out Dave Farley's courses

📚 BOOKS:

📖 Dave’s NEW BOOK "Modern Software Engineering" is now available on
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

📖 The original award-winning "Continuous Delivery" book by Dave Farley and Jez Humble

-------------------------------------------------------------------------------------

📧 JOIN CD MAIL LIST 📧
Keep up to date with the latest discussions, free "How To..." guides, events and online courses.
AND get Dave Farley's FREE "How To..." guide on Acceptance Testing here

--------------------------------------------------------------------------------------



--------------------------------------------------------------------------------------
SUGGESTED READING:

Рекомендации по теме
Комментарии
Автор

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.

gruttewibe
Автор

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

bryanfinster
Автор

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.

marna_li
Автор

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.

tadwimmer
Автор

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

danielschulz
Автор

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.

Автор

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

blankvoidsea
Автор

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.

eligolin
Автор

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

zpinacz
Автор

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,

krishnakrmahto
Автор

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?

josefd
Автор

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

dev_taco
Автор

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.

HoDx
Автор

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.

synaesmedia
Автор

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?

Axesurvey
Автор

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.

yossiyaari
Автор

GivenWhenTheWithStyle has a typo. :-)

Video editor needs a unit test.

LarryRix
Автор

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

researchandbuild
Автор

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.

MarcusPereiraRJ
Автор

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.

worknevr