 TTT practitioners starting with Ron Jeffries can back some of these guys all the way to you know practitioners who are doing this on a day to day job and kind of understanding what are the different styles are of those of doing test driven development and this is a workshop so I'm going to give you just a quick introduction and then you guys are going to be actually taking different problems and seeing how you would apply test driven development how what is the first test you would write what's the thought process that goes through and that's that's what we are going to try and do in this workshop while building products there are two very important questions that one needs to understand one is are we building the product right are we building the product right which is more of a business facing question and the second one is are we building the right product sorry the other way around are we building the right product which is more of a business facing question and are we building the product right which is more of an implementation slash technology facing question right why is this important because without understanding these two questions right the chances are that you might be focusing on the wrong things when doing test driven development right so this is this is a very two important questions Brian Maric who is one of the leading agile testing guru and also the author one of the authors of the agile manifesto basically came up with this categorization of tests to help people understand which test fits into which quadrant and what's the purpose of the test so he says on the top we have business facing and on the top bottom we have technology slash implementation facing on the left we have that's your left we have supports programming these set of tests help programming helps the developers helps the team drive the development and this test on the right critique the product these are the kind of test which after the fact once once a little piece of code is written after that the fact it validates whether it is actually doing what you wanted to do right so if you take any of these four quadrants you should be able to take any test and put it in one of these four quadrants and understand why it fits there and what's its purpose so let's see what test should fit into the bottom left corner drives development but is technology slash implementation facing unit test right unit test would fit into that quadrant what are the kind of tests that would fit into the quadrant about that which is business facing and drives development this is the kind of things that will help you drive your development these are the kind of things that will tell you what needs to be done and whether you're doing it whether you're building the right product acceptance tests right acceptance tests help you do that any other kinds of tests there is no such thing called functional test integration test is it business facing or technology facing right so integration test should go down there right you don't write integration test from an end users point of view you write integration test from an implementers point of view so unit test integration test I put all of them into the same bucket over there there is one other kinds of test which is known as low fidelity prototypes what are low fidelity prototypes low fidelity prototypes are essentially things that you do on paper prototypes or some simple marks that you do if people were here for the yesterday's session I ran we actually built a low fidelity prototype here we drew a coffee vending machine on the board and we said how the user will interact and when we actually went through and did some tests right is this the right kind of an interaction now so you even before you start building this helps you validate certain things from what the end users interaction would look like right so we have low fidelity prototypes we have acceptance tests in that quadrant what are the kind of tests that fits on the quadrant next to it business facing critiques those are kind of tests you do after the fact you've written the code it doesn't have to be at the end of your project right now be too late as soon as something's ready what kind of tests will go there acceptance test is already there right low test is it end user business facing or technology implementation facing performance might be from SLAs point of view but really it's an implementation thing right boundary testing boundary testing all of these tests cover boundary testing right it's not a separate thing in itself usability testing who's the gentleman who said usability testing that that's right we've done some usability testing using our low fidelity prototypes but not the whole thing right so we need more usability testing what else I'll give you a hint it's manual it's not something that can be automated exploratory testing right everyone's familiar with exploratory testing so you would have exploratory testing in that quadrant UI usability testing and exploratory testing those are the things that you would fit into that quadrant some people say that we actually do acceptance tests which are driven from the UI right I have not had very good success with that so I still would put the UI test in that quadrant and those are really very little in a large project for me so it's okay to do them after the fact if provided they are like maybe 20 or 25 at max on a project with 60,000 tests what kind of test would fit into that last quadrant performance test system test integration tests are more drives development not after the fact right so we would have performance test system test other kinds of things so this is kind of you know and you can take any other kinds of tests and fit into one of those four quadrants why is this useful it's useful because I want to explain where test driven development actually fits right well can I use test driven development to do system tests I can but you know just because I can I should not right where would I use test driven development then things that drives development right that's the you had the clue right on the screen it says drives development the test that drives development that's the quadrant where you would use test driven development so in the paper that I wrote I was talking earlier title of the house of test driven development we talk about two broad categories of test driven development approaches one is the outside in approach of doing test driven development what is an outside in way of doing test driven development starting from a business facing question driving your test down to the implementation right that's an outside in tests for those who were here yesterday we did an outside in way of doing test driven development we started from how a user would interact with the coffee vending machine and we drove the implementation from there right so that's an outside in way of doing test driven development what's an inside out way of doing test driven development where you start with one core entity right so I was pairing with Ron Jeffries for those who don't know Ron Jeffries is one of the three people who came up with extreme programming right so I was pairing with Ron Jeffries and Ron Jeffries when we were pairing on a particular problem I'll talk about that in a minute he started writing as he read through the problem definition he started writing on his index cards and he kind of kept moving them around and then after looking at all of them he said the central the entity the thing that holds all of this thing together is a clinic and he kind of wrote on the index card clinic and he said this is where I'm going to start so he started with clinic tests right so you start with something which is very crux and you build the system out right so that's an inside out way of doing test driven development and we're going to get you to experience all these different types of test driven development in this workshop before that I want to just step back and make sure we're all on the same page what we mean by test driven development I hope everyone's familiar with this but I want to do a quick recap so we start with the tests we start with an automated tests right what happens when you run this test you're lucky it doesn't even compile for me right when I write the first test it doesn't even compile if I'm using dynamic language then it's a runtime error but it doesn't fail it just blows up right so to get this to work I need to frame the test I need to make sure I have just enough code in place to make that work right to make it compile or not it throw up any runtime stuff let's say I'm able to do that and then I run the tests now what do you expect to happen you expect it to fail but what if it passes be suspicious if it if it passes be suspicious maybe something's wrong maybe the test you wrote is not right however right let's not be dogmatic because I've had arguments with people who will say oh your test expected as 0 now you should put in your code minus 1 so that the test can fail I'm like what life's too short for that nonsense right if I expect 0 and my code happens to give 0 yes that's fine but let me be suspicious let me now write another test that will not expect 0 right but that does happen sometimes when you write a test and you you expect it to fail it might pass you need to be suspicious right but you expect it to fail when it fails what do you want to do let's take a month and do some design right now make some little change to the code write some code change some existing code make a little change the little change is to make the test pass right the idea is to get the test to pass as quickly as possible by not damaging the existing system by not going in and hacking stuff over there right we want to do as little elegant code as we can to make it work right and then you run the tests what should happen if it fails make a little more change re-sync your mental model with what's happening on in in your computer right because those two models have gone out of sync you expected to pass it didn't slow down think what went wrong fix that ideally you expected to pass then what do you do call success and go home for a beer add more tests a lot of people do this two-step cycle right go write test write code write test write code right after three months six months they come back saying I can't deal with this who wrote this this is not maintainable anymore right the design sucks there's a whole lot of duplication it's not clear what's going on right because we are in a space where we do reflexive design and to do reflexive design we need what we refer to as refactoring right we want to look at what our design is not just the test not just the production code but also the test code to eliminate any kind of duplication to eliminate any kind of redundancy make sure that it's communicative make sure we've addressed all the code smells there are about 33 different code smell so I want to ensure all of that done all of those things are done right one great way to do that is to do pair programming and have a pair look at it and say hey does this make sense right if both of you agree chances are most other people will agree we always refactor when we have passing tests right and then we repeat this cycle until we have satisfied the four rules of simplicity anyone who knows the four rules of simplicity when do you stop test to one development on a particular problem on a particular story there are four rules of simplicity that we need to satisfy when we can say yes I think I'm done first rule simple all test should pass not just the test you wrote but all the tests that existed before that should pass can you call it done before that no what's the second rule 100% coverage that's for the managers to keep them happy it meets all the requirements but that's what your tests is right for if your tests are not passing you've not met all the requirements so that's already covered in point one point two is the code communicates it's not it should not look like a cat came and walked over your keyboard whereas it has to make some logical sense for someone who's gonna come back and look at it so it has to communicate what's the third thing third thing come on what else would you look at no duplication right so the code communicates but there could be bunch of duplication right so let's generalize it a little bit and say there is no code smells we've addressed all the code smell so duplication might be one there are many other code smells like primitive obsession like speculative generality so there's a whole catalog of about 33 code smell so we want to ensure that none of the code smells exist that's the third rule that was the last one that's what my tests are for for documentation the fourth one is minimalism right you want it to be as minimalistic as possible as little code as possible without compromising on communication and quality of the design right so those are four rules of simplicity that's when you will say I can stop the cycle I want to move on to something else right I know you guys expected this to be a workshop and I'm kind of just boring you guys with some gyan which you don't want so I'm gonna move along quickly everyone's familiar with this cycle except since this driven development cycle I'm just gonna boom boom boom boom run through it slow slow fast fast fast how about that we went to back so we have user stories user stories have a set of acceptance criteria right that's what we use in the planning meeting to decide how much scope we can actually consume how many stories we can actually consume in the next print once we agree on that then we start the iteration once we start the iteration the developer would call the subject matter expert and probably the tester if you have a someone who specializes in testing three of you are gonna sit down it doesn't have to be three people it could be one person playing all the three roles right so those are three different perspectives that you want to have and you sit down and you write what we call as the automated acceptance test right we want to capture what are the different scenarios or examples for the criteria that we just laid down during the planning meeting at some point the developer will say okay I've written two or three scenarios I know where this is going I can see I can guess what the next one will be and at this point I feel comfortable to go ahead and start hacking some code right so the developer would go off and start using automated unit test driven development to drive the development while the tester might cover other scenarios other edge cases other things which are important while the subject matter expert the business analyst whoever it is might go and help other people do this or look at the next print what are the stories that are coming do they have good acceptance criteria or not so everyone kind of then goes back and starts doing stuff when all the tests all the unit tests are passing can the developer say I'm done of course not because you also have to make sure all the acceptance tests are passing right when unless all the acceptance tests are passing you cannot say just because I've written a bunch of unit test might my job is done that's not accepted right so you want to make sure all your acceptance tests are passing not just the two that you started with but in the meantime the test might have written 10 other acceptance tests you want to make sure all acceptance tests are passing let's say all of those tests are passing right can I say I'm done as a developer not yet what is the one thing that we are still missing rule of simplicity that that's already taken care when we're saying that unit test driven development you have done you've applied all the rule of simplicity and you've made sure all the requirements are fulfilled but one thing that's still missing is the exploratory testing right you want to do some exploratory testing to make sure that there is nothing that you missed out from a point of view of you know something that the system will allow you to now do because this feature is added which might be a security issue which might be something that will confuse your users whatever it is something that you had not anticipated so when all of this is done maybe you will discover during exploratory testing something that you did not think about in the beginning you would go back capture that as an automated acceptance test and complete the cycle again right and then of course you do your sprint demos where you get the acceptance on the criteria and then maybe a sprint or two later when you have a stable UI when you have built a end to end UI maybe a screen together you might actually write some automated acceptance tests or UI test and also do some performance tests when you have something critical you know available with you right so that's in a nutshell what the acceptance test driven development cycle is so right now I've actually introduced to you two different levels of test driven development right but I want to introduce you to the whole gamut of test driven development all the different of cars of doing test driven development which is what this workshop is but before that a small commercial break right people have already seen this I'm going to just blaze through this that's me in Colorado with Venkat Subramanian we were hiking here a lot of fun I live in Mumbai these are communities or conferences that I've organized I'm an entrepreneur I have two startup companies I'm not going to go into details of that bunch of companies that I've worked for either as an employee or as a consultant now I come back to the topic right how many people here have been to Uppsala conference okay that's sad this is you're really missing something in your life Uppsala conference is where really all the patterns all the good stuff that we hear about have come out of right so you know it's like some people have you know I should go to Kailash Parvath before I die so put one saying I need to go to an Uppsala conference before I die this is extremely important to go meet the you know really awesome guys over there I happen to fulfill my teeth Yatra once so I was at Uppsala conference in 2006 I believe it was and I participated in what they call as the design fest so the gang of four guys run something called as the design fest so you form groups you basically subscribe to the you know you say I want to participate in the design fest then they randomly assigned groups they form groups they give you a problem and then through the day you have to work in a group and you have to come up with the best design for the problem right so I happen to be part of one group where people were you know this was the first 15 minutes of the discussion they read through the problem and they say oh that's a noun so that should be a class so that's a verb so that should be a method right and then we hit across this position where we were saying well the you know this is a veterinary information system problem that we were so you know you take your patient you take your pets to the vet and you get some vaccinations done and things like that so we were talking about that particular use case and so actually let me show you it's it's really small but that's kind of the problem that was given to us the whole bunch of use cases but if you see here the first use case that we have here where you know Dave Atkins takes his pet Daberman fluffy to the wet and gets vaccinations done and regular checkup done and we were talking about this and one person was saying well we have a patient which is which is the pet and we have a doctor right now who should have the method give shot or take shot right the rabies vaccination you're giving a shot should it be on the patient can the patient take a shot right so should the method be on the patient should the method be on the doctor saying give shot right and this argument went on for about an hour right because it's a it's a very important discussion and at that point I felt life is too short to waste time so I actually left the group and I said you know what I'm just going to try doing test-driven development on this so by the time these great guys come up with their fantastic design probably I'll actually have a working software to demonstrate what what this wet information system so I went off and I started working on my own there were people at the conference who knew me who were passing by they said what are you doing I said I'm trying to do test-driven development on this they would say hey can I pair with you I'm like that's awesome let's sit down and I started pairing with them and something hit me you know this is 2006 I've been doing test-driven development now for about five years at that point and suddenly something hit me I'm like oh that's that's very different way of doing test-driven development than I'm kind of doing here right so I'm like you know what this is very interesting they're actually very different ways or very different styles of doing test-driven development and I always thought that this is the right way and this is the only way because you know if you look at the slide I showed you it's so simple right write a test make it work refactor go back what what variations can you have in that right this so that's such so simple thing but when I started pairing with people it hit me and I then took on this role of a journeyman to go and pair with different people and learn from them what are the different styles of doing test-driven development I'm going to show you quickly a few glimpse of what we covered and then I'm going to let you guys do some exercise where you will also discover some of the different styles of doing test-driven development so this is acceptance tests return and fitness for that first use case that you saw and this is the kind of design we ended up with this is in retrospect we just did a we pulled up from the code what we came up with in terms of our design a procedure a bill an account a receipt all of these are classes no interfaces this is acceptance tests wrote return in Ruby and what we ended up with is this kind of a design right slightly different this is what I was talking that when I worked with Ron Jeffries for example this is this is what we wrote and this is the kind of design we ended up with you can see exact same problem exact same time you know spent by people and quite different designs not drastically different but quite different design right this is another this used to be my style of doing test-driven development where I didn't have you know I didn't say clinic test I would I would my test would all be if you see here let me highlight that if you see here it says charge account for service that's my test I don't really know what classes I need yet right I've not done the design I'm going to let my test flush out the design but I know this is the behavior I expect which is charge account for service and I would end up writing all my code in the in the test until actually I figured out hey these set of methods actually belong on an object which should be you know visit or should be clinic or whatever and that's how you know the design would emol and that's kind of the design that I would end up with fairly complicated in some sense with all the cross sections going between those classes and interfaces but also arguably fairly decoupled right my point about showing these is not that one style of doing test driven development is better than other the style but just the fact that there are different styles of doing test driven development and each leading to a different design right so I want you to experience this in this workshop so you walk away with acknowledging that there are different styles of doing test driven development and how they influence your design something to keep in mind this is kind of a quick summary that sorry this is something that I need some water that's too much text on the slide sorry so yeah this kind of something me and William Wake came up with anyone's familiar with the name William Wake he's the guy who came up with the invest principle for user stories he's also written a lot of books on refactoring and stuff like that really awesome guy William Wake and I was sitting down and we came up with this grid saying what are the kind of driving factors that drive you in different you know drive different decisions when you're doing test driven development so what I mean by that is are you using your unit test predominantly to drive your test are you using your acceptance test to drive your test what's your starting point right are you going after the API or are you going from the UI are you looking at the API or are you looking at the interaction right is it more stateful or is it more interaction centric is it more object oriented or more procedural in terms of the nature of job that you're performing do you go after the easy stuff or do you go after the core stuff right do you start with something easy or do you start with something really core do you go narrow very specific to one particular thing or do you go broad right do you do you use your test to drive the design which means I have no idea what the design is going to be I'm completely going to let it unfold itself or I'm going to I have a design in my mind and I will use the test to validate my design right so these are kind of some of the attributes or some of the things that we went which will influence your design when you're doing test driven development and this is kind of the X marks over there indicate a particular of thought of doing test driven development you add X marks in a different place it will lead to a different of tar of doing test driven development or a different style of doing test driven development right so right there don't let your brain run and do a permutation on the number of boxes and say there are like 600 different ways of doing test driven development that's not the point all right so enough of me talking that's just the context I've set which took about 30 minutes so we have another one are for us to actually do four exercises and we're going to spend about 10 minutes on each exercise and then do a quick round of summary so what we want to do is like for example I have a simple bonus calculator example I want you to form groups and each group is going to try and say what is the first test they're going to write for this particular problem right so let me explain this problem a little bit it's a fairly simple problem I have you know I'm trying to calculate bonuses for my sales people right so they have a certain amount of sales that they make in a year and they have a quota that they have to you know once they go over the quota then they get the commission but the commission is decided by a percentage of commission and taxes applicable on that percentage right and so if a person made a sale of 1200 quota was 1100 10% tax 10% sorry 10% commission 10% tax they would get nine units right so that's the basic logic if you didn't make enough sales then your if you if you didn't make enough sales then your bonus would essentially be zero right very simple problem is probably only three lines of code to build this but what's interesting is how what is the first test you would write how would you crack this problem right if you're doing test-driven development so form little groups and then come up with how you would what is the first test you would write and why you would start there we're going to time it for five minutes and then we're going to share each group is going to share what they come up with right this is a workshop this is not a movie so you got to come up and start working cute what so what would be your first test eligibility for bonus would be your first test outside in approach eligibility for test okay eligibility for bonus same thing all right same okay I'm not interested in my new details if it's same let's move on calculating okay let's go there when sales is equal to quota what do you expect no bonus so no bonus for average performing use the sales person okay it's about the same eligibility for the eligibility group over there eligibility did not meet and did meet okay that group did you guys have any discussion so I'm going to yeah the approach don't tell me the details each row is a test okay so here is the kind of mess I would write because this is just a very simple one I'm going to show you really complicated ones to go into that's where the fun is can everyone read this what's on the screen no bonus for low performers when sales is 0 and quota is 100 then individual bonus is 0 no bonus for average performers when sales is 100 and quota is 100 then individual bonus is 0 right bonus based on commission percentage then we are saying bonus is based on you don't want to see all those messages bonus is based on commission percentage after tax and no bonus for that's that that's just the next version of this so we complicate the problem by adding more things later on and things like that so that's pretty much how I would write test for this and that's what style of test is that inside out or outside in inside out outside in outside in it's really inside out because I'm just dealing at a one particular sales person level right I'm not building a whole sales management system all right let's move to a little more interesting problem right this problem is to do with calculating sales tax and there are there are sales tax at 10% but certain items are exempted from sales tax and then there is import duty which is charged at 5% if it's an imported product right so given that's the basic thing for now you can ignore the rounding and all of that stuff because we can get to it later and we've given some examples what is the first test you would write and why so again in your groups go through the same exercise I've shown you one example what I expect in terms of at the end of this exercise so I want you to think in those lines and tell me specifically how you would write the first test this one can be done both inside at an inside out and outside in so there's a lot of room for discussion don't spend the 10 minutes reading the problem I already told you what the problem is there are certain items which are exempted from 10% tax and there are certain items which get charged and import duty that's it there's nothing to read on the screen that's easy in which you would write the test wouldn't be item test wouldn't be sales tax test what is the name of the class exempted items test is exempted or is imported okay all right any any other solutions you guys came up with all right you guys need to listen up because I can't hear if you're talking local exempted product validate local not exempted product validate imported and exempted product what's the tax on it validate which is imported and not exempted product there are four scenarios and validating product is local and important so what I want you to tell me is in what class you're going to write what test right so what is the name of your test class and what is the name of your tests all right that's what I expect so come here all right calculate sales tax is the name of your test picture so you're validating that the import tax is 5% okay that's the name of your test okay but what if the percentage changes you go back and change the test names right something to watch out for we'll go there I'm done next group not done still designing okay I'll name the class is sales tax so sales tax I don't want you to come up on the fly you should have already done this yeah I mean that's what I was thinking actually and then I will group the inputs you know to make one case like the one book one item this one case and like that so each line you will read and you will test that yeah I will take I mean make the hard coded inputs in his case like one book one other item one next item and this should be the output so I'll supply the hard coded input serious test so again see what I'm asking I just want to clarify what am I asking from you guys what is the name of the test fixture right what is the name of your test class what is the name of your tests that's all I need right that's what I want you to tell me so I'll give you another two minutes to come up with that and then we'll go around name of the class in which you will write the test and the test names the method would serve okay we don't have mics so we have only one class compute sales tax compute sales tax is the test the class I'm not interested in your production code at all I don't care I'm only interested in the test class name and the method the test method names that's all I care about tax test class tax test class okay we have four methods sales tax for sales tax for domestic product without exemption sales tax for domestic product with exemption imported tax sales tax for imported products sales tax for imported so four tests for all the four combinations okay on a sales tax on the tax tax test since tax calculated tax all right we'll come here Mike please yeah sales receipt generator and we will be one sales receipt generator is the name of your tests okay generally the convention is either ends with test or starts with test or something we end with test sales receipt generator test and the first test method will be test sales receipt for non imported items then for non imported same thing as that all right who next I'm not trying to be rude to anyone I just have a lot of content to cover and I'm going to move as quickly as possible validates sales tax is your class all right no tax on tax exempted item one test no tax on tax exempted item tax exempted item tax on imported item tax on non exempted non exempted item okay need to pay a little more attention to someone reading those things should be able to understand it as documentation right these tests are your documentation so the method names have to be more descriptive something you want to pay attention to right all right cool thank you okay so very similar to that which is validate the product prices the test class validate product price is the test class so the methods are essentially this is one method which accepts which is validate price which accepts the product name and the build amount for it which returns back whether the base product price plus the tax on it matches the price that was given to it from the billing system so you would write one test but how would you cover all the different scenarios we don't have to cover that's not externally exposed right in the database you essentially would say this is an imported product that would be an entry in the database that's not an entry earlier that's an internal decision it need not be something I understand it's an internal decision but how would you make sure right when you're writing a test you want to make sure that all the four different combinations are actually working right so the validate price would have we have multiple we have different products passed as arguments the imported one non imported one and then arbitrary price values passed to it to ensure that base price and import tax so the challenge with that is right that's referred to as an elephant test the challenge with that is when that fails you have no idea why it failed it could fail because any one of those four conditions so it doesn't give you pinpointed feedback which is one of the important criteria for writing good acceptance test or unit test item tax test is our class then we have test for calculating tax for basic items exempted items imported items then come the combination of basic exempted imported exempted what are the names of your methods you're still telling about basic item is the first test calculate tax for exempted items calculate tax for imported items then calculate tax for basic exempted items okay good so those test names are more descriptive do they help you understand a little more better right so that's good we'll come here next question is sales tax calculated test and we have got the four methods that everybody has been speaking about plus we have one more method and that is test product whether it's a local or imported test whether it's an imported or local item test product that's just a method that we are going to find out whether it's a local product or an imported product and then we have two asserts inside that one assert per test rule you've read that that's you should have only one assert per test because now if the first assert fails your second thing will never get executed so you want to avoid that kind of an issue okay and then we want test local exempted product items then you have test local non-exempted product items test imported exempted test imported non-exempted items so all the four combinations go back there we would name the classes sales tax calculated test and the methods name would be like when exempted goods then tax should be 10% and when exempted tax should be 0 right 0 0 0 and when the goods category is non-exempted then the tax should be a 10% so we'll name the methods in a similar way again I gave the feedback last time that if the percentage is changed because government wants to give you ask more and more tax right all the time so it's going to change will you go back and change your test names so never put numbers in your test because that's something that's going to change and that will lead to higher maintenance of your tests right yeah so do that and then we'll come to you guys question okay different periods that's not going to change you know so you wouldn't add it in the test name what you're trying to calculate over there is there's some thought process some formula you're trying to drive out which is essentially decide what percentage of interest should be applied right so for a short duration loan you know taxes or interest is at a premium or long duration loan the premiums are the premiums on interest are low or things like that that's what the test should name should describe not the percentages alright test case name will be test cell text calculator and the cases should be validate cells tags validate input tags validate cells and input tags and validate so valid for validate methods for all the four combinations okay come here last group okay in the test name in the test name but we are saying that the test name should be descriptive so tomorrow if the tax is increased or decreased on modify so when the test phase I would actually come to know okay it should be 10% but why is it failing then I'll come to know either I need to modify the name no maybe when you assert phase you assert will say expected 10 got 9 right will you get that feedback that doesn't need to be in the name of your test okay along with the four test cases I would add couple more like you know testing whether it's a valid product so testing whether calculate tax works when you pass an invalid item for example how do you pass an invalid item maybe the design says that somebody can pass a valid item so maybe they pass null for price or something should not be allowed at all right depends on the structure of the item correct so you're designing the structure of the items as that that should not be possible right I wouldn't waste my life trading such tests because life is too short you design says that someone cannot pass now someone cannot pass random arbitrary stuff if people can do that that's a bad design in my opinion right so I'm going to show you I understand everyone has lots of questions but I want to show you how I would write tests for this right so I have a shopping cart so this is an outside in-way between test-driven development I look at it from a shopping cart point of view my system metaphor here is that I am in the store and I'm buying a whole bunch of items putting into my shopping cart and then I go to the checkout counter and I do a checkout and it tells me what is the amount right think of this as shopping on Amazon right you keep adding items to your shopping cart then you say shopping cart checkout and it'll give you you know what is the total amount and it'll give you a receipt essentially and you will assert on the receipt various different things so here we are saying check out empty cart when I check out empty cart my total should be 0 right I went to the store I didn't buy anything my total should be 0 that's the easiest test I can write to get started with right so that's my first test but it's an outside in-test from a user's perspective that I'm writing this test my second test is check out an exempted domestic item right when I check out an exempted domestic item which is rupees 100 domestic book right my total should be 100 because I should have no tax on it fairly easy to write this test right just return the price nothing more you need to do next test I would write is check out taxable domestic items domestic items that are taxable so rupees 100 music CD should be 110 and so on so I would write a bunch of things and I would also say rounding logic because all this time I didn't worry about not rounding stuff so now I'm saying rounding logic needs to be tested right so that's driven based on the category and based on the price that you passed in and so forth but that's not the only test I would write right that's only the starting point for me there are a lot of other things that I would want to do inside this so let's actually look at what other tests I would write so I would have an item test what does the item test contain certain categories are exempted from sales tax what categories are exempted from sales tax those categories are taxable imported items have import duty imported non accepted items have import duty and basic sales tax let's look at the receipt test I want to validate whether the receipt is being printed correctly right so the receipt test is basically going to validate how I'm printing the receipt so each specific unit test at the individual classes level and the shopping cart which is more of my acceptance test at the product level right this is an outside in way of doing test driven development but how I would do this inside out so it goes back to what metaphor you're using right so the metaphor I use here was I am building Amazon shopping cart and I'm adding stuff I have no affiliation with Amazon by the way there's no marketing I'm doing for them I just wanted to clarify that if I'm adding stuff to Amazon shopping cart and then I do check out and there should be the amount that I get on it right so that's an outside in way of doing a test it's more can you think of an inside out way of implementing this system start with the tax calculation portion I don't care about items I don't care about anything given this is the amount I need to apply this percentage tax what should be the number on it right so I start with the calculation and then I say oh by the way I have items I have categories I have other things and you kind of flush out your system and you say oh you can put things in the shopping cart right and you build the system out that way that's the inside out way of doing test driven development clear so this problem can be done in both styles yes asserts is okay but writing two asserts or two different things is not okay right so when we say one assert per test it means that you should not validate two different things on a test if to validate one thing you have to literally write two assert statements that are fine right but if it's two different things that you're validating all together putting them inside one test is not good idea break it apart into two different tests and call out what's the difference between the two in that case there's no difference between the two right so that's what it means by one assert per test it's not literally one assert statement per test it says one assert per test not one assert statement all right let's move on to the next one this was back when I was working at a medical company and they said what we want is we want to calculate the patient's age we actually have a program that needs to be fed in what is the age of the patient and based on the age we can give different medications different dosages of medications so there is another system which will essentially take the age and do some logic with it right so you have to you know that they explained as very simply that this is the logic if it's greater than one year you just report things in you know number of years if it is less than a year but greater than a month then you report it in months if it's less than a month greater than a day you report it in days less than a day greater than an hour report it in hours right because here you could have a new born who needs to be given certain dosage of a medication so which is why you can you need to know the age in these different durations and your program has to be smart enough to figure out what is the closest match and report the age in the closest match right so this is fairly simple they added another twist into the story they said by the way you know doctors and nurses can add new durations these are duration standard durations that we know but I want to know bi-weekly right or I might add a new because a new pharma company came up with a new way of measuring you know based on lunar calendar they measure something and then every you know some lunar cycle fourth night or whatever you need to be given every every Ramzan night you need to be given one dosage of something so they can actually come up with different durations at different points and time and your program has to be smart enough to take that duration and then report in the closest matching list of durations right so that's the problem what is the first test you're going to write right I want to know the name of your test class and I want to know the name of the test that you're going to write test class test class identify please pay attention identify the patients named with age identify patients named with age name and age yeah tomorrow they want to add something more that we are defining we have identified only one now what I'm saying the name of the class should again not include what data you are trying to get the data I am not defining the number of age number and all that just I am given the not number you're saying name and age right tomorrow you might need name age and gender you don't want to go change the test for that we can have identify the patients details identify patients details okay so come back to it we'll look at some other class use the mic please hello actually I came up with only one test name of the just tell me the name of the test and the patient's name should contain duration keyword patient's name should contain duration is that the method name or the class name this is the method name okay next please we are running short of time so we said patient age calculator is the best class name patient age calculator is the class name yeah and then we have check age in hours check age in for our days month so only thing that we were not sure was how was the input technically for us we just need the date and time of birth and then the program should be able to return back all of these whether it is if it is the same date and returns in hours if it is the same month then returns in days and blah blah blah blah blah blah that's the implementation detail I don't really care about it so what I was not sure was how was the patient's information going to be stored so that we can then that's what you would design that's what your test will help you design right okay so with test development right we are trying to write the design as we are building so we are going to decide how we are going to store the patient's information so we can do these calculations okay that's the test class name is patient registration test your friends are not interested in listening to you so what should we do no I should make more friends alright guys if you are not interested in listening to anybody else you are not going to learn anything trust me it's not a race right nobody is going to get a prize here so we want to see what other people have come to so you will actually learn from it right so please pay attention so we tried outside in and class name is patient registration test okay and the methods are let's say calculate age in hours calculate age in hours calculate age in days okay what if new durations come in weeks what happens when you get weeks new tests I gave you a little bit context right this is a medical system this gets deployed in hospitals you know how long it takes for you to make a change in the code and get it into the hospital it goes through FDA regulations right this is not going to allow you to hack some code on the server in the hospital right the patients are going to die if you slow down so it goes through an FDA regulation so something to keep in mind this is why I am choosing these problems because these problems put heart constraints and it kind of really forces you how you would design things so if your test names are kind of hard coding it's a good indication that this program is not extensible right again your tests are telling you something about how you should be designing alright so that's why it's called test driven design but could try let's come to this group same thing no I just have only one test case that I can think of right now test age slot test age slot age slot all this is adding new one so that's a one test if you could think of a new one alright good let's come here I think we also thought in the same way like the test picture name would be the calculate age test yeah and inside there we will write method like calculate age and hours calculate age in days test, calculate age in month and calculate nothing wrong with that but right from the beginning you know that you are going down a path where it will lead to a combinatorial explosion of your test and that might not be a good strategy to go forward right so why write all the tests and realize you know what I need to just throw them all away not a good approach something to think about let's go to that group so our class name will be so the function name will be check if duration correct and it will take the parameter as the the class name will be age calculator age test age calculated test age calculated test alright yeah and the function name will be check if duration correct it will take duration correct so it will take the date of that patient plus the reference that we are pointing to that you said about the Ramzan day and if we want to give a date with which we want to find the age if we give a reference basically reference as in what I didn't get so you said that if we want to find the age of a person not from current date but from some other date when we are launching you might want to register new duration so right now we have four new duration years months days are you said it when you were just telling about this thing that you would add a new duration that is weeks yeah for that we have made a generic function but for finding the reference of the date if you want to find the date of a person from now or from 10 days next if you are having an event but that's okay so you're saying that you basically have one method in your test which will do all the different yes plus it will see that if the age is coming as less than one then it will throw an exception or give some kind of message throw an exception not throwing an exception but actually it can be minutes also but it is not specified in the requirements not specified in the requirements if I had all the requirements within the program that would generate the code for me we need people to think what would happen but that's good you're saying there's a boundary condition what should happen over there should not throw an exception for sure but it should do something else but that's good let's come here the test name is age formatted test age formatted age formatted tests and one year display age in years what's the name of the test? for duration greater than one year display age in years what if I add a decade you will be adding a new test case you will also change the name of this test this condition is going to exist like this test case will be there if you look at the name of the test then one year then report age in years now what if I added decade as a duration would this test still be valid? if this condition is going to be still there even if you add valid it will become one decade not 11 years here we have specified the division as different division is specified then and that division is different than how current it is not are you understanding the point I'm trying to make so you can discuss amongst yourself let's move there in this test as you say that we can have one more type of duration so I think test requires some plugability and plugability is duration strategy and there is a chain of strategies for example one is your very tempting to jump into the design most often you make kind of miscalculation without actually when you jump ahead and start designing things in the head nothing wrong with that but for this purpose of this exercise I want us to stick only to tests what would be the name of your test class? Calculate age this is the first method name of the class medical system test that means the whole hospital the reason I am kind of fitting on these points it's very important because this is what will drive your testing strategy of how you are going to actually come up with your thinking and quickly jump and show how I would write the test I am not giving any detailed feedback at this point to individuals but you know we can do that after this session I am listening to what you guys are doing and then I am kind of showing you quickly what I will be doing so that gives us a reference point so let's open this if I started from an outside in approach I would say patient tests report age in years report age in month report age in days report age in hours this is where I am specifically saying that I want the age to be reported and so and so thing now this will go wrong what I was pointing out earlier that this will go wrong when I add something which is a decade so quickly you realize that this strategy of test is not a good strategy because this is leading to a combinatorial explosion so this outside in approach might not be the best approach to start for this so you are going to delete this and come back and do something called as the duration test so duration test says calculate duration since and you are going to say essentially you are focusing on just the duration so here we are saying duration since whatever value you get and you assert that that should be the value expected in terms of your result now where are we defined what are the different things so here we are saying if this is the date of birth this should be the years or whatever this should be what it reports if this is what the age is date of birth is then this should be the age so we have defined all these different combinations essentially one test drives the whole thing say calculate duration since right this is the basic test that covers the four conditions but then we also have another test which covers the modification part of it so here we have another test which says cannot register already existing duration types reports error while registering non-existing duration unregistering non-existing things can register and unregister largest duration so I am saying if I said duration since would have given me 31 years then I say all right let's register a new duration which is decades and then when I say since it should say 3 decades and once I unregister it should give me back 31 years yes like you have a case where you say reports error while unregistering non-existing duration types do you think your program would allow that if your program should allow that there is because this system particularly is a messaging based system you could get a message which is outdated where a duration was unregistered by somebody and another message came to unregister the same duration so you need to notify that that's already unregistered so that's a reason that you're considering multiple users using multiple users in a hospital using this system right and there is a possibility that somebody could do this your class that you have made again over here still it shows that it's going to add manually register or unregister but into an object so how does it become like from the first scenario which you said it might not be good approach I see the things being the same I didn't get your question sorry in the second scenario that you have shown right now you are registering and you are not registering this is not dynamic in nature what's the code for it which you are going to execute that's a test right but think about a UI where someone will go and say okay I want to register a new duration and they will select a new duration is decade and they will say a decade is from a drop down these are all my existing duration oh year it's 10 times the year right so they register that that's what will trigger this particular line of code from the UI okay and then they're going to say okay now report the duration of this person and it should give you three decades they will be changing code right you're going to have an interface through which they're going to drag this particular thing good question fantastic if I had a price I would have given you a price right that's a brilliant question so his question is if I run this test tomorrow right this test might fail because the time from now it would change right this test might not but let's say the days one this 10 days right so hang on to that right this test is going to work today if I run this test tomorrow it's going to be 11 days right and this test will fail so this is where you have a dependency on underlying system and that underlying thing keeps changing so your test is bound to fail if you leave it like this so what I did is I said this test extends fixed time test case where I am going to do here I have when I extend that I have to override a method which says what is the current time so I have to fix the time and all my tests are running against the fixed time right does it depend on the time zone does it depend on leap years no we have not gone into that but in the real system we had to take care of all of that day light savings all of those things we had to take care in the real complicated one so this problem seemed like that's like a two days worth of work ended up being a month more maybe more than that alright does this make sense I showed you in this approach if you do the outside and you soon hit a road block so inside out might be a better approach for something like this people are here to throw me out the last problem that I had was a meeting assistant alright so what is a meeting assistant going to do so one of the common problems is I walk in the distributed teams I have six people on my team and I want to figure out when I can meet all of them right for 30 minutes so I need some kind of a meeting assistant who can look at everyone's calendar and figure out who is available and what is the earliest 30 minutes lot that everyone's free right so I want to specify the duration and I want to specify who all I want to meet and I also want to possibly specify a time out there's no point meeting for this after three days right so those are three things and I want to build a meeting assistant so what would be your first test group work in your groups don't tell me the screen that's just an example of a calendar then I'm saying Jack busy for next two hours so Jack is available in two hours forever first available slot for 30 minutes is in two hours Jack is available later for a required duration we're saying Jack is available now for this much time Jack is available two hours later it should give you whatever for 30 minutes because you're only available for 20 minutes so then it should give you two hours later and then you can bring in now another character Jack and Jill and you can say both of these have the calendars that you've set up and then you're saying between these two the first available slot is it for 30 minutes is now right so that's a style of writing again outside in way of writing tests for this there can be many characters why did I only choose to because if it's two or more it doesn't make any difference as a programmer I know it to is sufficient I don't need multiple maybe I would write one test for multiple just just to test but for majority of my development I can just deal with in fact I started with only one for a large chunk of my initial development I only did with one then I brought in the concept of another user and at that point I said you know knowing my implementation I don't need many users maybe if I was not confident I would have added four five users and tested this out all right so that's pretty much it it's three o'clock and I think it's time to wrap up thank you guys if you have questions I'm going to be around and we can take more questions all right