Coding Blocks - We’re Testing Your Patience…

Episode Date: December 15, 2014

I figured this title was appropriate considering it's been a month since our last episode.  We've all been incredibly busy so we hope you've been patient waiting and maybe, just maybe it was worth th...e wait!  We've crammed quite a bit into this episode which is all about testing.  Follow the more link to see the show notes for this particular episode and don't forget to click one of the share buttons there to let all your friends know about the podcast!

Transcript
Discussion (0)
Starting point is 00:00:00 I got a very important question to ask you two guys, okay? What do you call an elf who sings? Snelf. Okay, I got snelf. Nothing? Nothing. Come on, man, so easy. A rapper.
Starting point is 00:00:16 Oh. You're listening to Coding Box, episode 20. Subscribe to us and leave us a review on iTunes, Stitcher, or more using your favorite podcast app. And with that, welcome to Coding Blocks. I'm Alan Underwood. I'm Joe Zack. And I'm Michael Outlaw. And let's get into it. It's Crib-a-time!
Starting point is 00:00:53 And I know we're like a month late getting back into another episode. We can blame Outlaw for all that. Whoa, whoa, whoa. With it being Christmas time, Jet jet brains comes through in a big way resharper nine yes yep not as cool as that uh doomsday deal they had a couple years ago with like 90 off everything but that was so awesome mayan calendar sale oh yeah man it was like 70 off yeah i think yeah man i wish they'd come back with something like that you know their sales would go through the roof well i, I guess depending on,
Starting point is 00:01:25 uh, what your needs are though, they do have a new bundle called resharper ultimate. So they've, they repackaged or I don't know how you want to say this. They've redone the way the skews were. So it used to be, you would buy resharper for visual basic resharper for C sharp and you'd buy those individually.
Starting point is 00:01:42 Now, no, that's just resharper. And they have this resharper bundle now where I want to say it was basically for the price of two licenses. You're basically getting, I think five or six, but,
Starting point is 00:01:54 and this is why I say it depends on what your need is because the other part of those products that you're getting were specific to C plus plus. So if you're not doing a lot of C++ development, ReSharper Ultimate might not be for you. I also noticed there's slipping more and more JavaScript stuff in there, which I guess is a sign of the times. Oh, you're loving that these days, aren't you? No comment.
Starting point is 00:02:19 All right, so what else? Oh, Progress Software just acquired Telerik, which I don't know what that means to the software world, but I know there's a lot of users of Telerik tools, especially in the.NET community, so something to be aware of. You know, we just got through November. We were talking about all the gaming. It's game season.
Starting point is 00:02:42 Yeah. Call of Duty. Anyone? I've been playing the ever it's been awesome yeah that game is amazing and you were dogging it before like oh there's just gonna be new maps that's all they ever do is change the maps it is so awesome no this game is this game is off the chain it's it's incredible the boost pack is fantastic i love just jumping around everywhere and actually i decided that i just wasn't to get it because I got all the old ones I don't play.
Starting point is 00:03:06 But then Patrick Dahl had to go and build a computer and take pictures of it. And then I had to build a computer. And now I got to do something to try it out, right? But you got to get a big video card. Yeah. Mine's not horrible. I don't think Call of Duty requires a big video card. No, but it doesn't matter if you need
Starting point is 00:03:25 it or not we're going there yeah yeah um and and speaking somebody else also mentioned shadows of mordor being on the console so i did get it on the ps4 it's amazing i was going to ask while we're on call of duty before we left that though did you finish the campaign i hadn't even started i've not played a minute of the campaign. Camp what? All right. Dude, I accidentally figured... Sometimes the storylines are fun. I accidentally figured out how to thrust sideways.
Starting point is 00:03:52 I didn't even know you could do it. Okay. No, I haven't played a second of the campaign. I'm off on my own over here. But no, Shadow of Mordor is absolutely killer. I mean, I know you play it on the PC, right, Jared? Yeah. I guess there's no point in asking you guys if you're an Atlas or a Sentinel.
Starting point is 00:04:06 So, you know, never mind. Oh, no, I don't even know what you're talking about. Yeah, clearly. Wow. All right, Mr. Boost Sideways. Interesting. Oh, okay, because I guess in the game it actually matters. It matters.
Starting point is 00:04:19 I guess the ending is either green or blue based on your decision, I guess. Is that the deal? Oh, no, that'd be red or blue, and that be halo oh okay no master chief collection come on no i've definitely got some things that should be coming in the mail from black friday so so we'll see all right so yeah i guess the next thing let's let's talk about we've got so it has been a month since we last did our podcast and we've gotten a ton of reviews so this one was was just awesome so i've got to read this one this was from holy moses intelligent plus and useful like really moses like like moses came down and parted all the reviews and laid this one down upon us i think that's what happened man um so intelligent
Starting point is 00:05:03 intelligent plus useful times entertaining equals perfection which humbling but um i'm a beginner programmer and found this easier to understand and way better than my sleep inducing college programming class it's also a nice break from the chaotic dumbed down ebola pro sports kardashian. Keep up the good work dudes. You make fun learning. You make learning fun and free grade a plus. So, Hey dude, we really appreciate that.
Starting point is 00:05:30 That one actually made me smile. Every time I've read it, I've, I've laughed Ebola and Kardashian in the same sentence. Although I'm huge into fantasy football and it kind of hurt me that you bashed on sports. So maybe it started out as there were 11 reviews and he dropped one of the tablets.
Starting point is 00:05:47 I bring you these 10 reviews. So yeah, that one was awesome. Also, uh, Arnie good. So he actually mentioned, or she,
Starting point is 00:05:58 uh, to see future episode on software testing and testing methodologies. And that's what we're doing this week. So this one's for you. Yep. Yeah. Uh, testing one's for you. Yep. Yeah, testing. One, two, testing. Right. Yeah, very nice. And also, last episode we asked if anyone had any real-world example of the visitor pattern, which we had begun to doubt. And we got two responses, Trent Apple and a comment on the website, Lol. who both responded with the expression
Starting point is 00:06:23 visitor. So we'll have a link to that in the show notes. I can't actually say this is, for a fact, an example of the visitor pattern because I still don't understand the visitor pattern. But according to Google, this is a great example. So thank you very much. Yeah, and let's bring in something new here. Let's bring in the mail.app. We get some mail occasionally, and you guys write in to us.app we we get some mail occasionally you guys write into us and
Starting point is 00:06:46 sometimes we're we're good about responding to it and sometimes we might be a little delayed in our response shadows of mordor yeah you know so so we got this awesome one uh from ray he writes sentences stumbled across your podcast recently and as a long-time developer found them to be one of the most useful around you You actually discussed real programming issues. Regarding your discussion on episode 17 of use what you know versus try something new and the cost of development platforms reminded me of his own situation. He primarily writes in Visual Studio and.NET, VB or C Sharp using MS SQL, and he wanted to write a simple data tracking application with very object
Starting point is 00:07:26 oriented storage requirements, but he hates mapping objects to relationships. So he wanted to try using an anti SQL object oriented database. And he found DB for, Oh, it says it was a simple, it was simple to integrate with visual studio. Dot net examples got me up and running within an hour and it was free.
Starting point is 00:07:42 Unfortunately, it looks as if support has been discontinued, but it is still available. But it was a great experience and worth venturing outside his comfort zone. So he talks about maybe we should consider doing a podcast on object language to database storage mismatch and discuss specific ODBMs they can be used for everyday applications so thanks ray for writing in and we'll put that in the bucket yeah we we've definitely got a long
Starting point is 00:08:14 list of things to do but that's one that i think probably all of us are somewhat interested in so yeah i like entity but it's kind of a pain to set up with the code generation and everything and i know there's a couple um yeah it's a pain if you're doing something little something exploratory then using a micro framework like massive or like pita poco or something like that it's so nice to just say like you know what here's my class here's a result from a query put them together i'm sure it's using reflection in the background but i don't care i'm just having fun you know what the problem is is that exploratory stuff always ends up becoming like the legacy work. Right.
Starting point is 00:08:47 Yeah. You know, you end up just building upon that. You're like, you know what? I'll refactor that later. You know, it's small today.
Starting point is 00:08:52 It'll be fine. Version 0.1 becomes 10.0. Well, I'm not on my couch. It reminds me of a friend of mine's, uh, uh, you know,
Starting point is 00:09:01 the little message he has on Twitter is like, uh, you know, it says something like writing tomorrow's legacy code today. Right. So much of the stuff I write on my couch ends up never leaving the couch. So I'm not too worried about that. All right.
Starting point is 00:09:15 So we also got another email, and this came from Louis. He said, hey, guys, love listening to your podcast. Could you add a list of your recommended tools i listen while biking and i remember the vague basics of some tools like the command line replacement but i can't remember the actual name searching for it is time consuming thanks so i know we've got a ton of them i i probably i use con emulator which might be what you're talking about it's con emu um i love that one oh because when he said command line replay i thought he was talking about like in some of the tips we've talked about like deleting lines of text or replacing lines blocks of text yeah i think he said that yeah i think he's talking
Starting point is 00:09:56 about actually command line replacement no way guys he's talking about biking tools i've got this fantastic i forget if it's park tools or alien wear or whatever But it's this great little thing Fits right into the bike seat And I never have a flat But yeah, you guys want to just rattle off a list I know we didn't prepare for this I don't know if that's going to be helpful No, it'll be a little bit, right?
Starting point is 00:10:16 Because it'll all somewhat be in one place Git Bash Git Bash is good Notepad Plus Plus Just talk to Ian, from there you get all the others Yeah, there you go But Notepad Plus Just talk to the infant There you get all the others Yeah there you go But Notepad++ Sublime Text
Starting point is 00:10:29 Sublime versus Notepad++ Yeah I don't feel like we can really list as much as tools Because there's so many competing tools Right You're going to say WinDiff I'm going to say Beyond Compare WinMerge Oh
Starting point is 00:10:41 Yeah But you know Sky Hanselman's got a big list of tools that he likes and he kind of does. Maybe we can do something like that on site. Just kind of have a running list of things that we like. Yeah, so we'll probably do that. We'll put together a list of tools and we'll create a blog post and we'll mention it in the next podcast.
Starting point is 00:10:56 Our 2014 favorite tools. Yeah, I like that. There you go, man. You got your wish. Alright, thanks. Thanks, Lewis. Now we got a blog to Lewis. Now we've got a blog to write. I think Alan has a blog to write. Oh, God. Here we go.
Starting point is 00:11:11 He touched it last. Yeah. Also, we got a message from Marcus. This is our last one. So he said he would love to hear a podcast on reactive extensions. And actually, this is something that we've talked about quite a lot and something we're very interested in. But I don't have a lot of experience with it, so I've been kind of hesitant to talk about it.
Starting point is 00:11:27 But we do have a local resource here, Jim Woolley, who I would love to talk with more about it. If we can bug him and come to the show sometime, that would be cool. Yeah, I think we can do that. He sounds like he'd be willing to. Yeah, fingers crossed. All right, so do we want to talk about some unit testing yeah please I would love to all right well I know I know we're pretty excited to talk about this one because this was a near and dear to our hearts I
Starting point is 00:11:55 actually love talking about this anymore than I love testing I love testing more than I love coding so that's crazy chat I'm chatty Kathy. So let's start off a little bit. Go ahead, Kathy. So, you know, we're talking about a little bit about unit tests, which is a specific kind of test, but really before we kind of dive into that, I want to talk a little bit about just testing in general. And there's two kind of broad categories,
Starting point is 00:12:19 which are really like, you know, testing that you do like as you're kind of working along in something like manual testing, like you refresh the page, or you hit F5, and you run through the application, and you see what worked within debugger if you see what the output looked like. But there's also automated testing. So this is testing that can be run from, say, a command line, or some sort of script or something that can be repeated without the involvement of a human. So unit testing definitely falls into that second category. So it is repeatable.
Starting point is 00:12:49 But there are lots of repeatable tests. So just kind of throwing it out there, there's security testing, there's performance testing, there's regression testing, meaning did I break something? There's UI testing. If you've ever heard of something like Selenium, where it actually acts like a browser. Yeah, it actually kind of mimics, like, you know,
Starting point is 00:13:09 the little mouse moving around, click, click, click, submit. So when I'm thinking here, when I think testing, I'm thinking more like test-driven development, regression testing, like, you know, the functional kind of testing. I am, oh, God, I hate Selenium. Right. That kind of, like, I'm not saying it kind of testing. I am, oh, God, I hate Selenium. Right. That kind of, like, I'm not saying it's not important. It totally is.
Starting point is 00:13:30 But. Well, that's one form of regression. That's one form of regression testing, right? Yeah. So why do you say it's fragile, though? But because, so more often than not, like, okay, so I stay away from it because i hate it but the the testing that i have seen done on it it's it's very tied to like okay well i need to look for specific classes or div ids or you know names of of the divs in order to find certain elements on the
Starting point is 00:13:58 page it was like oh god you better hope that nobody ever decides to change that because sometimes you know the the guy writing that selenium test is not the guy who's maintaining that page. And when I see it, I'm like, wow, that was a very dangerous but you got lucky assumption you made there. Well, one of the problems I've seen, and we don't want to go too far down this rabbit hole because we're actually talking about unit tests today but one of the issues that i've seen with that is you'll see people say okay i know that it's the third table on the page it's the fifth td down from that and when you do things like that you're not testing in a way that makes sense it's it's it's almost like writing code to because selenium is writing code to test your code right but when you would never write code that was that rigid or you would hope you wouldn't because then as soon as another use case comes along it breaks
Starting point is 00:14:50 well that's what i'm saying like that like any kind of so i guess another reason why i hate okay so so first off let me if i wasn't clear already i love unit testing but when it comes to like selenium tests or test testing like that those are following more the record and replay type strategy of testing and they're fragile yep and i'd say they're fragile because they really touch a lot of things like think about all the things that can break a selenium test like a value in a lookup table could break you change that column for that row from active to um new or something like that it's going to break if the html changes it's going to break if you lose internet connection during the test it's going to break if the business logic you know or if it's a little bit of a bug or the list goes on and on and on
Starting point is 00:15:39 but see here's why it's so important though because like and i don't think you said this one though but one of the type of testing that really isn't under the realm of what I was really thinking we would talk about tonight, but was load testing, performance testing, right? If you wanted to stress test your application, you need, the type of traffic I'm expecting to have, right? Yep. Then you need something like this, right? Like Visual Studio has this capability, you know, in Visual Studio Ultimate where you can record and replay and create a web test, right? So you don't just have to use Saloon. There's plenty of other options out there for this type of testing.
Starting point is 00:16:25 But yeah, I haven't seen any of them that I like, that I'm a fan of. One of the best I've seen, I think it was called Quick Test Pro or something like that, but it's a true testing suite. But it's literally like a macro recording, right? Like you go through, you click through, and you record what you do throughout the entire application, and you replay it. Now, if anything ever changes, like you said, a button on the page changes or it disappears or whatever about the workflow yeah that's what i'm saying like record record and replay unit any kind of testing that
Starting point is 00:16:53 is based on record and replay is fragile by its nature so so you know in the case of like a selenium if you decide to hey you know i want to test the checkout flow, but let's add in a new page. You've got to redo it all. Yeah, you've got to redo the whole test. So I don't know. But it kind of makes sense, right? Maybe somebody will speak in that's an expert in Selenium or web testing platforms, and they can write in and speak to their experience. But I, to date, haven't been a fan.
Starting point is 00:17:24 But I will say, even though you't been a fan but i will say even though you're not a fan it's still one of those necessary evils type things oh it's definitely evil because the thing is is let's say that you're working on bug fixes on other portions and you did not change the workflow in theory your your testing should succeed now and if it doesn't that means you probably put in a new regression right and that's why I conceded that it is needed. Yeah. Yeah. But so in the other testing that we're, you know, the regular kind of testing that I'm thinking of that we're going to be talking more about, like that kind of unit testing, I like more.
Starting point is 00:17:59 And it just seems it doesn't seem to have the same fragile this. Yeah. And I would also say that it goes for a different type of problem. Like when I'm doing unit testing, I'm frequently working with some sort of runner and I'm running the test often, but I'm not doing that with selenium.
Starting point is 00:18:18 The tests take a long time to run. So it's not like you're going to make a little change and then run through all your selenium tests again. we should just say that. It takes forever. So you said that selenium is slow, but really, to be in complete fairness, if we talk about when we say that selenium is slow, we're really just referring to that type of unit test. Right, right. It's not selenium.
Starting point is 00:18:42 Nothing against selenium. But really, if I could sum that up even better though, what's slow are integration tests, period. And you could write integration tests in a test-driven development kind of environment, right, if you needed to actually make connections to a database and you
Starting point is 00:18:59 needed to do real types of, you know, if you had dependencies on real file systems or anything like that, anytime you do an integration test, I don't care what kind it is, you introduce latency into your test. Absolutely. And really like the first time anyone hears about unit testing or test driven development or any of those buzzwords, the first thing they might do is sit down and write an integration test and think they're unit testing. And that's because that's kind of what comes to mind. That's what you think about when you hear the word testing.
Starting point is 00:19:28 It's like you think about scripting out some sort of change that does something important in your system. I feel like I kind of derailed this because we were going to start talking about the types of testing, and I've already started talking about the things I hate. So actually, though, I guess this is Festivus, so Greg, get around the Festivus poll and let me tell you what things I hate. But I think this is a good opportunity, though, to actually define and nail down what is a unit test exactly? Because we just talked about Selenium, which is like UI testing workflows and all that kind of stuff. And then you have your functional integration tests, which we just kind of said are involving your databases, your business logic, all that kind of stuff. So tell us, break it down. What exactly is a unit test?
Starting point is 00:20:07 Okay, so in my own words, if I were talking about the kind of unit testing that I like, let's say that you have a simple method that you pass in some variables, you expect a certain result. In my mind, when I talk about unit tests and when I talk about how I love unit tests I'm talking about a unit test or a suite of test cases that will put take different inputs into that method and test for different outputs or different scenarios like maybe if you expect exceptions to be thrown under certain scenarios things like that that or if you want to make sure that it can error handle correctly, that's the type of test that I'm referring to when I say that I love unit testing.
Starting point is 00:20:52 So what's your take on that? Yeah, basically the take I'm taking is the one I stole from Wikipedia, which is basically they give an intuitive definition here saying that one can view a unit as the smallest testable part of an application. So when I think of a unit test, I think of it literally testing a line or a very small piece of functionality, even within a method. So if you've got small methods that can be at the method level, but it's, it's usually something that's very kind of small and you add these little, very small things together and it kind of paints the whole picture. So, so to give an example to
Starting point is 00:21:22 what I was saying, let's say that I had some method called add and it takes in two integers and returns back an integer, right? A simple test method might be to pass in, uh, you know, two and three and test for the result of five coming back. Right. Um, that, that's the type of test that, that I'm talking about when I talk about that I love unit tests. Okay, so let's take this to another level. When you talk about that, you expect an integer two and three to go in. What if somebody passes a null? Are you going to be testing for exceptions at that point? Right, so those are the other use cases that I was referring to when I said that there might be a suite of tests that you have against that same method, right? That you're testing for like, okay, what
Starting point is 00:22:09 happens if you pass in a string? What happens if you pass in, you know, a null? Does it error handle it correctly? Or, you know, in the case of maybe you want to have an exception thrown under certain scenarios, did it throw the proper exception? You know, things like that. And to be clear here, so what we're talking about, just so you know, we have one method here, add, right? And we're saying that you might have 10 unit tests that you write against it, one that's actually passing invalid inputs, one that's passing in inputs that you may not expect, another one that's just maybe not even passing in the inputs, whatever. So you would write a unit test for this method five, six, seven different ways
Starting point is 00:22:50 so that you can identify that it's working the way you expect it to work. Yeah. That's – yes. Okay. Yeah, I like that. And so you are definitely testing a very small piece of the system. And I think a lot of people get frustrated when they try to do something like that because they don't think there's a lot of value. They can look at this small method, add, and say, obviously, it works.
Starting point is 00:23:10 And who cares? Let's move on. But see, the beauty of it, though, is that, like, going back to your point of regression earlier, though, is that you test these small little pieces like that. And now it's almost like you have a contract that, hey, at this point in time, you know, at one point, this piece of code passed all of these scenarios. And if you've done anything to make any one of these scenarios fail, it's on you. You've changed. You've done something. Well, and you need to worry about it at that point.
Starting point is 00:23:39 Right. Because that means somewhere in your application, things are potentially going to go sideways. Right. Because you've now changed the contract. It doesn't adhere to all of these scenarios that it used to adhere to. Right. But I would say here's the argument, and it's not a good argument, but I would say that a lot of people would argue that why not just test the method that calls that ad
Starting point is 00:24:02 or test at a higher level of abstraction and test like a workflow that ends up calling all these methods underneath, right? Aren't I testing all this stuff in a realistic way and the system's going to actually use it. And isn't that good enough? That's an interesting point to make about it. Um,
Starting point is 00:24:20 yeah, but there's problems with like you're testing the happy path, right? You're like, you can't possibly check all those little things. Well well when I was thinking is that you get too many dependencies Well, yeah, and that's definitely a problem as well when you start talking about the dependencies things start getting fragile They also start getting slow So if you're testing like a whole checkout workflow or something
Starting point is 00:24:36 Yeah You're probably looking at minutes to run through all of that this might be why I don't like the testing platforms like the seleniums of the world where, because there are too many dependencies in there where like, I like to be able to test that, that, that end point, like an ad method that we were talking about, you know, that seems like, you know, that that's, that's a method that's not going to call another method. Right. So it makes it simple. Once you start getting into these other paths that you were describing, where you have methods, calling methods, calling methods and classes, classes and classes, right?
Starting point is 00:25:05 It gets deeper and it becomes the possibility for your test failing, um, at a future date become higher. But you know what though? That's why you need a combination of the two. You need the unit test, you need the functional integration test and you need the selenium test, right?
Starting point is 00:25:21 Like, I mean, well, this is actually going to change that and say, that's where you would use mock. Well, I would say that you just described the testing pyramid. Yay! So there's this notion by this guy.
Starting point is 00:25:32 I didn't realize I was setting you up. Mike Kahn, we'll have a link to him in the show notes, who described this testing pyramid, which refers to, you know, a triangle with GUI tests, your user interface tests being the very tip of that triangle, your acceptance or integration or functional tests being the middle, and your unit tests making up by far the largest portion of these tests. And that's because they are very fine-grained.
Starting point is 00:25:58 When something breaks, you know exactly what line it broke on, and they shouldn't break that often, and you get fast feedback cycles when you actually work on it. So it's really useful as a tool for your development. And that's the way that I think of testing is it's really a tool to help me code, not so much prevent bugs, which is weird because when you think of testing, that's what you think about, right? Yeah, I mean, to add on to your comment, though,
Starting point is 00:26:24 it kind of is a great segue into like a test-driven development type of pattern. But I, for the life of me, can't do it. Yeah, and there's been a lot of debate about it. I read the books on it, and I'm in awe of the people who do it, where they write their test first. But honestly, there's more often than not, I don't even know what my class is going to look like yet. I don't even know what it's going to be named. Right. I don't even know what my class is going to look like yet i don't know what it's going to be named right i don't know what the methods are going to be named like and now i gotta write that and so i know that the approach is you know you write the test you write some code you refactor re-rinse and repeat right refactor refactor refactor
Starting point is 00:26:58 but since i don't even yet know what my class is going to be named what methods are going going to be named, things like that, sometimes I would be doing a lot of refactoring. And I'm very particular about the structure of my unit tests, which I was really planning on getting into this later. But the structure of my unit tests matching the actual tests that I'm – the methods that are under test. So I would end up going nuts having to refactor that all the time. Yeah, that's kind of funny about unit testing and testing in general is like, if you're talking about a brownfield app, most of the time, it's impossible to test it because there's so many dependencies, you really can't cut stuff out easily. But then at the same time, it's really hard to unit test a greenfield project, because you don't really know what you're doing.
Starting point is 00:27:45 And you're frequently deleting whole classes and changing things around dramatically. So you end up wasting a lot of time. That's why I would love to get better at TDD. But you've got to change your mindset. Completely. And you also have to plan a lot more up front if you don't want to spend a lot of time refactoring, redoing, refactoring, redoing, which is hard, especially if you're working on a personal project, right? Like you don't really want to sink that much time into it. You want to sit down and do something and get where you're going.
Starting point is 00:28:15 And I don't know. That's one of the things with test-driven development that I've found difficult is unless you have a well-laid-out plan, it's hard to go down that path. Yep, absolutely. found difficult is unless you have a well laid out plan it's hard to go down that path yep absolutely especially if it's a personal project and you don't even know if you're going to be working on this tomorrow if you're going to give up you know if you're just trying to get something working then you know it's hard to test but i do think that if you write a lot of tests whether it's brown or green or you just kind of force yourself to do it then after a while your code starts reflecting that style and so you end up doing things you know, keeping dependencies out and stuff kind of naturally. And although it's definitely easy to slip stuff in there and not realize until you actually try to test it and,
Starting point is 00:28:51 you know, it keeps you honest. It can be a good practice. Well, that is the beauty of, of test driven development though, is that it, it does force you into this path where you,
Starting point is 00:29:01 it tries to keep you more honest, which is a good thing right because i i've definitely found myself in situations where like after the fact i go to test something i'm like oh crap i made a dependency in there that i didn't mean to make yep so and you'll see people talk about it being a design tool and so it's weird with the name testing. It's kind of a misnomer, but at least, you know, that's my opinion on it. So, yeah. Yeah, so why? Why test?
Starting point is 00:29:35 Well, I would say that, you know, the obvious answer is, you know, that kind of springs to mind is fewer errors. But actually, I don't have a link to this. I need to find one. But in the book Code Complete, which is, you know, I don't have a link to this I need to find one but in the book Code Complete which is you know I don't know written in the 80s and it's been updated but it's still an awesome fantastic book but they actually did a lot of studies on different kind of testing methodologies and you know basically comparing them you know like how does code review do against automated testing versus you know like static analysis and they did find that unit testing was not near the top.
Starting point is 00:30:07 You know, I think it found like 30% of errors and code review did much better. But when you combine these multiple tactics together, that's when you got by far the best results. And so it does, you know, reduce bugs, but not as much as you might think. The good news there is that I would say that you probably find bugs sooner.
Starting point is 00:30:23 And I don't know if there's been any studies that determine that or not, but it's nice to know if someone makes a line of code change and runs the test or else maybe some sort of build server runs a test and they check in, then hopefully they're going to find that error the second it happens and not three months later after you've got a bunch of data to fix. Well, before you go on to the next portion of this, I think that's one of the things that you guys were talking about just a minute ago with it forces you to be consistent in the way that you code. And also the way you think about things, because in a lot of cases, you'll see people write code and it won't check for nulls or it won't check for things.
Starting point is 00:30:57 When you start writing unit tests, you have to think about these things because you're going to be thinking about, all right, what happens when I give it this input? What happens if I give it a null input? Does it send me back a null output? Whatever. And so when you start thinking about that, you kind of get in the mindset of you have this set of things that you're going to be trying. And so it kind of, it almost forces you to be more complete in just your approach to writing code at that point. So, you know. Yeah, absolutely. I've also seen the remark that sometimes people say that tests are the documentation. your approach to writing code at that point. So, you know, yeah,
Starting point is 00:31:25 absolutely. I've also seen the remark that, um, sometimes people say that tests are the documentation. I've never gotten this one. I've never gone to the test to be like, how should this work? And I feel like that's the case maybe with integration tests, but unit tests.
Starting point is 00:31:37 Well, this is where I'm going to say like, uh, you know, to your comment a moment ago though, about the, uh, about catching the errors and everything is that,
Starting point is 00:31:44 yeah, it can catch errors sooner in like your, comment a moment ago though about the uh about catching the errors and everything is that yeah it can catch errors sooner in like your your low-level api calls like the add method that i mentioned right but that doesn't mean that you can't use that method wrong right so so maybe in your ui you know you could still have a a bug in your ui where you're uh you know you called add when you should have called a multiply method right right but the add method is still working so yeah it's not going to catch your usage of that method wrong right but that that's where you know other platforms might come in play better yep yeah absolutely also you know we kind of mentioned it promotes loose coupling, good design, and we kind of mentioned catching bugs automatically, so automatic regression catching, which is really nice.
Starting point is 00:32:32 But really, the three biggies that I think are really important, as we mentioned, it promotes, I just mentioned this, well-crafted code. Also, my favorite, a shorter feedback loop. If you've ever done something where you had to just add some little line of code, but then you have to spin up the application, kind of click three ways, set up your data, you know, this way and that way, in order just to see if something, you know, stupid worked, like changing a plus to a minus, then you can do that in a little test, you know, be reasonably certain that it's going to work like you think it's going to work, and then go, you know, verify it when you need to. So it's a way of kind of working. More importantly than that, though, you can run it through a multitude of scenarios
Starting point is 00:33:12 much faster in your unit test than you could by spinning up the application as you described, right? And clicking through the UI 20 different ways. Yeah, whatever that interface might be. Yep, so if you've got some little code that kind of like converts a hash map to an array or something like that, something kind of trivial, you wouldn't really think about it. But now I don't have to go click the application to do it. I can see that my conversion is happening like I expected. And this might be the whole reason why I like the API type unit testing versus the Selenium
Starting point is 00:33:39 is just because it is easier and faster to see it without having the dependencies in there. But your dislike of that, though, it makes sense, but it's still necessary. It's testing something totally different, right? It is. You're testing what the end user is going to see as opposed to what you as the developer expect to happen, right? And that's really the big difference. The place where I see these happening, though, these happen. Okay, so this is kind of in line with Joe's comment about shorter feedback loop. Because the place that the unit test is ran should be at the developer's workstation, right?
Starting point is 00:34:18 Whereas I would imagine that like load testing, performance testing, those are handled out closer to the edge right that that's that's happening as part of you know uh you know before you deploy it you know something like that a selenium might be before that before you like send it off for user testing you know you run it through some automated test just to catch some of the quick ones. So, you know, there's different testing types that are happening at different stages of the development cycle, right? So, yeah. Yeah, and if you think like the opposite of a short feedback loop, like a long feedback loop, like if you're working for a cash register company or something or an ATM machine,
Starting point is 00:35:04 you need to make sure that if they type in five digits that it displays an error message. Then you shouldn't have to make the code change, upload the code to the ATM, go over to the ATM, try five digits to see if it worked, and it doesn't, you go back. Especially when something's multiple steps in. That's a long time just to test this little change. So if you can kind of make this little change, see if that's working, kind of move on to something else that's somewhat related,
Starting point is 00:35:26 and then go kind of verify it in the user interface later on, then you've saved a lot of time. I know I don't want to use your ATM. Well, it kind of depends on which error direction it went in. And I'm really surprised to see, maybe not surprised,
Starting point is 00:35:39 but I know there's been a big rise in unit testing in JavaScript lately with tools like Jasmine. And I know for me, when I used to write a lot of javascript um i would do stuff like yeah no comment so you would do something like you know write a line you're not sure if it's going to work so you write an alert or a console or you know write the debugger statement and you see it and you're like okay that's not quite what i thought let Let me go back, repeat, click, click, click, click. I thought the alert was for testing JavaScript.
Starting point is 00:36:09 That's right. That's definitely it. That's not how unit testing is done in JavaScript. And that's never been left in production code anywhere. Oh, man. You should leave your console open just to see the stuff that's in there. But, yeah, the JavaScript testing frameworks have definitely grown in popularity over the past year or two. Yep.
Starting point is 00:36:29 And I got two quotes here from David Starr, and these are from the Perl site video, which we'll have a link to. One of the quotes is that writing tests first means writing testable code, and the other is that writing testable code happens to result in well-designed code. So those are things we just talked about, but just, you know, before we moved on, I wanted to mention, like, what do we mean by well-designed code. So those things we just talked about, but just before we moved on, I wanted to mention, what do we mean by well-designed code? Because it all works, right? Isn't the real value in just getting the right answer? But I think what he would say here is that well-designed code
Starting point is 00:36:57 means that your code is easy to read. Not necessarily easiest, right? Because we've got interfaces. We've got code that's easy to maintain and easy to change. Because it's solid? Because it's solid. Because of cutting those dependencies out, you're going to end up doing some interfacing. Yeah.
Starting point is 00:37:14 Yeah, so let's take a moment to make a shout out here. So we got some love on iTunes here. Amy Meyer wrote in and she says, a great podcast to improve your coding. Focused to the point, real developers talking about real issues
Starting point is 00:37:30 and decisions we all make. Decisions are mistakes. Maybe a little both. I think maybe she's giving us some credit. I guess my mistakes are decisions, right? It can be. That's super sad. We also got one on Stitcher which uh that one's
Starting point is 00:37:46 usually a little bit quieter but from adam uk awesome podcast for devs i think regardless of your experience you're going to learn something new from these guys where do you think he's from don't no idea uh adam muck not sure yeah it's a weird name but um as always guys we really do appreciate the feedback and if you are enjoying the podcast, you're learning anything, please do take the time to go to iTunes, Stitcher. Come up to our site and leave us a comment or something. We really do appreciate it. And not only that, like Alan said, if you are enjoying it, do us the favor and tell two friends about the show and get them hooked on it as well. And if you don't enjoy the show, tell three friends or three people that you don't like. Get them hooked on it.
Starting point is 00:38:32 Absolutely. We appreciate it. All right. So how do you test? Yeah, that's one thing. There's plenty of tutorials, so you can definitely go Google it and see. That's how we're not going to read code over the air to you. But I did want to mention what it really means to actually write a test.
Starting point is 00:38:51 And for the most part, at least for me, it means starting up a new assembly that just contains tests. I don't want to mix my test code in with my normal stuff. You don't want to mix your chocolate with your peanut butter? That's right. Not in this case. I don't want to be deploying any sort of test code that could accidentally get run or do something weird in production. So definitely like to keep that separated. And then you use some sort of test runner.
Starting point is 00:39:13 And MS-Test comes bundled with certain visual versions of Visual Studio, I'm not sure. I think it's a pro, right? Well, they did just come out with a new community version, though, and I believe that one includes MS-Test, doesn't it? Oh, nice. I don't know. I might be wrong on that.
Starting point is 00:39:28 Yeah, and also another popular one in.NET is NUnit, and what's nice about those is they both have standalone runners, so you can run them from command line, and it actually has a UI you can run, which is nice. No, nobody uses that. I used to use it. I like it. Yeah.
Starting point is 00:39:43 It's a bright green, though. Maybe when it first came out you used it i mean yeah so now i got resharpened now who bothers i mean i know we're talking about these things but for those who don't use them i mean what what are they looking to expect from this right oh sure and test runner basically loads up some sort of config file or else it like scours your assembly and figures out well you know what public tests And it goes through, it iterates through, and runs each test and tells you which one fails. Well, more often than not, depending on the test runner, they'll have different decoration. It's looking for methods and classes decorated with different attributes.
Starting point is 00:40:22 So let's say this is like I tag it as a test class or a test method yeah and if everything succeeds then you'll basically get a bunch of greens right if if something fails in there it'll stop and let you know or in some of them it stops and others it'll continue running but it'll point out which one of those unit tests failed yeah well yeah i mean it shouldn't stop running the test just because one of them failed. But what I really wanted to point out here, though, because there were some other ones, other, you know, like XUnit and MSpec that, you know, maybe you need to use for your specific. Definitely NUnit is among the top. And MSTest is definitely up there because it's bundled in, you know, more often than not, you're going to be using a version of Visual Studio that has it built into it. But we should point out that NUnit is, of course, a variation of JUnit,
Starting point is 00:41:14 which was the Java version. And there's some slight differences between the two. I mean, NUnit definitely started off of the shoulders of JUn unit, but they definitely ended up taking different paths. So there are some subtle differences between them as they've both matured. But what I really wanted to mention with this part, though, was that don't use MS test. yeah because because there's a lot of there's a lot of things that you would want to do that you might want to do that in the beginning of your unit testing um career you might find that you know you you don't even think about you're like well i don't that's not a big deal i don't care and so you just use ms test but eventually you eventually you'll kind of grow up into that career and there'll be certain things that MS Test will just fall completely short on.
Starting point is 00:42:12 And like the biggest one that comes to mind for me that I often want to do that I can't do easily or well with MS Test is parameterized test. Absolutely. And by that, what I mean is like let's picture you had that add method right and let's say that i have another class and another assembly as joe mentioned and in that assembly and in that class there's a method to test that add method and you know maybe i want to test have one version version of it to test two and three and another version they'll test three and four, another version they'll test four or five. Well, it'd be nice if I could only have one test and then just pass in those values as parameters to that test and then just test each one of those to see that they return back the expected result, right? Now, in that very contrived example, that might not seem of value, but you'll see that there might be tests in the future where, let's say you want to do address validation comes to mind, right?
Starting point is 00:43:17 Any kind of string manipulation where you might want to just pass in different variations of a string and check to see like, hey, did my regular expression still match under this scenario? What about under this scenario? What about if I'm looking for a PO box in this format, a PO box in that format? What about, you know, so that's where parameterized tests are awesome. Yeah, because if you come up with a new variation on that in the future, you can just add another list of parameters. You have the one method, okay?
Starting point is 00:43:50 So you're staying very dry, but you have multiple attributes on top of that method, each with different parameters, right? And there might be some subtle differences between like an N unit versus a J unit. But yeah, parameterized tests all the way. In MS tests, there's no good way to do it yeah there's something with that xml file but no one does that oh yeah i mean i've seen i've seen some other complete hacks out there where they're like creating data tables on the fly and passing in the values that way and then passing the data table off to the method and then yeah gross that's just fragile too i mean i don't know yeah i don't want to be spending my whole time messing around with that.
Starting point is 00:44:26 I just want to get to it. Well, yeah, I mean, as far as your comment about fragile though, you can just as easily write bad unit test code as you can regular code. So you do have to be careful about the way you structure some of this. Yeah, I mean, one of the things that comes to mind is, and we talked about this is you could, if you have a hundred different things that are testing various, a class per se, and you were newing up that class and every one of your hundred test methods, that that's not a dry approach. And now if that class changes, the implementation of that class changes and you can no longer instantiate it the way that it was being done 100 times before, you now have to go touch every one of those test methods to update how it instantiates that class.
Starting point is 00:45:14 Oh, you mean like if you change the constructor or something? Yes, yes. So one of the – Yeah, constructors, man, that's not very driving. Man, who does that anymore? Getting away from that. So what you should do is it's very easy for people writing unit tests to just kind of almost copy and paste their code into a new unit test. And that's a bad idea, too, because then you are doing bad practices. Keep it dry.
Starting point is 00:45:37 If you're going to be newing up a class somewhere, put that in its own call somewhere. And then that way, if that ever changes, you only have to change it in one place. So even your unit tests need to be coded well because it can come back to bite you in the butt later if you don't think about these things up front. Well, I will mention, though, we said before when we were talking about the Seleniums of the world, and we categorized those as the simple record and replay type test scenarios there are other or you know there are older frameworks that did similar things at the api levels that you know really kind of fallen out of usage out of favor nowadays, but the pattern of testing that has become more widely acceptable would be the AAA format, the arrange, the act, the assert pattern for your test.
Starting point is 00:46:39 So when you're constructing your test, you have one portion of it where you arrange variables to match whatever scenario you're testing. You have an act portion of the method that is going to actually test the method. It's actually going to call the method under test, right? And then there's the assert portion that will, that'll be last. And that's going to check to whatever the return value was, for example, or if you're checking to see if a certain method got called. Whatever it is that you're trying to test one assert method, the one assertion in your unit test. Yeah, I feel like if you're having a problem following this pattern in the AAA, then maybe you're doing something a little fishy there. And it's a good pattern for different reasons. Like you don't want to have more than one assert because if one of them breaks, you don't know about the rest of them.
Starting point is 00:47:44 It's not as informative and it kind of hides stuff from you all right so uh one other thing since we're already talking about things to watch out for i i got a dog on it i'm sorry singletons a lot of times oh my god there's one in the application they all they often you do it why would you do this to me, Joe? I'm sorry. I thought we were friends. I couldn't do it. The singletons often, they hide dependencies. So you might have a singleton class that does stuff like interact with session or the database or the file system like a logging application.
Starting point is 00:48:16 All the different examples we gave of reasons to use singletons are all really bad for unit testing. Now, hold on. Before you go dogging my boy Singleton now, is this because the Singleton itself is a bad pattern or because the specific implementation maybe should have used some dependency injection maybe? Dependency injecting a Singleton? Well, like whatever the dependencies that you're talking about that the Singleton has. Right, right. Well, so yeah, we talked a little bit about Singletons whatever the dependencies that you're talking about, that the singleton has.
Starting point is 00:48:45 Right. Right. Well, so yeah, we talked a little bit about singletons and how you kind of instantiate them. And if you're kind of, you know, passing those things,
Starting point is 00:48:52 like I think actually the definition of a singleton might be that it creates itself. Right. Yeah, it does. But, but what I'm saying though, is like,
Starting point is 00:48:59 you're talking about the, the, the singleton itself has like a dependency on, I don't know, like a database or maybe the file system. And what I'm saying is if that singleton has a dependency on something else, right, what if you were using like a dependency injection to solve that? Then is it still the fault of the singleton pattern in regards to testability? Right, right.
Starting point is 00:49:27 Before you could dog it, I'm a boy now. It's true. So singletons, I will say, singletons often hide dependencies, but that's not a requirement of singleton. It's just how everyone uses them. Yeah, it is often used bad, I will admit. So if you see a singleton in code, you're probably going to have a testing tough spot. In fairness, that's not bad use.
Starting point is 00:49:46 It's just not loose coupling of it, right? Yeah. I mean, it's – well, this often goes back to like when we were talking about the creational patterns. Shoot, what episode was that? I forget. But – and we talked about the singleton and then that particular pattern, there's at least a dozen different ways to construct a singleton. And my favorite particular one of them had to do with where you have a – if we're talking strictly in C-sharp where you would have like an instance property. property, right? And whenever you call that property, if it's, if that value is null, you know, based off of some member backing data, then it can instantiate a new version of itself.
Starting point is 00:50:31 And then that's what it would return back for you to use. But you, you allow it to be reset. So if you want it to be able to maybe, maybe you want to have a specific method to do the resetting, or maybe you want to be able to just pass in like a null value to it, or whatever your preference might be. The point is like, one of the Singleton patterns was like static constructor, hate that version of the Singleton implementation. Because in the examples that you mentioned, where if you do have a dependency on something like a database or a file system, whatever that might be, if that static constructor-based singleton fails, then it will never re-instantiate it and you can never do anything about it. So at least in the instance property version that I mentioned, in your testing scenario, you at least have the ability to reset that value back to null. So at the at the arrange portion of your test case,
Starting point is 00:51:32 you know, you could you could say singleton dot instance equals null. And that way, you're guaranteed that the next time when you call that it's going to be a fresh version of it. So it'll reset itself for your test, which is, you know, something we didn't really discuss. But, you know, each version of your each one of your tests needs to be a fresh state. Right. And that's a really good point. And so we've got a little section here we called how do I know if I'm doing it right? And actually one of the... When it hurts. Exactly. That's exactly right. But one of the items on there that I'm doing it right? And actually one of the items. When it hurts. Yeah, exactly. That's exactly right. But one of the items on there that I'm adding right now is basically can your items run out of order?
Starting point is 00:52:11 And then that's really important. I don't think I've ever seen a test runner that lets you order your tests specifically. Oh, that's actually a pretty big one, though, too. Because when you write your unit test, there is no guarantee depending on what tests are going to run in what order. And depending on the test runner, I've actually seen you will see different results. You'll see different tests get called in a different order. Well, I'm pretty sure, like, I don't remember now. One of them, specifically if you were to run MS test versus in-unit,
Starting point is 00:52:42 one of them actually i've noticed and maybe this was just my luck but i happened to notice that it was running all the tests bottom up it's like whatever the class was it was running the test bottom up i feel like that's a feature like that they do that to kind of keep you honest you know it makes sense that you don't want to rely on some sort of state because we're supposed to be cutting out our dependencies here and testing our actual code lines so we shouldn't be relying on some sort of shared state between these methods so i think it makes sense to run these tests out of order just to make sure that calling method a before b doesn't do anything in the stateless test yeah and if you actually have a test that
Starting point is 00:53:17 depends on the outcome of another test you're doing it wrong yeah and you're writing integration that's what i was going to say that's an integration test at that point so well i don't even know if you could call it that because then if i switch the test runner it's going to fail no but but what you said is if you're writing them that depend on the outcome but i said if you're writing a test that depends on the outcome of another test right that's that's oh okay yeah right right and it's also really bad too because if you think like say i've tested one it moves the file test two deletes the file from its new location. What happens if test two fails? And then I've got this file sitting there, and it's going to mess up future runs of the test.
Starting point is 00:53:51 And it's just getting my system into a bad state. Yep. Yep. Also, another reason or another way to tell if you're doing it right is whether you could run your tests on your build server if you have one. And what that kind of tells you is that the build server usually doesn't have access to things like the production servers or production database, at least hopefully not, things like session, IIS, stuff like that. It's just a dumb build server. So if you can run your tests on your build server, then you're probably doing okay.
Starting point is 00:54:23 So let's back up for a moment here because we kind of skipped ahead but let's say like why should we test first why should you test first yeah i don't know if i agree that you should no kind of depends so there's a big argument right now kind of going on between like martin fowler and um the dhh ruby guy we can a link to. And they're kind of talking about the value of TDD. They're not talking about the value of testing, and they're not arguing that. Both of them kind of agree on that. But they are talking about the value of writing the test first.
Starting point is 00:54:54 And the problem is, as we kind of mentioned, brownfield code, existing legacy code bases, it's really hard to abstract stuff out. And when you're doing greenfield stuff, a lot of times you're focusing on the UI and kind of just seeing and prototyping and seeing if something's going to work. So it can be difficult to test first. And so, you know, kind of the idea, I think that DHH is kind of proposing, I'm surely getting this all wrong, but what I'd like to think that he's going after is that you don't have to write your tests first as long as you're writing testable code.
Starting point is 00:55:24 And TDD is a tool for writing testable code, but it's not the only way. Thank God. Yeah. And there's this whole notion of, they call it red-green refactor, where you basically write the failing test first. You basically write the test code with no code to test, make sure it fails, and you make sure it passes by doing green and you kind of do and you sort of little cleanup and make sure that it's still green
Starting point is 00:55:49 and you just iterate on that but it's uh slow it's very slow i will say the closest i've been able to personally get into like tdd which isn't i don't think according to everything I've ever read about it would be considered true TDD is if I'm already pretty far along in my, uh, class, uh, or classes, I should say, whatever that namespace is that might be working in and, and already have pretty much established the pattern of where, where it's going to end up. Then I can start writing tests that, uh, you know, I know I'm going to want this test and I know I'm going to want this test and I'm
Starting point is 00:56:25 going to want that test and I can go ahead and have them fail. But where I say like I I'm still fall short on on the true TDD is like often I'll know that I want to test something, but I'll go I won't know exactly how the the innards of that test are going to look. So I'll just write an assert fail or assert is true false. Yeah, I don't like that. Type of method. But I know you say you don't like that.
Starting point is 00:56:56 You're stubbing it out, basically. Yeah, exactly. I'm stubbing out the test, and I don't commit it like that. But I go ahead and write that structure. That way I know like, hey, at some point I want to write a test or I want to come back and finish this test to pass this. But it's not true TDD. I still can't get into that. Yeah, it's gross.
Starting point is 00:57:18 As much as I try and want to. Another big problem I have with TDD, and you'll see this a lot, is a lot of times you'll say write the minimum amount of code to make the test pass. And what that means is if you're testing, you've got a length function, and you want to return the value 1 if there's only one item in the list. And that very first test you write, you call it has1. And then you go make it fail. Then you go over to your code. You return the value 1 because you're literally writing the least amount of code to make the test pass not correctness then you come back your test does it equal one yes it does and you add your second test and that's when you go and end up kind of
Starting point is 00:57:53 fixing your first case uh but that just seems really gross and backwards to me and i i just haven't been able to swallow that yeah i'm kind of i'm kind of curious to see like where is this going to end up in a long like like you know 10 15 20 years from now are we curious to see where is this going to end up in the long run? Like 10, 15, 20 years from now, is TDD going to be the winner or are we going to come back on it and be like, you know what? No. Maybe some other pattern will become the main one. Who knows? Honestly, I think it probably boils down to the type of application, right? Like if it's something that is critically financial or transactionally related, then maybe you do something like TDD. Because it makes a lot of application, right? Like if it's something that is critically financial or transactionally related,
Starting point is 00:58:25 then maybe you do something like TDD because it makes a lot of sense, right? It might be slower, but your whole goal is to make sure it's perfect, right? So I would almost think that it might differ across industry or across application type. And even work type. Like if you're trying to fix a bug,
Starting point is 00:58:43 like you can't add a negative quantity to a cart. It makes sense. The bug exists. You could write a test that adds the item to the cart and does it work? Yes.
Starting point is 00:58:52 Then I go fix it and fix the test. Right. So what happens if you write that code, the least amount of code to solve that test or pass that
Starting point is 00:59:01 test, as you said. So in your example, you were testing for one you write a method that is hard codes to return back one then you go to lunch and you forget yeah and i think that's what his point was yeah and the code coverage shows 100 because every line is tested that's like the sopranos of code forget about yeah i'm good right yeah so so how do you test how do you tdd brownfield stuff then existing code yeah you can't don't yeah it's already written the code's already written it's brown yeah so especially from then on
Starting point is 00:59:32 it's kind of the boy scout rule you basically just try to make things a little bit better and any sort of new code you write you try to do it in a dependency less style you know keep it solid and then it's testable but i mean almost going back to your point you almost can tdd portions of your code at a time only if you're like introducing new features exactly so brownfield you brownfield doesn't mean that you're not ever enhancing it or anything right it just means that it's an existing code base so to your point a minute ago hey if there's one portion that you really strongly feel that needs to be driven by a certain set of rules, then maybe you do that portion that way. So I don't know, just an interesting thought on that.
Starting point is 01:00:13 Yeah. All right. Oh, and so here was something interesting I found on Stack Overflow. We'll leave a link in the show notes, but there was this thing that this guy wrote and I don't remember who it was, but he had this, these two notions and I'm sure they weren't his, but equivalence partitioning and boundary value analysis. These were two different approaches to unit testing that I thought were pretty interesting. So really what it boils down to is instead of trying to test for every single input and output that exists.
Starting point is 01:00:46 So equivalence partitioning is you break your inputs into groups. So let's say that, I don't know, maybe you have negative numbers, zeros, and positive numbers. That's your groups. And then given those, you have an output expectation based off those inputs. So that logically groups your inputs and your expected outputs. And that's why they call it like this equivalence partitioning, because they all should, given the input, give you an equivalent type output. Clearly, this guy uses NUnit. And, you know, to me, the kind of like the kind of dumb it down, so I can understand it, you know, to me, the kind of dumb it down so I can understand it, it's basically a way of dividing your data set into these kind of regions that you think make sense.
Starting point is 01:01:30 So, you know, like if you've got something that makes change for a dollar, you know, you could test every single combination of the coins and it's going to be miserable. Or you can write a couple of tests. You basically subdivide your data and say, you know, big amounts, small amounts, negative amounts, something like that. You know, that's probably a bad example, but it's just the idea of kind of taking up the full range of expected inputs and kind of dividing it so that you're testing a representative
Starting point is 01:01:56 from each group. Well, am I thinking about this wrong? Because when I made my joke, I was thinking of parameterized tests. Well, I would do parameterized tests with it, you know, so I would do, like, tests for negative, tests for positive, tests for big, tests for small, whatever. You're just talking about having the parameters grouped together.
Starting point is 01:02:10 Yes, yeah, and then the boundary value analysis was actually taking that equivalence partitioning, which we just talked about, like, one step further and saying, hey, all these edge cases themselves also need their own tests, so if, I mean, I can't come up with a great example off the top of my head, but let's say that, you know, you were taking in us dollars, but then somebody passed in pesos, right? You might have a pesos type test. So it's basically expanding upon
Starting point is 01:02:35 the grouping and saying, Hey, these outliers, the ones that you expect these edge cases that may occur, you might want to have unit tests for those individually. So that was a pretty interesting take. Yep. So let's talk about why testing sucks. Yeah. It really does. If we haven't convinced you already. Yeah.
Starting point is 01:02:54 Well, first off, it's trying to tell me I didn't do it right the first time. Right. Which we all know is wrong. I did it right. I'm not wrong. There's a reason why, like, you know, seven-eighths of the places you've probably worked in your life haven't had zero tests.
Starting point is 01:03:07 It's because it's hard and it requires a lot of refactoring. And a lot of times management doesn't see the value. So it can be a hard sell. And you're going to run into people who say, I don't have time to test because I need to get this done. And the easiest way is just grab the value out of the session and I'm done and I'm, you know, at lunch. Yeah, it's kind of a hard sell when you're like, okay, so it's going to take me, you know,
Starting point is 01:03:29 60% of my day to write the unit test and then the rest would just be to actually write the code. Right. We need to spend the next six months refactoring before we can even start testing. And then I swear it's going to make us faster. Yeah, good luck getting that one past the bosses. I mean, the thing is, though, it really does reduce technical debt though and that's one thing that none of us will argue here but it is a really hard sell when you're like yeah seriously it's going to take me half my day to do this as opposed to just getting the functionality out there so i'll agree with you on the technical debt but but you brought up the uh um oh gosh How did you word it a moment ago?
Starting point is 01:04:12 Where the stats of how much faster it's going to be or quicker. There's actually been some tests, some studies. Interestingly enough. Different kind of test. So there's actually been some studies where they've actually taken the time to say like okay you know group a will write code and they won't write the unit tests uh and then group b will write the unit tests and like which one actually performs uh faster and in up front yeah that uh you know the group b that was writing the test especially if they were following tdd they might have been behind up front if they were following TDD,
Starting point is 01:04:47 they might have been behind up front while they were just structuring tests and everything and getting a flow down together. And group A, who was just writing code, looked like they were rocking right along and going to proceed faster. But then once the second group got their test structured, then they started to progress much faster and with a much higher confidence. And I know we were going to talk about this in the resources we like, but actually some
Starting point is 01:05:11 of these tests, these studies I'm referring to, there's actually a reference to it in the art of unit testing. In that book, it references some of that. And it makes sense because the people that just started hitting the ground running coding they probably started producing spaghetti code and that kind of stuff which is much harder to do if you're actually writing unit tests against your methods so absolutely yeah i mean their code with all their dependencies works fine for right now and then three weeks later they end up finding that their their their problems that they're trying to solve then become more difficult because of dependencies that they mistakenly baked in without realizing it. But now they're at a situation where it's like,
Starting point is 01:05:48 well, I can't easily undo that. So I'm going to have to live with that. And now I've got to bake in all these other, and I jumped through all these other hoops to try to get around that. And it becomes a nightmare. Yep. Yep.
Starting point is 01:05:58 So, so another reason why it sucks. Oh, explosion. So the thing with writing testable code is that you're writing these small units that kind of compose together, and it's all very solid. And just like the solid principles that we talked about quite a bit, it leads to a class slash interface slash method explosion. You're definitely going to end up with a lot more classes with a lot smaller methods. And that can be a really good thing for composability and good architecture,
Starting point is 01:06:25 but it can be a real pain for someone who's not familiar with code or is familiar with the old version of the code that used to have one file with seven methods and is now looking at seven files and three interfaces. Seven files? Wouldn't that be like 14? Right. Depends on how solid it is. 43 methods. Right.
Starting point is 01:06:43 But especially it could just be a pain. And a lot of times people kind of struggle also with public versus internal or private methods and what to test and whatnot. So it can be a big deal. Cool. Yep. And along that line, there are the dependencies. So, yeah, that's really the roughest spot is you've got to cut that stuff out there. If you've got tests that rely on session or request. You find the dependencies so uh yeah that's really the roughest spot is you've got to cut that stuff out there if you've got tests that rely on you find the dependencies so quick especially and even in
Starting point is 01:07:09 the dot net framework you know like the http request you know there's no interface for that there's no way to graft on an interface to existing code you know we talked about that in episode one and so uh you're going to end up writing wrappers for a lot of stuff and then not only are you writing these stupid wrappers but then you're going to your test and you're using some sort of mocking or faking library to write fakes for these wrappers that you just wrote so it's like quadrupling your code well here here's what i was gonna say is like uh one reason why it testing can suck is if you're not prepared for it you might find yourself having to learn dependency injection and mocking and now you're like oh crap all i wanted to do is test my stupid ad method yeah right right but but if you have this
Starting point is 01:07:50 is where like if you have code that has these dependencies and then you you got to find a way to deal with it right yeah and it's gonna hurt or or depending on the scenario that you're wanting to test if you're wanting to test you know hey did uh did this other method get called you know or not right then you need you need a mock for that yep so one of the questions we've gotten here uh is basically for knowing if you're doing it right is are you cursing your mocking library because it's a it's a pain to mock it really is and i've seen some cool things with like structure map and you know some other libraries and uh it's still pain even dependency injection it's still painful it's annoying you're gonna spend time you know goofing
Starting point is 01:08:29 around with your mocking library just to try and set up your structure map would be for the dependency injection yeah yeah but i've seen it with testing a lot for some reason um i don't know why also uh test coverage kind of sucks and you you're never going to get 100% for anything that's not trivial. What? Yeah, it's really difficult. There's always going to be that one line in there, and you're not even going to think it's tested. You know what? I hate it because sometimes, depending on what tool you're using, that one line that you're referring to will be the curly brace right after you throw an exception.
Starting point is 01:09:00 And you're like, well, of course that's not going to be called. I just threw an exception. And there are some nice tools out there, but I've yet to find the code coverage tool i completely agree with oh well i've written some stupid stupid code in order to please that code coverage tool like things i would never normally do and i know we're gonna work and i make the code uglier just to make sure that i can get so i'm gonna save it i'm not gonna talk about right now because i got my one that i like yeah we'll get to that in the tip we'll see i don't want to tease it but i want to tease it and um before we get into the resources one other thing that i saw that somebody said and i really like is if you find a bug in your code you should immediately write it
Starting point is 01:09:44 oh yeah that's it sorry you should immediately write in your code, you should immediately write it. Oh, oh, sorry. You should immediately write a unit test before you go and fix it. And then that way, you know that, Hey, we've got this covered for the future.
Starting point is 01:09:53 Right. Makes a lot of sense. Yeah. Well, that way you can test the before and after. Yep. Right. Did I actually solve the problem or not?
Starting point is 01:09:58 It's, it's a great, it's just a great little tip that, you know, it gets you in the mindset of doing that. And there's always, you know, room for okay i changed my mind i don't like unit testing anymore it's too much work it's a lot of work but uh there are people to help you there are resources that will help guide you through this process oh really please tell what are some of those a favorite of mine is the art of unit testing by at roy oshrove awesome book and it's
Starting point is 01:10:26 short and it's to the point so awesome and he really knows his stuff so there was uh last year this time last year a year ago yesterday he released the second edition of that book and it so the book is actually has examples in c-sharp but for all of our listeners who are not C Sharp developers, I can tell you it applies to anything. The concepts in there, he actually talks about other languages too, just conceptually everything that he's talking about applies to any language out there, period. It doesn't matter and it is a fantastic book. So we will definitely have a link to that in the show notes. Yep.
Starting point is 01:11:20 Also. Oh, yeah? You want to do it? I'll do it. I can do it. No, I want to do it. I want to do it now. No, I'm going to do it i'll do it uh i can do it no i want to do it i want to do it now no all right i'm gonna do it cool because i kind of i already hinted on this one yeah and that is uh do don't use ms test so resources we like i i threw in there that was not a hint by the way a royal actually did yell at me on Twitter once for recommending MS-Test.
Starting point is 01:11:46 It's a true story. I mean, it's kind of better than nothing. I was going to say, right? Notice I said kind of. But, I mean, at least it's there. But really, use NUnit if you're in a.NET environment or JUnit if you're in Java. There are other ones in either environment. I mentioned XUnit before.
Starting point is 01:12:10 Whatever you want to use, just really MS Test. It's great that it's free and included in with your version of Visual Studio, but it's going to fall short eventually. And you might not realize that pain until you've gone too far down the path of MS tests. So if you can switch to NUnit, it is recommended. Yeah. And I also wanted to mention earlier, we mentioned NUnit being heavily based on JUnit, but also want to mention that J unit was based heavily on X unit, which was one of the, like the small talk first testing framework. So I think a lot of the things we talk about,
Starting point is 01:12:50 like asserts and whatnot actually came from there. So just wanted to get that in there before you guys scream at us. So another resource that we like that I wanted to throw out there was in regards to how to structure your unit test. So I kind of hinted at this, uh, earlier in the show, but we're going to include a link to this on hacked.com. This is Phil hacks site. And he has this great article on how he, uh, you know, grew to love structuring his, um, his, his unit tests. And it starts off with, uh, the idea of being like, whatever the method is that you
Starting point is 01:13:25 want to test, you create a class, a test method specific for that, that class. And then for each scenario under test for that method, you create a separate test method for it. So for example, in my add method that I mentioned before, I might create a class called, you know, add tests. And inside of add test class, I might have a method for um, you know, testing valid integers or, um, testing for null, things like that. I might have different methods for each one of those use cases. But what I like to do, though, is take combined Phil Hack's idea here or that he documented here in his blog post that we'll link to with some of the patterns that I cannot pronounce his name,
Starting point is 01:14:24 but Roy said in Art of Unit Testing with how he liked the structure of the unit test. Because Roy kind of expands on this idea that I think couples very nicely with the concept that Phil Hack had documented, which is that in the naming of your method, Roy suggests that you name it in a pattern of the method under test underscore I wasn't expecting that. So I'm going to start over. The method under test underscore That's going to throw me off every time. The scenario
Starting point is 01:15:02 under test underscore It was coming, too. That's what it feels like every time I see an underscore in a method name. The scenario under test underscore. It was coming too. That's what it feels like every time I see an underscore in a method name. And then the last part is the expected result. So you have three parts to your name. So normally you might not use an underscore in your method name. But for these test methods, you name it so that it's method under test underscore scenario underscore expected results. So in the add result or the add method that I mentioned, I might have the add test class like Phil Hack had suggested.
Starting point is 01:15:36 But one of the methods might be named something like add underscore valid integers underscore returns valid integer as the name, right? And then that way, you guys are looking at me crazy when I suggest this, but what ends up happening is that no matter what your test runner is now, when you see the report, you have a really good idea right away what was being tested, what the expected result was in the scenario, the method was being under test. So right away, you get a lot of information just by looking at the name alone of it. And depending on your test runner, that might be very valuable data for you. And it also is very valuable because when, you know, some developer comes behind you three months later and wants to modify your tests, he knows exactly what you were trying to test for.
Starting point is 01:16:34 He knows, he knows the scenario that you were trying to test. So you were trying to test valid integers and he knows that you were trying to, you were expecting a valid integer to be returned back from, uh, from the method under test. And he knows what method was supposed to be under test. So just from the name alone, the next developer coming behind you already has a lot of valuable information. So going back to Joe's reading the test as documentation point. Yeah, that definitely sounds nice, although I've got to say, the programmer that's coming after you is most likely just going
Starting point is 01:17:05 to unattach your test project if it starts breaking. Or they're gonna comment out the test, they're gonna return true, it's gonna be green, and that's gonna be it. Yeah, it definitely, it just could comment it out. This is the world we live in. That test failed, so I commented it out. Now it's, now I can build.
Starting point is 01:17:21 The CI server, the CI server passes. I stepped out to the real world for a second. I'm coming back to test land now. I think you're jaded. Just a little bit. So there are a couple of great videos on Pluralsight too. What?
Starting point is 01:17:35 Yeah, there's a ton on testing in general, but there's two in particular I wanted to mention with Scott Allen. Ah, that guy again. Yeah, if you're on Pluralsight, you're familiar withott allen and also david star so we'll have links to those they're great cool and now he's got a few of them out there now it's tips of the week what you got joe all right so first uh we're talking about different kinds of testing um there's a podcast i just discovered on the security side of things called uh the defensive security podcast and not only do they have the best intro music of any podcast I've ever heard,
Starting point is 01:18:07 they're also locals, and it's a great show. So you should check it out if you are into application security and keeping up with those sort of things. Yeah, Joe has turned me on to this one, too, and I have really enjoyed it. Although I do say I am looking forward to someone coming out with the Offensive Security Podcast. Hey, we got time, right? We can start recording after this, huh?
Starting point is 01:18:28 Yeah, it'll be marked with an explicit tag. Yeah. So in the tips of the week, you kind of hinted at this a moment ago, but when we were talking about coverage, I am a big fan of, oh my gosh, I hate to say that it's another JetBrains product,.cover. I'm a big fan of, oh my gosh, I hate to say that it's another JetBrains product,.cover. I'm a big fan of it.
Starting point is 01:18:49 I like it. Your mileage may vary. But it's a great tool for being able to visually see what the code coverage is. And not only can you – okay, so let me describe this. You can see the code coverage in multiple ways. So in one way, you can see the code coverage from like a bar graph percentage kind of point of view. Like, hey, how is my, this particular namespace that I'm working in, what percentage of that is covered under these tests that I've been writing? So that's good information. But what's also cool too,
Starting point is 01:19:30 is it's almost like running a highlighter over your monitor. You can turn on, uh, one of the little buttons there. I forget exactly what it's called, but it's almost like a Crayola marker. And it'll actually show you all of the code in green that is under test and any code that is not, that has not been run under a test it'll be in marked in red so you can visually see the paths that you have written tests against and i'm a big fan yep and also it produces the xml file that you can use with other tools like and depend yeah you can you can take that into that output into independent and then, uh, you know, from your static analysis, be able to see coverage as well. Very cool. So my tip of the week is hardware based. Um, I just recently got the Microsoft sculpt ergonomic keyboard and,
Starting point is 01:20:16 and one can never have, one can never have too many keyboards. I have, uh, more than a small collection at my house at this point and this one is by far my favorite so far um it's got a key feel similar to like your macbook pro but it's yeah it's it's the chiclet keys they have good travel i'm not a fan of the function keys which really stinks as a programmer but i think that you're recommending it so here's the deal with the downfalls it's still so freaking good yeah that it overcomes them like it you're not a hard you're not a mechanical keyboard fan right that's just joe yeah i'm not i'm not a huge fan of that because i don't really like the clickety clackety noise i don't need something to wake up the
Starting point is 01:21:01 neighbors right um it's the only exercise i get the hammer action on your fingers i got strong fingers oh there's so many bad jokes but i'm here to tell you like this particular keyboard after you get used to it is just absolutely phenomenal like i can type incredibly fast it's super comfortable so um that's So that's my tip of the week. So it's not like a rocket gaming keyboard. Wait a second. Hey, if we're doing these podcasts once a month, can we really call it a tip of the week? Whoa, whoa, whoa.
Starting point is 01:21:38 Sulfating podcaster. All right, so he just unit tested us and we failed. We did. It's a good thing it's not automated. All right, so he just unit tested us and we failed. We did. It's a good thing it's not automated. We're going to go back out to the Rocket gaming keyboards again, but no. Maybe we need some show resolutions for the next episode. Well, have you seen these? I mean, since we're on the keyboards and it is Christmas time,
Starting point is 01:21:58 and you might be in the market for something. Have you seen their Rocket keyboards? They look wicked. Rocket keyboards? Yeah, it's R-O-C-C-A-T dot org. You can go out and you can find them. They have various keyboards, but they have like a built-in pad on the front of it. So, because picture like your laptop, right?
Starting point is 01:22:17 It already has like a pad to rest your palm and then you start typing away, right? What's the website? R-O-C-C-A-T dot org. It's German. And, no? Yeah. right what's the website r-o-c-c-a-t.org it's german and uh no yeah this page is r-o-c-c-a-t.org a rock cat yeah it says this page is in german would you like to translate it mine doesn't do that you did something weird you must have clicked on the language at the top at any rate i just got to it there's like different illuminations that you can get for it, too. And if you're into gaming, you can have different keys illuminate different colors. So it looks wicked.
Starting point is 01:22:50 I'm not saying that I would go out and spend it, because some of these keyboards that they have are like $170, $180. I mean, you can spend some money on it. I've definitely spent more than that over time. Well, I mean, we were talking about the Adesso, I believe it was. No. No, not the Adesso. The Kinesis. The kinesis is 320 yeah or 360 depending on that's why i thought you might be like all over this one but but these are mechanical keyboards and it's not ergo i don't want any part of this well no yeah joe joe would be all over this oh i will give a tip
Starting point is 01:23:22 on this though so an additional tip on top of my other one uh massdrop.org hold on that might be important no massdrop.com go to white house so no don't uh so massdrop.com this site is fantastic so i do a headphone review site as well on top of this and they typically have things from audio file to keyboards, which, Joe, they have mechanical keyboards all the time. They have the code keyboard on sale recently. They do have the code keyboard. And so Massdrop, the way that this site works is it's like they just have a certain number of items that if more people buy them, then the price keeps going down. So give them a check out.
Starting point is 01:24:05 I really like the site and I like what they're doing. And if you're into keyboards or audio file or headphones or anything like that, it's a good place to go. Nice. So with that, that's the end of the show. So we talked a lot about automated testing and not automated testing and how it encourages good design and fast feedback cycles. But it's very hard. So we hope you learned something. Yep.
Starting point is 01:24:28 Well, I think we focused more on just the testing of it, not necessarily the automation of it. Maybe we can do continuous integration separate. And continuous delivery. Uh-oh. Oh, snap. Yeah. We'll have a whole pipeline of podcasts. Yeah.
Starting point is 01:24:42 So, hey, hint, hint. You can look forward to that. So subscribe to us on iTunes and Stitcher and more using your favorite podcast app. And be sure to give us the reviews like we've said before. We greatly appreciate it. We love to hear the things that you guys say and love to know that you enjoy it. Yep. And also contact us with any questions or topics, anything. Leave your name, preferred method of shout-out, which nobody does.
Starting point is 01:25:06 It could be website, Twitter, whatever. Now, what if we start getting some random questions because you said to contact us with any question? This is going to get awkward. We'll write you back like three weeks later. I'm down with that, but whatever. And we'll mention you on the podcast. Also, visit us at codingblocks.net where you can find show notes, which we have very
Starting point is 01:25:26 good show notes in case you guys haven't actually been there. Examples, discussions, and more. Yeah, and send your feedback, questions, and rants to comments at codingblocks.net and make sure to follow us on Twitter at CodingBlocks. And I'm not promising anything, but our show notes might include
Starting point is 01:25:41 some time code. Yep, that's right. Man. I don't even know why. so they can skip the boring parts there is nothing as a matter of fact we're gonna start mixing important stuff at the very first 30 seconds of the show everything i say is important all right peace out hey by the way Merry Christmas everybody cause you know we're not getting another one in before Merry Christmas Happy Hanukkah what else is there
Starting point is 01:26:13 Kwanzaa I don't know like all the other ones that's why everybody just lumps it in to Happy Holidays Happy Holidays everybody

There aren't comments yet for this episode. Click on any sentence in the transcript to leave a comment.