Logo TIB AV-Portal Logo TIB AV-Portal

TDD - the why, the how and the when not

Video in TIB AV-Portal: TDD - the why, the how and the when not

Formal Metadata

TDD - the why, the how and the when not
Title of Series
Part Number
Number of Parts
CC Attribution - NonCommercial - ShareAlike 3.0 Unported:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal and non-commercial purpose as long as the work is attributed to the author in the manner specified by the author or licensor and the work or content is shared also in adapted form only under the conditions of this license.
Release Date
Production Place
Bilbao, Euskadi, Spain

Content Metadata

Subject Area
Fabian Kreutz - TDD - the why, the how and the when not TDD is great, we all know that. But why is it so, and under which circumstances is it ineffective or even harmful? In this talk I want to delve into the deeper meaning of testing to derive how to do it best. All of this from the point of view of somebody who has profited but also struggled with testing and TDD. For every experience level from beginner to advanced there is something to learn or ponder.
Keywords EuroPython Conference EP 2015 EuroPython 2015
uniformity Computer animation Google boom testing unit testing
point presentation Computer animation code time code testing structure
mathematics Computer animation code single phase code testing errors form
Google boom maximal extreme variables programs
track Computer animation extreme code time punching HPC computational
script states code code part applications traces number attributes goodness mathematics Computer animation Google boom statements testing modularity console errors form
default functionality key code storage bits part argument dictionaries system call caches Computer animation loss configuration case orders normal input testing objects systems
suite Computer animation suite case code code testing branch testing errors
modules suite functionality Regular Expressions suite regression Development code effects part mathematics Computer animation case Google boom automate testing testing refactoring
point Development views time programs versions goodness Computer animation case linear testing testing systems
Computer animation Google Development boom Continuation sets testing testing variables
control uniformity Computer animation closures Google time Development boom testing testing help pressure
control processes Computer animation Google time boom testing bits testing number
code parity time cellular code sets bits instance processes Computer animation Google boom testing testing refactoring objects
versions Computer animation code Google boom testing testing refactoring help
point code argument storage lines compiler mining goodness Computer animation case orders testing testing message-based write
control Computer animation code Google time boom code testing testing
programming language functionality Computer animation information sources ones matrix maximal diagrams information
Types programme processes Computer animation compiler generate compiler data types
man suite code time unit bits branch unit testing programme uniformity Computer animation Google boom pattern Right testing generate Type Safety data types
Types Computer animation code Java Google boom testing unit testing Free Type Safety compiler exception
Integrationen moment unit division unit testing Spring uniformity Computer animation terms different framework testing write
functionality implementation distribution Super capacity breadth states unit The list generic counting fields Computer animation objects case testing framework objects classes
man modes files projects maximal directories information Computer animation orders testing testing diagrams statements objects Gamma
Computer animation factor Google time boom testing Frustration certification
data management Computer animation case Development code water testing
Context modules views combination interactive cloud platforms code generic argument unit testing variables Computer animation case phase environment testing framework virtual reality simulation Abstract platforms Abstract classes
specific processes Computer animation Google boom capture code testing Ext information
Adventure specific Computer animation iterations code Continuation plan iterations objects programs architecture
relation Computer animation Google boom Ext testing
Development projects code Average processes Computer animation ons website configuration testing testing Right Games
email integrators code knot Continuation help Peer-to-peer mathematics Computer animation case Google boom testing pressure errors
point functionality code integrators Managementinformationssystem time Development knot unit testing part applications subset connections Computer animation testing
functionality integrators code Development unit unit testing subset processes uniformity Computer animation case Google boom testing Right cycle
modules implementation code time projects storage lines Average Exponentialfunktionen Computer animation case Google boom file system box testing testing Games implementation progress monster
Types runtime Computer animation Google boom projects production
Robots Red Hat Computer animation Google
yeah how OK welcome to my
talk on unit testing and to the and testing is an important subject and there should always be on every conference lots of talks about it and in 4 for promotion and with just on behalf of the hands they have been already a lot of talks in a lot of conferences and and I don't know if I can say something truly original about this and so this talk is aimed mostly at beginners and testing but also for people that have tried testing a lot and some Estrada would find it difficult to adopt simply dissatisfied with without and with the success that they have um the general
structure is the wider when not in the house known it's a bit different than in the title it just sounded better in the title and let's let's start with basic reasoning why we would do testing at all and the thing
is what do we do as coders we we read a lot of coat and we read a lot of code and we just continue reading and only after reading
a lot we will also write some code and usually the point of this time in any presentation is the code should be readable because you read it much more than we write it but I want to add as something that we always do and that is the
trying out afterwards see so is run the code and see if it actually it's
and it's and I I hardly ever commits any code to without at least trying out without looking at it at all because when I do I always manage even even in a single character change I was managed to put in some in some new error so at least I I try to compile it ironic in in some form it it has to be done and and when these this phase of baby steps and the baby sicknesses over and you you know your code runs then you feel this if you like Dr. Frankenstein it's allowing them to really happy about that the and a very important thing is that you can do your beta tester human you simply get a feel of how the code works and unfortunately all of future techniques that I will build on our everything like alternating tests and TDD will not give you this but I'll come back to that later
uh 1 of the dangers of maybe trying out is shut programming as as humans we tend to try to keep the the thinking as I at a minimum and then I I catch myself frequently that's instead of really thinking how to solve the problem I just tried out of it doesn't run them with those some variables tried out again and I'm just continue this without actual thinking untill
onto it it looks good enough and the other extreme is is maybe a little
bit older than uh at the time of the punch cards and maybe nowadays if the if you have a slot and at the same time slot and a super computer I'm sure you will think for always over your code to make sure that the 1 show that you have a running the code will be there will be successful but what is the right thing to do should it be a lot of thinking and hardly ever trying out all should be a lot of trying out and highly of the thinking the than that get back on track on the
Y. let's alternate and and trying out is nothing really else than than alternate to trying out to and computers are very good at doing uh repetitive tasks and and especially when the
set up of air is expensive I I imagine there for example you mean you have to go manually into the jungle Ottoman or into console and tweets some records and remove all the traces from the last 10 test from then you go to the actual application click click and a number of buttons to to do the the manual testing to the men were trying out and I bet with so many steps in between you occasionally would just make some errors and you have to start again go back to be as good as or remove all the traces return to that state and alternating its scripting this part is definitely worth and the problem with documentation is that it out
and tests goods test names are very good documentation which automatically raises an alarm as soon as it updates so when the the code changes in some form the test will break and maybe a disciple of this test is actually operated of changed or removed OK now this is a bold statement to say that could because reusable and modular people say that but that's why how how does that happen but this is attribute
because well I hope you can still see it on the this this kind this constant but it it it does what it's supposed to do so it normalizes the input key and then checks if that keys in some cache storage otherwise it will return any for the so we are done right and that the code works it does what's supposed to do but but it's really hard to test why is it hard to because it uses a lot of outside dependency and so 1 thing that you usually do is you you make dependencies injectable In this case you would move the uh the store from the functionalist school that we have here 1 Scope further out into the object scope and then the test can easily inject those dependencies and the function Xs it through the the option to the to the object scope uh another thing that you realize when doing tests is and the and that the standard dictionary has a get and that the get of the stomach dictionary accepts an optional parameter for the default and that's a good patterns and in this case it also helps with testing because you can simply put it as an additional parameter into the function call instead of having to mock the get 84 function in the object and then what testing you might also realize that there is some normalizing of the function is really it's own and the normalizing of the keys actually it's own functionality and you might want to extract it so that you can do it targeted tests for this 1 and target tests for the getting out of a storage so what testing really does this it's testing reuses your coat and and by trying to have a small test cases were reusing it bit by bit and in order to make a co testable you have to make it reusable and you have to make it modular so testable code is
good let's get back and see and what what happens if we don't just write a few the just just maybe the happy cases and maybe 1 thing but truly a comprehensive
test suite which means that you try to go through all the error cases you try to obtain as much code coverage as possible and well as I just said that if if you care for all all there cases and for all branches and then you could becomes more robust because it because it's not the thing that you normally try out you use some some things are in
in impossible to try out through the you but they still somehow happened due to mysterious circumstances and in automated test
you can there you can produce these we have circumstances and that way test all cases which makes it more robust and once it's more robust you have protection against regression and only comprehensive test suites give you that just a few tests here and there I'm no no protection against regression at all and so on regression is maybe the thing when you change a small function somewhere if you if you work on a single ticket but my favorite thing is that I am very dissatisfied with 1 module i go into that module and turn it completely upside down like refactor the whole thing and when I have if I have these comprehensive test suites then I can be sure that my changes that I can check afterwards what effect of those changes have on the other parts of the of the system and and I have to say this feeling of freedom that is the best thing that ever gets during my development I'm I'm a I'm just happy when so OK you
say I write texts but afterwards so why even
bother with what's what's the point in moving the the testing in front of the development uh well there
are some risks and testing and turned what I have written
so far what I have said so far and you can find it in any book but the books maybe don't mention all tools often and also the risks and especially because accomplished testers don't we have these problems anymore accomplished system might say what kind of moral and says that he's going to make tests but then is not linear amount of experience it is it just practically happens that's out of all kind of reasons good and not being clear about it sometimes just being lazy you're not doing and and we can assume maybe people have talked about it too often enough that that writing good tests and it is it's profitable because because you gain more time then you lose right and unfortunately you will not only right that test you will also right that tests and that also takes time which which you don't get back and in fact once you have respect tests and you will pay interest you pay interest to update them or you pay interest to to live with them and what I just said that tests make refactoring possible they also discouraged refactoring I once had to know so I had to extensive tests on my views like 120 test cases on the views and the test relied on a certain way that the use set up there the initial . but that's the way how they set up that was just deprecated I wanted to change so I wanted to refactor it so that the views get the set up to from someplace else but that would break all the tests so it took quite some time I I was pointed out a lot because I was simply afraid of breaking all the tests and having to rewrite all this stuff again and we all things if you simply don't do it right then you don't get the benefit out of it I said the benefit of good test means is that the document is the better the test things are not but then they don't document and this has something to do uh sorry this has something to do with the uh with the robustness of the mythology testing itself doesn't seem to be robust because In the worst you do it the less benefit you get a a robust system would be well you do it halfway correct and you still don't get good benefits but that that's not the case and I've been talking about shotgun programming anti-bonding is the scaled up version of it that you don't really have to
understand the coded all there is a book somewhere or you you have to add a new feature test test break well you just with variables so long and you're on the test and we variables and run the test on to it works no thinking involved
so yeah as a set this is a question of about robustness and and moving out of the testing from after the development before the development it it doesn't solve those problems but I have found
out that it gives us a certain amount of control over them so laziness and time
pressure leading to not writing tests actually to doesn't help so much with that and you can you can just as easily not write tests beforehand as you cannot write test afterwards but then again and postponing the testing on time when the developer has some of pond closure when the developer things now the thing is done
that maybe it's just not the optimal time to to put their testing in the process so maybe helps us a little bit I show that by some arbitrary number and this is really
absolutely arbitrary number it just says all maybe it helps a little bit it gives us a little bit of control and back to the whenever whenever you do to related things then you do the 1st though the 1 that you do 1st you do it once so when we
do test after then we do the coach and while while doing the test we go back to the cold and updated at the end and there we have actually the thing that that tests help improve the code quality on the other hand if we do the test 1st and and decoding after then we are working for the test twice once when we write it and once when we are actually doing the cold sometimes maybe we realize all the test was withdrawn and we have so which 1 is better
and I think that and we have to to see the parity that the most important thing about code is that it runs correctly the 2nd priority of code is that it is of good quality this is maybe we had for developers but in in an economy at in the economy it it is in fact so that if you have a running code is independent of the quality maybe that is the time when you start making money and that is necessary for anything to continue and also um we have processes we have refactoring and the test set was a lot to later update the code quality to become better we have the test to help us in the refactoring on the other hand it is not a priority 1 of tests that they just pass that it's not the objective that we have many tests that passed the objective is that the tests are of good quality that they are testing exactly what we want to do so I say the most important thing at the time of creation is that we are thinking about test twice so we do it 1st and then we think about it again to ensure good quality because unfortunately there is actually this this 3rd instance the other thing which helps us refactoring the tests we are a bit on our own so back and I would say that gives us quite a TDD gives us quite a lot of improvements and and for far the refactoring TDD actually literally is the answer because what you don't want to do what you don't want to do is and what I do in the in the test after mentality what you do is that you
you 1st go into the code you refactor the code because it's bad cold and then you break all the tests OK and then you go to the test and then you change all the tests but not only is this dreadful work
but also you losing all the benefits the tests don't help you anymore they don't protect your so literally is the solution to this 1 is think the other way around I think test 1st go into the test 1st refactor the test for us to to be able to do both at the new and the refractive version of the code and then after was reflected the cold and that way you are protected all the way through so even more imaginary . 1 this and with test names it it's the same thing really because when you are testing 1st
then the very 1st line of code that you're writing is the testimony so the very 1st thing that you do is when you start articulate what you're going to do next and that's how you get a good test things on the other hand if you have a test after mentality if all your code is already there and you just copy-paste a lot of test cases then you just you just have to fill a void with necessary identifies the compiler says well those tests need some name and you just say and Test 1 Test 2 Test 3 4 test again and so and so I would say
kdd gives us even more control uh but there are still 2 OK 2 points that i skipped so far and well there really difficult and you need these you need to understand understanding you need to understand your um that the requirements in order to do this well as a said
about shotgun debugging should and evolving is the opposite of understanding it is they're not thinking so the helps us with an rethinking thinking because it and it focuses on the what and not on the house In fact I would say then
you know what when when when you are at this place that you want to write a good test the 1st thing you can't really do that without and without understanding what this is about because you have to formulate the test name and you have to to to create and you have to create the what you have to articulate it not only in the name but also in the in the in the test code and at this time your understanding becomes deeper on the other hand unfortunately it is possible to just put there some code which which seems to be like maybe what the customer wants and it is is always very easily possible to just put some tests afterwards which pass writing test that passes is very easy but that's not what we want so the control that gives us here by the way as as in Germany would we would say understanding helps you to overcome your inner picked up but let's have a more
information is testing especially good for Python
and in something imposed unfortunately I didn't write down the source so I can give you the souls but in
something the imposed I saw like 9 or 12 so move matrix of 9 or 12 these kind of diagrams which plot efficiency that you gave that you have in a language as a function of the experience that you have in the language and I distinctly remember that there was a significant update in despite in efficiency Due to unity and it was wondering and I mean it's true I I felt this myself but but why is that so for Python and not for all the other programming languages in my opinion 1 of the
reasons this python has problems
and that's absolutely fine and nothing is problem-free but we we need to have solutions for those problems and 1 of the problems that is very often mentioned with Python is the dynamic typing uh especially job Haskell programmers might not even try Python because they say sailor dynamic typing it's the the can really work well the my compiler checks against that and does everybody know what dynamic typing means all right let's ask who was who who knows what dynamic typing the only I think that's almost everybody
and I'm a bit short on time so of uh continue as so what what what is it that through that pattern programmers say
afterward they say that it's not really that so was who was right other Python programmers just us to see their own faults or these statically-typed proponents does not seem like well in my opinion unit
tests help alleviate the problem a lot because the comprehensive unit test suites will help you and I had to go through all all branches of your code and that's why they will execute all type errors they will execute or
none none type exceptions and they would pay on it and I have realized that myself that I am actually suffering from dynamic typing I am producing a lot of these type errors in my code it's just that during the trying out and during the testing I find them very quickly and and they are not a problem for me and so OK there has been a good compiler and the Java compiler they they solve the problem systematically but unit tests they do it and they do it well enough of and another
thing is the Haskell compiler does it for free unit tests are not
free because you have to write them but then again you anyway want to write unit tests so they are a free side another reason is of
great frameworks and terms at the moment it's especially knows and pi test and there there are lots of talks about practiced especially also here in Bilbao so I'm not going very deeply
into this but there's 1 thing that I want to mention as as the difference between J unit and pi test which I don't hear very
sold J. unit object-oriented which means that we have a base class with all we will all kind of generic assertions and then we have lots and lots of test cases which have set up and tear down very special assertions some helpers and then maybe lots of so we find object-oriented programming we tried to encapsulate many things into 1 class things that belong together they go together into 1 names the thing is that with 4
test it doesn't really seem to work because we have on the 1 hand the functionality and on the other hand we have the state in which the thing it's sold for example if we have some some list implementations subspacc implementation we have different functionalities like getting the length of a pending something popping something and we want to have test cases for the set up when the stack is empty when it's at count capacity field so how do you organize these in an object either you you organize them by functionality then you can just set up but then you can use the setup provided by the test framework each each test function has to do its own set of or if you you organize them by state which means that you you have to put widely different functionality into 1 object and and whether whether they happens go they the happens must be some home mixed in from the outside and makes sense
work if you have multiple inheritance and if your language allows make sense I was working in on a project with this is not from the project but in that project we had to write a diagram in order to find out and how much and how to write the next test OK to speed up a lot
practices the answer there is some doubt that it has a more function-based approach instead of the object based approach and that helps a lot
OK the when not and I'm
sure that if you have some frustrating time with tests you would like to have a certificate like this society you want me to give you a know a
direct reason which hopefully is exactly your reason and from now on you don't have to do any test you don't have to put in work but it's not that easy the general
general thing is that if it doesn't work for you improve it works but what I don't like about this is and that it doesn't mention the costs and dates and economic factor of we have to see so then we have to measure how did the consequence the profit and maybe the profit is really high and maybe the costs are low but the costs are something that we have to be aware of and that we we have to mitigate we have to 1st find out where our costs 1st we use them and only then we should try to improve uh when the the
costs come from they come from mismatches between community and other things 1st mismatch might
be you and it's not common school practice to throw all little children into the deep water because that's the way how they learned to swim faster unfortunately in corporate culture that is the case so you are a
developer you start with a few you right now and I think that's the reason why I am managers don't think that testing is a good thing why why they don't get that feeling because it's simply not you can just turn it on and starts laying golden eggs and while the
luckily we have a we have a good argumentation we agree that that having the tests is what we want and we have to write tends to have good but writing them was the suspect and not the good thing is that the more we write the more we learn to write better
but now the problem with this is that learning is a human experience and you can't infinitely were and you cannot learn too many things at once and you do not long at all if the problem is too difficult and now we have a new concept the difficulty of testing I don't know know of any metric but I'll give you some examples of things that are very difficult text so framework subclasses like John generic views may be you know where where where the class really is a combination of class class and variables and makes and those are really difficult to unit test anything else asynchronous very difficult uh simulated environments like a mobile platform where where where the platform on which you are developing is evolving and and you have to walk a lot abstract subclasses uh uh evolve in in my case quite often before I really know what they are supposed to do they become useful already generalized without really having a good name for that thing that I'm producing them and that makes them really hard and everything that has high interaction means a lot of smoking and a lot of mocking always need means a lot of them context another thing is
that if you read the TD book
you you get the impression that it is all that you ever need you just you just turn this 1 on and then everything works fine but what is not said there is that you need to to have a process around which fits with so and you need a
specification gathering process which is maybe in your company done by non-technical people and especially you need a large capture around it and the
object picture also needs to fit with the because if you do TD alone ignoring the architecture you will always be something in which breaks apart at iteration 3 and the team has
to be on your side because doing it alone just doesn't work and now if you have a customer that you can educate in your process great but if you have an ever-changing customer just simply not worth it soul so you have to to compromise between what the customer gives to you maybe the customer gives you only very bad things which simply doesn't work with at all because the the requires you to have very good specifications at the beginning now I'm I'm not saying that having good specifications the beginnings about thing definitely not do you want to have that but but if you don't have to you might have to compromise and then there are spikes so I'm I'm sometimes going off to the programming adventures and I'm and those that called might become the peak but it's I'm I'm I'm starting we on an adventure without a plan not knowing where and then to simply impossible so in the
end I would say it's a if everything is in relation you have to see what is your competence good enough to to tackle the difficulty and you can you alleviate uncertainty if if not if if you come and come to something which is simply too difficult for you to test and don't don't try to fight it until your teeth fall out maybe skip the tests on that 1 and and test something else 1st onto your competence grows enough because it it will always grow no nobody ever finishes nobody has this competence where you can test it everything but you can also
see that and there are the 3 people on 1 side and the
processes for higher so if you can get the process on your side there are 4 feet 4 . 4 people on your site and that should we should give you the bias that a lot of testing is a good idea
OK but how how to do it now and we agree on the Y and we know that there are some costs but how how to had to go to the next step how how to work with those costs 1 thing and
this is just a recap actually because I have mentioned already the tools and it's very important not only that you use the right tools but that you learn them don't don't start learning a completely new testing tool and a new testing ontology in the in the new project that you are building uh we which which will invoke may involve maybe 30 developers what you want is you you build maybe a small experimental project on itself for yourself maybe a tic-tac-toe game and in that game you try out everything so you will run all the dependencies and all the configuration of the testing we don't try to learn to many things at once but continues
integration helps you and and your team with with peer pressure because it shows you uh everything it shows you whenever somebody breaks the test the test don't help at all if you don't run them if you just write and you don't run them regularly continues integration would not only 1 them but will inform the whole team by e-mail for example uh if somebody breaks and you have to create a company culture in in which nobody wants to be the 1 who broke the tests and with peer pressure you can it becomes fun and doing it the right way I also have realized just just do it just just
start with the 1st test if you have a legacy code and you test after that's fine too just start with the 1st test and while you're doing the test you will realize 0 by the way there's this 1 error case it's very easy to just copy-paste this testing changes but here and there and then you have the 2nd test and and then you realize hey will which is just a few steps and I can have really thorough tests and I will have you have a comprehensive tests and it's never see the trying out I have mentioned at the beginning trying out this
is the thing which gives you which gives you a feeling of the code how it how usable is how or performance is it doesn't make really in a sense I have just heard somebody tell me that he he has written these great tests and everything was working with tests but then when after a long time they actually started the application they realize that half of the buttons were invisible because they did they have tests on on that part and I have to
mention these things which are very difficult to test especially with unit test like him interaction and synchronous and synchronous come and connection to 3rd parties and that the the the point here is that functionality tests or integration or acceptance tests whatever the name for that should be that will help you a lot and that gives you behavior-driven development as the the next step above there are that the names are
sometimes used differently but also I have seen in this conference already talks which show you you have to TDD process as the small 1 using the small unit tests and then you have the behavior during development cycle around that which cares for the bigger tests for the acceptance tests so there
are cases in which I don't do any unit tests at all because the function tests will capture the unit that is also
thing right here what is a unit the and I was very confused about this a lot because his name also implies somehow that everything is made up of units so everything can be unit tested and I disagree with that there are some things which are simply not meant to be unit tested you have to have tests on everything so that you know that the code runs through but sometimes functionality or integration tests are simply enough for there if you want to to create your your test and it
test names then think the finger user story as uh storage module I want to access the file system by doing this and that and all of that user story you can generate the the the test and as I have no mention of few times don't be dissatisfied with your progress sometimes you see people that say all yeah I'm doing have 100 per cent coverage I have 3 thousand 10 lines of code for tests the lines of test and only you 40 lines of code and you get the feeling OK maybe I'm not much maybe I'm not set and fight with my testing maybe I don't benefit because I'm not doing it extreme enough I don't think that it is that that it tastes like that so don't over do you will grow slowly and the thing is don't exp expect testing to be the thing that you turn on and then everything works what do I mean we do it all wrong I said already you should have this smaller that you
have this smaller testing project you have a tic-tac-toe game for example and don't it it's it's only maybe 1 1 file of cold and you right comprehensive testsuites sweets um that that have 100 per cent coverage coverage is a tool which I didn't have the time to to mention them and you will and then try out after what's to introduce a box that is not found by any of your tests and and that way you will find out it's actually quite easy to do and that way you realize how to write the you can create a more a test case for features at once and then you try to refactor and you will find out that test this horrible and you can if you test too many implementation details instead of the overall API yet has a really bad I have learned all these things by doing them in
huge production projects and I just wish I would have learned them in in very small projects so if this is all that you that you get from from my talk and try it out beforehand don't try to do too much learning at once
an and with that I am I reached the end of my presentation and do you have any
questions I I think that I am very
sorry that we have known what type of questions because we're running time things