38. public class UserMailerTest {
@Test
public void notifiesSupportTeamWhenExceptionIsThrownWhenSendingMail() {
}
}
39. public class UserMailerTest {
@Test
public void notifiesSupportTeamWhenExceptionIsThrownWhenSendingMail() {
}
}
40. public class UserMailerTest {
@Test
public void notifiesSupportTeamWhenExceptionIsThrownWhenSendingMail() {
}
}
41. public class UserMailerTest {
@Test
public void notifiesSupportTeamWhenExceptionIsThrownWhenSendingMail() {
verify(supportTeam).reportException(exception);
}
}
42. public class UserMailerTest {
@Test
public void notifiesSupportTeamWhenExceptionIsThrownWhenSendingMail() {
userMailer.passwordChanged(username, email);
verify(supportTeam).reportException(exception);
}
}
43. public class UserMailerTest {
@Test
public void notifiesSupportTeamWhenExceptionIsThrownWhenSendingMail() {
doThrow(exception).when(javaMail).send(anyString(), eq(email));
userMailer.passwordChanged(username, email);
verify(supportTeam).reportException(exception);
}
}
44. import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.*;
public class UserMailerTest {
private final SupportTeam supportTeam = mock(SupportTeam.class);
private final JavaMail javaMail = mock(JavaMail.class);
private final RuntimeException exception = new RuntimeException();
private final String username = "john";
private final String email = "john.tdd@gmail.com";
private final UserMailer userMailer = new UserMailer(supportTeam, javaMail);
@Test
public void notifiesSupportTeamWhenExceptionIsThrownWhenSendingMail() {
doThrow(exception).when(javaMail).send(anyString(), eq(email));
userMailer.passwordChanged(username, email);
verify(supportTeam).reportException(exception);
}
}
58. What I learned so far
●
TDD is a skill – learn it
●
TDD is a tool – know when to use it
●
TDD is software design - sometimes
●
TDD is documentation – very likely
●
TDD focus on goals – yep!
●
Tests increase coupling – seriously!
●
Practice Kata – No jokes here :/
59. Want moar?
●
Growing Object-Oriented Software Guided by Tests
●
Loads of other books – read them all
●
http://martinfowler.com/
●
http://test-driven-development.com
Starting with a bit information on me. My name is Wojtek Bulaty. I recently joined Equity Derivatives IT department as a Java Developer. I will address your questions at the end of presentation.
I will just scratch the surface today. If you want to go deeper I will recommend some books and websites at the end fop the presentation.
The first thing I would like you understand is that TDD is just another tool. Let us start with a real world example.
I need to screw some screws. How do we do that?
I can use a normal screw driver or an electric screw driver . Both of them do the same thing. Which is one better ? I would say it depends on the context . Some call is “constraints”.
What if I ordered a small shelf from IKEA. Which tool should I use? In my opinion the normal screw driver seems like a good fit.
What if I ordered 10 pieces of furniture that need assembling. I would probably choose the electric one.
What if there is no electic ity where I work? In that case the electric one probably is out of the question.
So, which tool sis the good tool, and which is the bad one? It all depends on the context.
Jakies wykresy tutaj? Time and budget?
For example: trading time for long term maintainable code. Do I want to spend the time now and do TDD and end up with maintainable code or shall I just hack some shell scripts and thin k about maintainability later? For example: you are very likely to spend more time on tests than on production code when you are doing TDD. Can you afford that? Or may be you should ask yourself: can I afford not doing that? I hear people talking here and there, tests are good an others tests are bad. I wo u ld say they are not good nor bad . They are just a too l . You need to know when and how to use it. TODO: troche obrazkow tutuaj zamiast tego tekstu
The second thing I would like you to think about is: TDD is a skill.
4 years ago I used to work with a team in Poland in Krakow. They used to say they did TDD. When I joined them there was 30% code coverage by tests. Half of the team wrote tests, the other half did not. Most of the half that did write the tests did not start with the tests though. They started with production code and then wrote tests. This resulted in mixed feelings about the whole TDD approach. The team did not like the tests. They were hard to read, write and update. They did not seem to catch any bugs that went to production. Those tests were just pure pain. After couple of months working on a the project I attended an internal training on TDD. It was eye opening. The guys there showed me the most common errors we made in our tests in the new project. I started to understand why nobody liked the tests we had. We were not good at writing good tests, that was it! I read couple of books on TDD. I started following peoples blogs. Those guys from the training joined out team as well, so I had a change to do some pairing with them. That was the time I understood that TDD is not about writing some code that will exercise your production code and do some assertions on the results. It is about producing executable documentation, maintainable test code, etc., etc., etc. I found that it takes time to learn the basics of TDD same as it did take time to learn to basics of Object Oriented programming. So, I would like you to consider what skills do you have as a software developer. I call myself a Java developer. I know a bit about Oracle, OOP, DDD, Multithreading. I know couple of more things but I would not put them on my CV. One of the things I do put though is TDD.
We did not know how to do TDD. We did not know how to write tests. TDD is not just about whiting some code to exercise the production code. There is a lot of rules you should follow: Keep tests simple – our were not Each test just one piece of functionality …
Example ?
Example?
When I joined the Network Model Infrastructure team at Sky I was supposed to work on 9 applications. It was a completely new domain for me. Talking with a protocol called SNMP to all that expensive broadband devices in exchanges. The lifecycle of a broadband customer at Sky. For example, what happens when somebody signs up for Sky. There some manual process like a guys walking in the exchange and plugging in some cables, that is modelled in a database. There is some configuration that needs to be done automatically on a “special” STINGER device. Etc. The domain was huge. What was my typical way of learning about an area of the domain? I looked at the acceptance test suits for the systems. For example if I wanted to know how do we configure a STINGER device and what messages do we send to other Sky systems when a customer joins Sky I just looked at test called “provision customer”. All information I needed usually was in there. So even if all other members of the team were on holidays I could still know more or less how the systems I support work. This is different to standard Word documentation that it is always up to date. Also, lower level tests documented more fine grained functionalities. There was a lot of unit tests that documented why and how exactly the communication with an ISAM broadband device works in scenarios like network errors or timeouts on the device side.
Add an image demonstrating coupling with tests
You can practice TDD with code KATAs. For example, I want to make a comparison between my cooking, and my TDD. I started learning how to cook about the same time when I started learning TDD. Let us discuss the leek soup I made loads of times :) The first time I made it I did not look at any recipes, I just followed my heart. It was awesome, tasted very good! The second time I made it, it was almost impossible to eat and I was wondering what happened. It was horrible. But I did everything almost exactly the same? Then I started looking into the recipes and found that some things should be added to a leek soup and some not. Some spices are needed in a leek soup, some should be avoided. The ratio of water, leeks, butter was also a very important thing. Slight variations in those thing could make the soup very good or very bad. After following the recipe several times for couple of different soups I started to see the patterns. Even though I have still a lot to learn, I know a bit more how to make a good soup without a recipe. I just can see if it is going to be the kind of soup I like just by looking at the ingredients! It more or less looks like I am in the third stage of competence when it comes to preparing a leek soup ;) haha How did I get there? Using the tool called “recipes”! How can you get to the next level of competence in software development? Using the tools and practicing as well. The best tool I have found so far is called TDD! Once you are competent you probably will not need the tool , you will just “feel” when something is good or not, you might find that it acctualy slows you down. But for beginners, TDD is in my opinion a very good way of working. Following the very simple rules of TDD allows you to unconsciously produce code that is more likely of high quality and compliant with the harder to understand rules of high cohesion and loose coupling. Following the very simple “red-green-refactor” and “test should be simple” rules is more likely to produce code that is compliant with the harder to understand (or easier misinterpret) SOLID rules , etc.
There is a lot of things I learned about TDD, acceptance tests, test infrastructure etc. outside my work hours. I did that by solving different kinds of programming problems by doing TDD at home. For example, a lot of times during recruitment processes I got unattended programming tests. Most of them were not even intended to be solved by starting with tests. But I did that and learned a lot. How can you get to the next level of competence in software development? Using the tools and practicing as well. The best tool I have found so far is called TDD! Once you are competent you probably will not need the tool , you will just “feel” when something is good or not, you might find that it actually slows you down. But for beginners, TDD is in my opinion a very good way of working. Following the very simple rules of TDD allows you to unconsciously produce code that is more likely of high quality and compliant with the harder to understand rules of high cohesion and loose coupling. Following the very simple “red-green-refactor” and “test should be simple” rules is more likely to produce code that is compliant with the harder to understand (or easier misinterpret) SOLID rules , etc.