TDD: The Bad Parts — Matt Parker

preview_player
Показать описание

TDD, the savior of bad code, the promise of a better world. And yet… so many teams have tried TDD and failed. It’s a deceptively simple practice that actually requires a good deal of craftsmanship and skill to wield effectively. Through explanations and examples, we’ll examine a number of common problems teams face, including:

Test Coupling

Many folks our community promote the idea that unit testing means having a test file for every production class, and a test for every public method. And yet this tightly couples tests to the underlying design patterns of the codebase, and makes it hard to refactor. We’ll look at a way to minimize the surface area of your testing and intentionally define an interface between your tests and production code.

Mocking (Hammer of the Gods)

Mockito (and libraries like it) have created very simple and powerful ways for Java developers to create and use test doubles in their tests. And yet those libraries have also led to a good deal of misunderstanding and misuse of test doubles. We’ll examine the five types of test doubles, their roles, and when they’re applicable – and we’ll also look at the common problems developers run into misusing these tools and concepts.

Death by a Thousand Flakes

Outside-in behavior driven development is a commonly used practice. And yet we have too often conflated “outside” with ”GUI” – with disastrous results. We’ll look at the problems this has caused, including slow test suites, flaky test suites, upside down testing pyramids, and more.

Test Suite Bankruptcy

When all of these bad practices combine, they lead to one place: test suite bankruptcy. We’ll examine a case study of a team that, with the best intentions, applied all of these practices together for the better part of a year, and was forced to declare test suite bankruptcy at the end. We’ll talk about the tell-tale signs that you are approaching bankruptcy, and what you should do if you ever find yourself in that situation (or inheriting that situation from others).

SpringOne Platform 2016
Speaker: Matt Parker; Engineering Director, Pivotal.
Рекомендации по теме
Комментарии
Автор

When you talk about refactoring, I feel the same thing. I write my unit tests and my production code is covered. But, if I need to change a lot of things in Refactor step, probably my design is not well designed! In my opinion that is the point. Martin Fowler said, "TDD is a tool, and people should learn how to use it well." And it's true.
TDD is just a technique, but it won't take any decisions for you. Damage is caused by people. With or without TDD, if you take good decisions, your design will be great but, if you make bad decisions, your design will be bad.

Actually, I practice BDD and TDD and at the moment the experience is being great. When I need to change a lot of things in Refactor step, I try to learn what I could be done to avoid it. And to be honest, I feel very confident because the Integration and E2E test (BDD) ensure the behavior.

Thank you for the talk. Cheers

SoneiiraGF
Автор

I strongly agree that outside-in testing does not mean GUI testing. Every time I mention BDD then people associate it with Selenium. Every time I mention unit testing then people associate it with the smallest of possible units which is a single class or a method. I believe the best bang for your buck lies in-between and that boundary is to be strategized per project. As I write my applications using semi-DDD and semi-CQRS then my B(T)DD boundary tends to be the execution of a command.

kallaskaspar
Автор

Would really like to see some actual examples.

BryonLape
Автор

when he said BDD i thought he meant Bug Driven Development, thats what i do.

ulissemini
Автор

Not sure why I was recommended this as it’s quite old. I’m trying to focus on the content but i keep giggling to myself like a ten year old as it somehow makes me think of General Grievous 🤪🤣

portlyoldman
Автор

Thank god you're here.
I've just started learning TDD recently, and I noticed about the "test every classes and methods". I felt something bad about this, but I didn't know how to fix that, I knew there's something wrong. Came your talk, you cleared my confusion and saved hairs on my head. Thank you very much!!!

zzzfortezzz
Автор

Awesome talk. Thanks. Especially the fact, that you see only the slides, so you can follow the topic.

PaulGaida
Автор

I don't take the point about test coupling. Yes, it forces me to change tests when refactoring, but I think it's kinda normal. If you change "unit", you need to change "unit test". Otherwise, the unit test becomes integration test. As Uncle Bob says, TDD is a discipline, and there are some arbitrary boring rules in most disciplines. Also, when you remove test coupling, you trade understandability on flexibility.

sergeykholkhunov
Автор

Did I miss it, or did he never finished the story about the company and their unit tests? (outside of just saying they were still around).

ThaDanzar
Автор

Fantastic talk, every developer who makes tests should listen talks like this.

albertoeyo
Автор

This is a very good talk, all the principles talked here are to the point.

nikosc
Автор

I do not understand, why a controller test with a mocked service is useless. Matt says the controller does not contain logic. Sure, in this example it is trivial. But you write tests for designing a good Software architecture and for ensuring future changes do not break the rest of your logic. Furthermore, if the Controller does not contain logic, why do we need it to implement?
Hence, Controller tests are useful. Especially if you want to test permissions, the correct URLs with HTTP verbs and the returned model structure including the potentially different status codes (404, 201, 204, 400, ...).

christianwulf
Автор

Good talk but I think a lot of people misunderstand refactoring. Refactoring does not always mean modify existing code. The O in SOLID stands for "Open for extension, closed for modification". Once a piece of code is in production you shouldn't modify it. You can extend it or replace it, but not change it. This means new tests, new classes, and new methods. Quite often it also means new abstractions to make for a smoother transition to the new code. The temptation is to go in and simply change the existing implementation because you find some error, or the code is difficult to understand. This will often lead to failing tests so now there's a temptation to change the tests. None of that is advisable. Instead put your eye toward REPLACING the existing code with new code. It's cheap to do, you'll have more confidence in it, and it leads to more abstractions.

CoffeeWithSteve
Автор

Great talk. Matt could you post a link to a TDD open source project you mentioned during questions?

pawelbartoszek
Автор

Strepsils... The main takeaway I got was Strepsils

nathansnow
Автор

This is more of bad practices in testing. how is it TDD related?

Rockem
Автор

my suggestion is to always ask yourself: "how can i do this with less work"

HoDx
Автор

LOL that swallowing sounds...reminds me of that Silicon Valley episode..Im still convinced most software project failures are mainly just lack of domain knowledge. Without domain knowledge you'll never get it right. Because customers are horrible at explaining what they need in a form that a developer can understand.

researchandbuild
Автор

Look outside of what you want to discover, is not form J. WILK. Is an Oriental common practice.

SoaringSimulator
Автор

I think at this time the definition should be changed to UTDD, U is for Unit, makes things less confusing

roberttonne