Coding Blocks - We’re Testing Your Patience…
Episode Date: December 15, 2014I 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)
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.
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!
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,
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.
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,
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.
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.
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.
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
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.
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.
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.
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
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.
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.
I bring you these 10 reviews.
So yeah,
that one was awesome.
Also,
uh,
Arnie good.
So he actually mentioned,
or she,
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
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
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
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.
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
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.
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.
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,
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.
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
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?
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
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
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.
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.
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.
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
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,
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.
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,
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.
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
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
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
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.
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
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.
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.
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.
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.
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
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.
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?
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.
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
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
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
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.
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.
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
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,
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
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?
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?
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.
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.
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,
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
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.
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.
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,
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,
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?
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.
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.
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.
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,
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.
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,
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.
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
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
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?
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,
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,
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,
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.
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.
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
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.
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
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
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.
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.
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.
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.
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.
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.
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,
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.
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?
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?
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.
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.
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.
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.
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.
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.
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.
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,
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,
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.
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.
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.
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,
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?
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,
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
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.
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.
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.
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.
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
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
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.
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.
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
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,
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,
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.
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
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
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.
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.
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.
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
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.
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
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.
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.
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,
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?
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,
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
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,
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.
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,
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.
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
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
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
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.
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
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.
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?
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
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.
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.
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.
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,
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
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,
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
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.
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.
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
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.
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?
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,
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?
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.
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,
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,
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
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.
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,
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?
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.
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
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.
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.
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.
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.
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
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
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
Kwanzaa
I don't know like all the other ones that's why everybody
just lumps it in to Happy Holidays
Happy Holidays everybody