 yes great hi thanks thanks once again for coming for the PHP Meetup so today my talk will be about how to refactor like a boss so how many of you were actually here for my last presentation quite a few you know over there right yeah right so in my in I'll just go a quick recap from part one all the things that I kind of covered so let's see how how that goes so question is why is why is refactoring why do we do it right so my hypothesis is that software left alone would decay so if we don't touch your software after a while you'll just get get stale and it become irrelevant so we need to change it so change made to the internal structure so basically why is refactoring refactoring is a change made to the internal structure of the software that makes it easier to understand cheaper to make future changes and it also does not change observable behavior of the software so when you refactor a code you should still perform the same way as it should if you have test coverage that helps you understand that you have actually make some change that changes behavior that would be good if we don't have tests then you got to have some QA guy who go through the do some regressive regression testing and all that which is quite stressful so basically refactoring a code shouldn't make any change to behavior of a software and overall it should improve the design of the code basically should improve the design and readability and how well it can be maintained in the future basically the two important things easy to understand make your refactoring makes your code easier to understand and also it gets cheaper to make changes so this is how you can justify to your boss that your spending time refactoring I make I'm making it cheaper make changes in the future okay that's how justify to your boss when you say when you're spending time doing this of course having help test does help you ensure that you did change your behavior right so which is why test driven development is important and I think it should me become try make it a habit to write tests before I write code it's hard I know but you know I'll show you some techniques later so some of the common free fracturing techniques I covered I covered some of this in the last last talk so we'll see first of all is how change your names to communicate intense because full and bar doesn't actually communicate intent right it should be like first day of last name or something like that and we take away all the magic numbers so you have things like exchange rate and all that stuff in magic numbers somewhere you will put it to pass it to a variable say that variable name that gives it intent it helps you understand what it is and try to keep one responsibility per function basically your your function to try to be as small and lean as possible and only does one thing at a time right so in the last session I actually went through quite a lengthy discussion of how do you should how you can refactor a very simple test code so today I'll be touching on the last last point which is do not be obsessed with primitives right primitives what are primitives primitives are basically you know associative arrays arrays that you pass into your code right so why is associative arrays are awesome as a generic data container so basically you passes it just is the best is a generic container for all sorts of data of information information about what's in the shopping cart information about what's in you know how much you've spent on something or how much is this user buying from your website it can be very awesome for just storing all sorts of generic data but they do not communicate intent right unless you have a sociable because you have a kind of associative arrays if you have name but then you can't be sure that the name will always be there you can't be sure that the associative array will always be have the set right so why we may have to make changes in the future so you may have if we make changes in the future if your associative array doesn't for some of your associative array you change the payload and you change the name of the key right and you don't have tests that covers you you mix it very hard to basically mix your your API very brittle right so basically try not to be obsessed with just passing arrays or associative arrays around so in the alternative to doing this is to basically use classes and models so in the last talk there was a talk about ORRMs so ORRMs is actually a very good way of extracting away behaviors right and simple classes is well so good for encapsulating behavior so what you want is to have behaviors communicated to a class rather than having you do sorts of all sorts of funny things the second point will be switch to a compositional approach basically you compose and create classes to that they can mix and match together having classes that has each class having its own explicit behavior and other classes having an explicit behavior when you put them together they can have new interactions where individual objects that has individual its own way of behaving when you mix them together in the novel different way you can then have new ways of using them always use so use objects that work together so basically yeah what I said earlier about composite compositional approach so in the last example we have a last last week's last month's example we talked about a club membership register so just to recap to you maybe I'll show you how it looks like the wrong one yes so this is right so the membership register will basically is a CSV file a CSV file which is where you will pull your membership record and then you have a way of adding new members and in the last in last week's last month's refactoring we actually broke a one single function in which was something like this this original function which has basically things like add member which is an add member function and then we broke it down into four different three different functions which has each each each of the function having an explicit behavior right so we have one method that tells us that gets the member and ask the second method asked me is this member in the list and adds it to the file and then the actual function that actually gets implemented or rather the one the function that gets used in the API is actually quite straightforward if I can scroll down to the bottom so to use this is basically just a matter of passing in an array an array of names which will basically because and then related to remaps to a CSV file so I felt is the fastest and easiest way to implement this is just passing an array which then gets used and inserted into a CSV file so this is the first implementation which we covered in refracted so this the API is very straightforward it's just passing first time last time an email because that's how the CSV file is kind of structured right so it's the first bit so yeah so so as soon as you array a passing add member blah blah you check with duplicates duplicate email you you would not insert if there's already in there yeah so basically some simple simple simple checking and then the actual act of inserting into the into the file is is also handled by a separate function right so you have done that and your your boss and all manager is happy but your manager can view again rubbing his hand saying hey you know I'm thinking of adding a new field to the CSV file right to this register I'm getting confirmation from directors but in any case you want to make sure that the script can support say and address few right for example so we have first name last name email and now we want to address few which means a fourth column in the CSV file okay so assuming we cannot move away from CSV we'll stay with your CSV so what should we do right so how do we do this well a simple approach would be to say you know just add a new item to the array right so we have the input array that I show you earlier on which has only which has three things first name last name and email right so let's maybe add a fourth item you know like first name last name email and then put address assuming the fourth column will be the address field right so use the same method and it should solve the problem right but what if what if the boss becomes so enthusiastic as they look I also want to capture the phone number or maybe some other information about how much they're earning and so on that so what this happens in the future what do you do if you follow the same method of doing this you means you have to keep growing the array the ray has keep growing growing growing which can become a little bit crazy so what if they also decide to change the order of the field say oh maybe email is more important because we want to make sure the email is the real true primary key and they want to change the order of the input field which makes it crazy right that means oh no may all my code will be broken because I expect the first column to be first name right you can't get this kind of a request at work you do right okay that's not good okay so yeah we panic and say no maybe this is not the right approach to solve this problem right so what we want to do is take in terms of business logic what we want to do so instead of modeling a new member as an array let's imagine it as an object as an object with attributes and behaviors so basically OOP to use the OOP approach we model it as an object so how do we convert a procedural code which I've shown you into a object or a rendered code simple way of doing this in the industry at least what I've tried and successfully used is this thing called CRC class responsibility and collaborators how many of you have heard of this term CRC no okay well it's basically it's about going to the drawing board and drawing drawing a little card like this and say this is a class name this is what a class knows and what it should be doing and these are the collaborators the people and other classes that you actually work with so basically what this class knows and what this class is responsible for you write it down on the left column and the collaborators who what you actually have to work with yeah you have to instantiate or work with or have to rely on for example and these are our collaborators who are these other classes you work with so one way to modeling this is looking at so we're dealing with a membership registry right so I think the first obvious class we have is a member class right so what does what does member know what does a member class know why is it responsible for you know the member class knows about the first name the last name the particulars of the member right this is the first thing that we know so he knows what about membership about the members particulars so we also want to know about so this is a club membership right so probably has a club membership register which is kind of like some some container that will have a list of members this container also know who are the current members because based on our the use case of our application is that if I add some if I add a new record you must make sure that I don't add a duplicate person for example so you need to know who are the current members then you can also add a member you also probably needs to as it is now the function kind of does insertion in the database you know inserts of the item in the record and writes new members to CSV file and the collaborator that this membership register work with the collaborators is basically the members right so you basically the member class has his own responsibility the membership register class has his responsibility but it also works with members because he relies on how does it know that this person is already in the database by checking the particulars of this member class right this member particular so we look take a step back this seems to be a fairly straightforward implementation but wait do you do you get a sense that the membership class is actually doing too much right it's actually you know it seems to know a bit too much about how we store the data right our previous implementation had functions that was broken out of different things and maybe we should try abstract that behavior away because we seem to be in insertion of the stuff in the database should probably be a separate class so this how we restructure it so we are still have a member class we still have a membership register but it knows less things now so the club membership only knows about the list of members who are current members and how to add a member and then as it collaborates with the members class it also collaborates with a data store class which will which will create later data so class will be could be a ORM or some database connections that you have right so it's this data place this data store class could be abstracted away and the data store has only two responsibilities it's only responsibilities to read the CSV file and the right to it right straightforward right so three different classes with three distinct sets of responsibilities and they have you know from this diagram that who are the collaborators it could possibly work with because the membership the membership register is basically the center of the application it collaborates with the member class to find out who are the names and also use the data store class to basically read and write to the file right so these are the collaborators that membership register works with of course you could also go back and do some bit more thinking about how this works and maybe we refactor it a bit but let's work with this for now okay so based on your procedural code that you have you draw CRC cards you kind of figure out what are the collaborators what are the responsibilities of each class so this helps you in clarifying of getting some clarity about what your models should look like and how your how you should model it and all your classes what you should be doing right so from the previous one we looked at it has a smell it that the class has too much responsibility which is very good for you can sense the same sense the tingle in your spidey nerves or whatever you know spidey senses that is bad is bad okay so yeah so we have this thing so how we form that small little diagram we kind of like translate into a kind of like a model structure or rather a class structure so we have a class which is member has probably knows about the particular list so now current as is so what is the what is the rule of refactoring refactoring shouldn't change the behavior of the code right so based on what as our code actually doing now let's refactor it and make it reflect that behavior in our database and CSV file right now we only store the first name last name and email address is possibly in the future but has not been confirmed yet right so we take our current existing behavior first name last name email make put them as public attributes then we have data store which basically has a has basically a read all function and append function which basically appends the data into this into the CSV file and then this the heart of our application which is basically the one we will eventually use is say it's just add member and add member will collaborate with is is in register and all members basically will pull all the members and check whether it's in register right so understand so far are you over me so fast cool right so let's write some tests so I believe in test-driven development like a religion so basically use test to guide your development features so basically how you the features they're going to write use test to kind of guide you along right I see as a kind of like a way of discovering how you how you should write your classes so test are important and ensuring that your code changes and does not affect existing behavior of your code so basically you want to make sure that your test will help you in the future that it will not we make changes in the future you will not break anything and the way we do TDD is basically we write of tests which doesn't have any code implemented yet which will basically fail we call that a failing test they write the test that kind of makes it work the minimum amount of code right to make it make the test go green from red to green and then we go in and make the code more awesome basically we do be more refractoring reduce with stop repeating ourselves take out redundant code maybe we imagine how we yeah so basically refactoring is the last bit make it green and then make it clean so right test so I use PHP unit how many of us here use PHP unit no yes awesome great okay so p3 unit is basically it's like it's a class on his own you're right you're using classes to write to write other classes which is class section never mind so first you have a we'll test the constructor of the force of bodies test over here we're testing the constructor of the member class we're passing in some these are the certain values that we want and this is what we're passing in to say an imaginary member class we have not created a member class so we have just written a structure of how you should look like so assuming your class looks like this right now and you apply this test you apply this behavior my behavior is when I pass in an array of associative array of first name last name and email to all two members as part of the constructor the resulting member class should have first name set as the first name last name set as the last name and emails as an email right so mine you have not written a single line of of implementation code yet right it's just public assesses so we have public we're public first name public last name so these are three attributes here we apply this test we run this test what do you think it would happen we don't have a constructor yet so constructor doesn't know what it what to expect and what would happen in your first run of the test yep it failed because it doesn't know who you didn't it somehow the first name was not set so the first first sign of rate so do not be afraid to see rate because it's a sign that you're doing something right or wrong never mind so basically you look at the error messages why is this telling you is telling you that you're expecting Michael but Michael is not there right what's going on okay so this is right feeling this is the right feeling test so we done test test driven development for a while that you should you would kind of have a sense of what are the right type of feeling test and what the wrong time of feeling test if right now feeling test would be I expect this to happen and it really not have is really not happening right a wrong time feeling test would be but it failed for an unexpected reason right for example you it couldn't for example I cannot find the member class what does that tell you if the error message says I cannot member class is unknown or not found what does it tell you you're probably not including it or requiring the the member members of PHP in your test in your test suite right so that's a wrong type of feeling test the right type of feeling test is where I read this something like this like I expect to find the first name the first name is not there so let's go implement the code right minimum amount of code and say look this is the first name so I expect that the API I'm expecting is I'm your I'm expecting an associative array the associative array has first name last name and email and I will set it accordingly I'll set the attributes accordingly right so this is pretty much a very simple implementation and of course the part the test is passing right now so let's take a look at the code again right how do you think this code can be made better how do you think this code can be made better can you see can right I figure out okay don't you think it's a bit cumbersome to always set the field name explicitly you find it kind of weird that if like say I have to add address or I have to add gender or something it means this constructor could grow right this construct will grow quite explicitly so it might be a bit strange to do it I mean it might be it might not be able to do survive too much changes in the future right so let's try and make it such that we only if there's a new field we only really make the change to one line of code rather than seven lines or eight lines of code based on you know yeah so how we do this okay so a simple loop like say we know that it's going to be an array associative array we can do it for each loop and then we have a say a static method which kind of declares the known the known field these are the known fields that we kind of will have in this class and then we can set it explicitly right with a variable variable huh well if assuming I have no option to use ORM but an ORM would actually have this discovered for me but you know but let's let's let's put that aside and just deal with just simple plain old PHP classes right how will we do this so this is how I will have done it right so I have an explicit list of known known known columns known fields that you would have so in the future if we add an address or phone number where we change we just to change this one line of code right of course to make it more readable you want to make a multi-line I can kind of like you know but still just one point of one point of change right so it's how you can make your future changes cheap or rather make your future changes not so expensive right because yeah and then how do you okay so let's look at this look at reverse look say if I add a new field say address how will our test be amended to reflect this yeah it's a test again so how would this test be if we amended to reflect the new field well it's simply just a matter of adding another assertion at the bottom right right well this goes so we also could also be refactored right we're not just refactoring tests code we also can refactor tests right the same method that we have we have used to put a static method with an array of known fields you can also do something similar right so basically based on what you expect to be known in the to be known to the class I can actually use that and loop through that I can use the same static method look through it and look at this so basically I want I will use the test the codes the members own I could basically use this guy where is it yeah I instead of turning this in a private matter it could be a public method there's a public static I can actually access it outside of the class which means I can use it in the test so test can then use this field to loop through to check itself right so that's one way of making your test a little bit more a little bit more like future proof extendable right so that's one way of course there could also be a clever alternative so we could use some very nice PHP function such as array walk this is very interesting function you know PHP has a lot of like array manipulation you know stuff so you do like array walk find the known fields and you have you pass in a use functional programming to kind of like pass in something and then inject it into this guy it's very clever code but it's definitely not readable right you will find your your most smartest engineer in your team doing something like this just smack him in the head right this is totally unreadable what the hell you trying to do right so so there's a there's a limit to how you should refactor all right you should you should refactor the way that it makes easy make changes but not in up to a point where it makes it impossible to understand right that only you understand it that's wrong okay so that's yeah so so clever alternative like this wouldn't make sense so after some time you basically you rinse I repeat all the what a simple all the tests so after some time working through all the different classes this is kind of like the final implementation so the member it's the member itself again has a known fields it has the same thing I also initialize a member basically I want to have a way of initializing a record easily so basically I pass in a pass in a record or array of sorts and they construct the member and returns a new member so it's kind of like a a factory a factory method of sorts okay you understand why I need this if you're going further down I also implement a little function called equals so basically from based on this from your object comparing with another object is that the same guy right something like that so it has some form of deep equivalent checks inside so for me remember from the last month's example you first of all check whether email is the same and also check whether the first same last thing is the same so this is following the same use usage that we had in the last month's example and then we have another method called values which will basically be used to kind of derive and get all the public attributes that can then insert into a CSV file so CSV data store so we have a in my earlier example where I talked about a CS data store right rather in the earlier CRC class we talk about a data store well maybe we should name the thing a bit more appropriately right naming a naming a class with the right names also communicates meaning data store doesn't tell you what kind of database is using right so CSV data store is a way of communicating intent basically the this class is meant to be storing the CSV files so basically it's a matter of just creating a CSV file pointer and then passing in the file handle and this is actually all right sorry this is actually deriving a name so in our earlier example in the last month's example the file name is actually hard-coded into the function right which can be a little bit un-extendable basically in the future if you change your file name then you have to make a lot of changes in the code but you can make it part as part of the constructor and say I want to make I only read from this file name or that file name so you could have you could create like I know files based on alphabets all the a's will go into a file all the b's go to b file something that so you can actually change your file name if you want to right otherwise you use the default default value which in this case is just member CSV and then basically creates a file handle which is a instance attribute which you can then use anywhere in your class so this is where it reads all uses the same file handle it will winds it to the top loops through it and checks and then returns the data so basically I found that in the earlier test that whenever I do a insert it will put the pointer at the at the very end of the file right so we need to probably do a rewind to move the pointer back to the back to the first record you would discover this in testing right you'll find these behaviors like this that happen so yeah so as his own attribute or rather array you do an array push to push into the data then just return the data so this is just returning arrays right at this moment and then here's the heart of the application so the application first of all it takes in a data store so it's what I'm talking about a compositional approach you have in your the creation of your class you also you also inject a dependency you're telling it look you shall depend on a data store and this data store will implement certain API certain have a certain predictable behavior your data store has a fine all and then a pen and maybe a delete in the future for example so you could easily switch out this object with say my SQL data store right which which implement the same API is fine all you know append the database which is just an insert and delete which could be just a remove right I'll just just delete from database for example so this is a compositional approach where I would basically pass in an object and this helps you in testing we're writing a test sometimes you want to minimize your connections to the database so you can actually pass in a mock object mock object which expects certain API to be called right which means don't need actually need to make a call to the database but as long as you call it with the right API when the right attributes it returns certain value which you can then expect right but in this case I'm also setting a default value say if you don't pass in a data store I'll I'll just assume that you're using a CSV data store and then just instantiate that right so this is a very good way of injecting dependency but also having a way of having a fallback in case nothing works all members basically just goes through and reads all the data from the CSV file so from here it gets all the records see here is collaborating with data store reads all which is a method of all found a data store gives all the records as an array and what I do next is that I'll call this method called init member so what is the clever thing over here is that I'm passing in the record which is a full array into and I'm calling init member on every single object inside the array right so this gives me an array of like say five of five items array map basically what it does is basically on every item of every item inside already you call this past this you call this method and passing an object right which is a clever way of like creating a instead of getting an array of arrays you're getting array of associative arrays you're getting a array of objects is it clever okay fine I write clever codes and okay and the question is is it in the array is it in the registry so basically ask itself is are you in are you in the registry we should call the equal method which I talked about earlier so based on all the members that you have passed in or these are the members I know of is this member they are querying inside the list right so basically simple as that and next would be basically the actual the actual method that gets caught to inject or insert a new member to the database right so here we are you calling I believe we are calling get value sorry yeah so basically new member dot value this will actually give me an array array of all the items I expect and then appended to the database and it returns true and then the remember we are not changing behavior of our code so the code the original code that you that we that we have is basically a plain old function right we don't want to change that code too drastically not yet at least so we want to keep that original function and original API but what we're doing instead is we are you surrounding that procedural code with object oriented code right so basically over here for example we are creating a new instance of club membership and passing I'm getting it in the add member function which will then call but first you initialize a member and you are and you basically try to add the member to the list so the same behavior that we had before no changes to the behavior right which means this method remains the same until you have an opportunity to refactor your change this actual implementation right into from a procedural kind of thing to the object oriented kind of thing so yeah so basically this how you can make your object oriented code collaborate with your procedural code yeah so yeah so when you're moving away from procedural code or this this hopefully a suggested way you can learn so a cleaner approach will have been to revise that member function all together so we say instead of using the function here let's change API all together the API shouldn't be using this animal it should just be called using objects directly right so this is you've got opportunity to change the implementation but if you don't then the previous example will be like it would be a good way to move forward so possibly when your manager confirm the change and you can actually change this code and whatever yeah any question so far any question so far are you are my examples clear need some feedback thank you okay so what have you learned so far so we basically use CRC cards to identify boundaries around domains entities and models right so we we use CRC cards to discover what are the responsibilities that these more objects should have and what are the people what are the other classes that it collaborates with this helps you to slim make your make your classes slimmer and leaner basically they only be doing one thing your and your methods also be doing logical things that only associate with the class we also use test-driven development to guide you so basically a good way a good way of thinking about it is that a test is kind of like how in an ideal world I will like to interact a test is kind of like in an ideal world how I would like to interact with this object right in an ideal situation I I will want this to we see first name last name and something else right and it has to be reasonable so having a test helps you to like imagine in your ideal world situation how I want my models and objects to work right so basically what you're thinking will be if I pass this code on to someone else and he reads this test you should also have a same aha I now I know how this object works because your test will be able to expose those behaviors right so a test driven development TDD is a writing test versus a good way of kind of like helping you define before you write the code before you write a single line of code help you define for yourself in an ideal world how will I write this code how I want my fellow colleagues to write this code that I can understand right so it basically a test also ensure that your changes your change be your changes doesn't affect behaviors of your code and of course having test also helps you ensure that you don't introduce test introduce bugs rather test writing test and also what I found is that writing having tests actually make gives you more confident in refactoring code just imagine that little piece of code of code that I that was written earlier on I don't know whether I can she find it the little piece of code where the first implementation of of the constructor for example the first implementation of the constructor makes I just in basically I'm setting your first name last name blah blah blah without test how would you how confident are you in making that change right having a test helps you ensure that you you can confidently make those changes that you want and not having to worry about am I introducing a bug because your test to help you cover that right the test will basically save your ass right in yeah so I found even in right now I'm doing Ruby professionally it's like having tests just gives you a lot more confident in refactoring stuff that you know they won't break anything right so one last caveat is only introduce backward incompatible API only as a last resort because you know that going forward if you know going forward that this particular way of doing things is bad for your to cut the health of your code and you should change the behavior altogether like the example that I gave about how ad member is still a procedural function let's change it into an object or rented way of doing things right you know going forward like for three months down the road you basically reap the results reap the rewards of doing that kind of refactor then go ahead do it right but only we introduce that as the last resort for example at yeah replacing at member procedural function with a cleaner implementation which is full all right for example that's all I have and you can find the code here I have the full examples that that I have shared with you today so you can see the test as well the code I have is fully tested I hope it's fully tested you can find sorry it's not tested set of full request right so yeah thank you any questions yep I think you will have a luxury of time you should test everything I think we call some we have we write I write tests for models mostly because mode the models are where you have your business logic and those things cannot fail those things cannot break so that's the most critical hits of your code we also write test for critical path like say interaction with your application I say to add something to cut check out make payment the critical parts of your application these are the parts you need to that you know that your business cannot do without those are critical parts that you also test yeah any other questions I think personally I will only go okay we will get a legacy code base and you need to work with I what I did previously was if I'm going to introduce new features and all and those new features also touch older code I'll take the opportunity to write tests for the older stuff right I'll write some simple test to cover the open older stuff and then also write test for the new stuff and I'm writing that will cover both things so slowly as you as you build your application or add new features your new features no doubt somehow other will have touched up old code so you think I'll put you to write small tests to check the old code and you can use the opportunity to also refactor you know it's on the older code that you work with has some has some good improve from some some refactoring you write some you write some tests you write the code or you refactor the code right so this I will take a gradual approach and not do a clean throw everything out that will be right I think I will just take the opportunity as it touches the old code write tests make the fact make the refactor and also write tests for the new stuff you're introducing yeah so that will be approached I there's approach I made I had back in when I was looking at me for the tree so we are to refactor the whole login system but because the login system touches the minus some database in the back end so I actually we actually took opportunity to refactor some of the old classes I also wrote some tests to make sure that I didn't bring anything right a test coverage will be good way of okay I expect old old very old class to behave a certain way that's why some tests will actually make sure that she's supposed to work in that way and it is working that way they make the change and still make sure that it's to give you that result right so a gradual approach will be what I would like yes it's going to take a longer time than normal development test room development is at the very beginning when you're not used to TDD you will definitely time sink setting up your test harness or the HP unit or the stuff and getting familiarized with the way of testing that's the result in some downtime in the very beginning is no doubt about that because as a team familiarize themselves with the ways of testing the way of the way around writing code because and there are some code they're so spaghetti and so tango it takes some time to cut understand where are the where are the seams where the seams that you can okay this is the part where we can tear apart and say we can test this part separately as from the other part right so fine it's going to take a while for the team to ramp up but once you reach a certain once a team has some familiarity in how on how the testing framework works and how best to tear apart the code in that it makes it testable once your team has become familiar with that it would be much faster but it still we can assume 20 30 percent times of writing the actual code it will take even team experience you know correct so but I think yeah what I used to work at a startup and you know that the startups were like oh we need this feature yesterday you know like dude we don't test this it's good if it breaks the future is it's going to cost you money but no users for the product versus if yeah if we are making a product of course well again it's a compromise right it's a compromise about how much you want to write how much you want to how much test to write and how much you want to develop how fast you want to develop the product right so we've got enough QA people to cover your ass then it's fine I wouldn't put my I wouldn't put my bet on it on the long run but yeah QA is done by QA so yeah QA is the more advanced QA to be writing like salient as they would test the integration level layer that those tests are invaluable helps it helps you check regressions and all that other stuff right but then they only see the side effects they don't see how the code is put together and what how how it's how it could there could be some hidden bugs that you don't know about you know so about is yeah so yeah what's the code yeah yeah yeah it I think it's always a have a technical that but as long as don't make too long yeah technical that that you can just go forward first and then try to refactor the one that you can't refactor so this is always a technical that is impossible that you can finish all at once yeah so you leave it like that but make it like for me I make it like not more than 30% that's my technical that more than that I have to finish the 30 this 40 and make it 30 again I make it like that yeah I think one way can help will be to use something like continuous integration server I say Travis CI or code climate these are two very very nice free tools you can use so what this what they do what they have is they basically take a code run some tests and tells you information about how many how much how many percent code coverage and it tells you about bad coding practices like too much copy and pasting and too complex so code climate is wanting to check out Travis is one of those ways they can run the test so everyone can see yeah I would suggest putting spending time putting putting together a test suite is one thing having a way to let everyone in the team have ownership of the code is having to have like a CI panel that everyone can see is made of green something that so when test fail is that oh really look something is wrong someone's push a broken test helps your team get some ownership of the process yes seems to be there's a bit of there's a lot of skepticism is to do 3D or maybe even to do tests in the first place we asked about compared to normal development I could ask the question does that already do three tests so my question is what would you take as the major selling point to do to go for this approach to say let's do tests in the first place let's invest 30% more time to do tests how would you convince an organization to go that way I mean it's going to be cheaper to make changes in the future if we actually do tests and you refactor your code okay test having tests and refracting a code immediately like the leading way of doing things having a fairly test passing test and then refactor immediately it's actually very good in the sense that how many times I've written code that you wrote two months ago then QA came to you to say I have this bug right now and then you think oh shit how did I write the code again what was that thinking when I wrote that code right and then you have to spend time getting back all the context that you had you had two months ago like alright I wrote this I wrote this lot of code because I was thinking about that and this and that and then got distracted by this product meeting and came back I forgot about to write that the times I did done that it's quite embarrassing anyway yeah so having having tests and being able to refactor it means you have immediate feedback about where your code is working having that in having the urgency and then being able to refactor it on the spot means you still have context about that code but why you've written that way one way that we can mitigate this or make it easier to write code and test code is to do pet programming right pet programming two persons working on the same piece of code together the different styles of working what the style of working is called ping-pong basically ping-pong right so I write the test I write the test you write the code I write the test so it helps you have some fun factor in writing this I've written the ultimate test I dare you to pass this if you have some fun to the coding experience but it also means that the knowledge about the code is shared amongst two persons it improves the it reduces the risk to your company basically if someone goes away or has an accident or fell sick at least the other person who had worked on the code before as pair would have contacts and know how to fix the problem so that's a good thing of that and having a test trip having a pet programming also help in the sense it has what I call extreme code review I mean I've sat next to a developer so many times and same as us because of typos do you spell it wrongly do you spell it wrongly you know and they the variable was actually this I gave the wrong name in the implementation sorry that extreme code review helps as well right in reducing all these bugs possible bugs that go out I'm a big advocate of code pet programming so if we can please do it I encourage you to try it and having that and makes it easier to help because right then the burden of writing tests is shared between two persons right and you know and then basically you can focus like say you do if you use a ping pong kind of method so one person will be focusing on how to structure the test how to prepare the test in a way that you know think think about think about the fixtures that could be required and needed for this piece of code and the other person will just focus on how to write code in the most performant way and how to write a code in the way that would be you know that you can easily make changes in the future right so I would be a little better if you can afford it if the company can afford it please try it actually the way QA can also be your pet anyone a designer to be your pet QA to be a pet for not manager to be a pet this could be a way of helping them understand what you're doing right so that's one way to try to have a more shared responsibility amount with you and have a share of the shit for everyone I hope I hope this makes sense any other questions okay I can be reached at Kodokongfu on Twitter you can you have a question you can tweet me or Facebook message me or something actually that's all I have