Jeff Terrell: Alright, welcome back everybody back to reality, I hope everybody had a good fall break I certainly did is very nice to have a couple of days to relax.
Jeff Terrell: Hope you found it restful.
Jeff Terrell: I only have two more lectures to give in this class so i'll try to make them count today we're going to be talking about testing.
Jeff Terrell: Wednesday will probably continue our discussion of testing and testing related topics.
Jeff Terrell: And after that will be on to tech talks.
Jeff Terrell: Also on Wednesday, we will have our final quiz of the Semester.
Jeff Terrell: and keep in mind that Wednesday the tech talk preferences are do I already have I don't know, maybe 10 or 12 tech talk.
Jeff Terrell: topics and dates posted to the website so if you're curious which dates are still available or what the topics people have already chosen are so that you can work around those constraints feel free to check out the website, I am up to date as of an hour ago.
Jeff Terrell: Note that the first day of tech talks is it is one week from right now so three teams will actually be presenting on Monday.
Jeff Terrell: So keep that in mind, you know these tech talk topics and dates are first come, first serve so if nobody volunteers, for the first day of tech talks a week from right now.
Jeff Terrell: We already have one volunteer where one one team scheduled for that, but if nobody else volunteers, then basically that's probably going to be the last two teams to get me your preferences.
Jeff Terrell: are going to end up going on Monday, which maybe would be fine to get that out of the way, but just letting you know that's relatively short notice to turn around from Wednesday to Monday and give a decently long talk.
Jeff Terrell: also remember that the.
Jeff Terrell: tech talks require you to have some sort of active learning component and that just means involve the audience somehow it could be as simple as a kinds of things I do with poll everywhere, or that could be something more involved, you could have a quiz at the end, you could have.
Jeff Terrell: A sort of lab or tutorial for people to follow, along with and give them instructions for how to do that, so how you want to do that is up to you, but just be sure to involve the audience somehow for full credit.
Jeff Terrell: DEMO videos as i've mentioned to you a time or two before they are do starting next Monday, so keep that in mind, and they will be doing every week from then on this will be demoing new features that you create during the previous week so.
Jeff Terrell: that'll be an important communication device for you to share your work with everybody, including you know the ta and I.
Jeff Terrell: And i'll mention one thing I got some feedback from mentor Mike who's the mentor for team l he mentioned that he's actually used the DEMO videos he's kind of on his team storyboard at the DEMO videos before he even started development.
Jeff Terrell: And the team would get together and kind of sketch out what they think their next DEMO video should show.
Jeff Terrell: And then they would go off and try to make that happen, you know implement that DEMO video so that was a neat way to kind of turn the concept on a tad almost kind of in the same way that test driven development.
Jeff Terrell: talks about writing tests for this is a way to just to organize what is it that we're doing and what is important and it helps the team.
Jeff Terrell: focus on delivering the most value to the customer, or to a client in the next iteration so maybe something you want to do, maybe not they would just sketch it on a whiteboard sketch out what the DEMO video would look like.
Jeff Terrell: and periodic reminder that the APP lab is a good place to go to you for technical help.
Jeff Terrell: Now, given that we're not going to be doing lectures, for me, after this week I might not really have much in the way of announcements, at least during lecture time i'll probably save as much of that time as possible for tech talks.
Jeff Terrell: So I might not be reminding you have upcoming deadlines so be aware of that.
Jeff Terrell: we've got.
Jeff Terrell: test coverage report do November 8 we got a variety of things do over the next month or so so just keep that in mind, be responsible, maybe.
Jeff Terrell: You know, you might want to add credit cards to your trailer board about the assignments and they're due dates and stuff just to make sure that you don't forget.
Jeff Terrell: Okay, I wanted to check in now that fall break Oh, is there a question.
Jeff Terrell: I think.
Jeff Terrell: Right.
Jeff Terrell: yeah, I suspect, so the question was For those of you on zoom What if the one topic that you want to do.
Jeff Terrell: You might have difficulty filling the available time with that topic, and can you do more than one topic I think that's fine, I think the main idea is just to give you practice communicating to people in this sort of a setting and communicating technical ideas to a technical audience.
Jeff Terrell: That said, it'd be a little bit surprised if, once you got into it, you didn't actually have enough content these things have a tendency to like once you start getting into them.
Jeff Terrell: You could talk about almost anything for for 2025 minutes, especially when you're getting other people involved and maybe walking into a tutorial or something like that.
Jeff Terrell: also keep in mind, you know your your mentor might be a good test audience for your tech talk so if you're prepared enough to get your tech talk ready before you meet with your mentor some week, then that might be a good way to get some good feedback for your tech talk.
Jeff Terrell: Any other questions or anything.
Jeff Terrell: Okay.
Jeff Terrell: Alright, so Moving on, I wanted to check in about how are you feeling about your project, now that the walking skeleton has been.
Jeff Terrell: Do.
Jeff Terrell: And just at this point in the Semester just checking in.
Jeff Terrell: All right, still some people in green couple people in orange but, most people are somewhere between yellow and light green okay.
Jeff Terrell: cool so it seems like it might be somewhat stressful for some of you.
Jeff Terrell: i'm sorry.
Jeff Terrell: But most of your feelings somewhat okay about it so that's good.
Jeff Terrell: Okay cool just checking in i'll leave that open for a bit more.
Jeff Terrell: Okay, so today it's going to be a little bit of a different day i'm going to be a lot less slide driven and going to do a lot more.
Jeff Terrell: Working in front of you to show you different things and show you how it actually looks in a development environment.
Jeff Terrell: And i'm really going to be focusing on testing, as the title of today's lecture indicated, but before I go there, I wanted to just tell a story about a recent project and talk about some of the lessons learned.
Jeff Terrell: There kind of related to testing, so I worked on a project recently, this would have been like.
Jeff Terrell: Maybe a year ago year and a half, and it was not the best code base i've seen.
Jeff Terrell: There were a lot of repetitive ways of doing things that were all in the code base.
Jeff Terrell: And there were even, in some cases like multiple dependencies that would do the same thing, and it was like one person had decided they wanted to use this approach.
Jeff Terrell: And a different person had used some other approach to solve the same kind of problem, but both of those approaches were in the code base they use different dependencies and there's a lot of repetition in the code base there weren't any tests.
Jeff Terrell: And the code generally just wasn't very simple or clean or organized.
Jeff Terrell: And it was kind of difficult to dive into this project, I mean.
Jeff Terrell: You know, we figured it out, and we were able to make progress, but as you we were trying to you know add features to this code base and you've heard me kind of talk about some of these things before, especially with agility.
Jeff Terrell: We would dive in and we'd say like what does this code that i'm looking at do is it relevant to the thing that I need to do right now with this feature that i'm trying to implement I don't know it's kind of hard to understand what this code is doing it's not really very clean.
Jeff Terrell: And if i'm trying to solve a problem, like.
Jeff Terrell: Maybe there's a particular implementation approach that I want to use and I don't know if somebody has already done this, and maybe written a set of functions for me that would make this job easier or not.
Jeff Terrell: I don't have a clear sense of what all is in this code base and, of course, because I don't have tests it's really not easy for me to figure out if i'm changing existing code, am I breaking anything.
Jeff Terrell: So these were reasons why it was kind of slower to get in this project, and it would have been on a different project that maybe it was more organized.
Jeff Terrell: And so I had to I kind of recommend it to some of the people I was working on, I think it's important to.
Jeff Terrell: take a step back from the features, we need to work on and start to clean up the code base a little bit and address some of these things.
Jeff Terrell: And what that meant is you know these features that people wanted.
Jeff Terrell: had to take a backseat to actually cleaning up the code base and it's not it's not a fun situation to be in because I mean, thankfully, the clients in that case we're really understanding, but.
Jeff Terrell: In some cases you're like trying to explain to your client why you're not really delivering on features right now.
Jeff Terrell: And maybe explaining that the developers up to this point in the project, maybe haven't done the best job of keeping the code, simple and so now we need to address some of the complexity that has gotten into the project.
Jeff Terrell: And this happens fairly often and in software.
Jeff Terrell: And one of the key ideas here with this project is that complexity begets complexity.
Jeff Terrell: If you're starting from a place of a complex code base it's going to be pretty hard for you to avoid complexity in your solution.
Jeff Terrell: If you're starting from simplicity, you still have to work to eliminate as much complexity, as you can, but at least then it's a lot more possible if you're starting from a complex State then it's likely that your solution is going to add yet more complexity, to the project.
Jeff Terrell: and complexity adds a good metaphor here would be drag you know, like airspeed drag for maybe an airplane or.
Jeff Terrell: Just the friction of wind on your windshield and your car that kind of thing complexity is drag on your project more complex your project is and your code bases less simple it is the more progress is going to be slowed down.
Jeff Terrell: Another metaphor would be debt like financial data, you know you're swiping a credit card is going to add drag on your finances, because now, you have to pay interest on the loans that you took out.
Jeff Terrell: So the lesson here is spend time refactoring before your messy code gets repeated and compounded.
Jeff Terrell: And we've talked about this right red green refactor agile practices so you've seen this before.
Jeff Terrell: This is the xp value of simplicity.
Jeff Terrell: But I wanted to mention that, again in the context of this project and that's relevant to testing because testing.
Jeff Terrell: Good tests make refactoring easy and safe and so we'll talk today extensively about what good tests are and trade offs between different kinds of tests in a bit of a toy example, but one with real code.
Jeff Terrell: And before we move on, I did want to mention a pretty famous refactoring principle is don't repeat yourself if anybody ever heard the term dry.
Jeff Terrell: yeah few people okay.
Jeff Terrell: yeah so dry means don't repeat yourself, and that means that if you are finding duplicate code like you're adding duplicate code what you really should do is.
Jeff Terrell: extract the commonalities into some other place maybe a function that both of these instances call or class or something like that, and then.
Jeff Terrell: Let the parameters of your function, or maybe the instance variables of your class or something like that to term or capture kind of the variation between the different pieces of code, but if you have a lot of repetitive structure and repetitive code it's worth taking some time to.
Jeff Terrell: Extracting out the commonalities so that you're not repeating yourself that tends to be I mean that's kinda.
Jeff Terrell: it's not always a good idea, there are cases, especially if you don't understand the pattern well enough yet where you might want to wait on doing that, but as a rule of thumb that's one of the most useful ones that I could impart to you as far as keeping your code organized.
Jeff Terrell: And something else about this, so when is something done I, this is something i'm pretty sure i've talked with you all about before, but as a reminder.
Jeff Terrell: I recommend not considering a feature done until there one there are tests for it and to the Code is as simple as you can make it, in other words you have tests and you have refactoring.
Jeff Terrell: Otherwise, the feature is not done, if you have that definition of done in your mind as you work on your project it'll help you avoid complexity and keep things simple and.
Jeff Terrell: avoid a lot of problems that you might have otherwise keep your drag minimal and keep your speed as fast as you can.
Jeff Terrell: But that said, sometimes it is useful to defer tests until later, maybe you have a meeting coming up with your client and you really want to get this one feature done and that's most of the way done but.
Jeff Terrell: You haven't finished all the tests for it, or maybe you haven't made it as clean as it can be.
Jeff Terrell: And so yeah maybe you go ahead and hit the deploy button on that thing, and you know that you need to come back and figure out the tests, but just keep in mind.
Jeff Terrell: You really should come back, while it's still relatively fresh and add the tests and refactor the code don't forget that you need to do that.
Jeff Terrell: And you know, maybe, that means that you have a conversation with your client as well to say like.
Jeff Terrell: yeah I got this out the door, but it's not really finished, I still need to go back and kind of clean things up and that's going to mean that next iteration i'm going to have less ability to take on more work because some of my time needs to be spent paying down this debt.
Jeff Terrell: Okay, any questions about that.
Jeff Terrell: kind of remember to refactor remember to test.
Jeff Terrell: Testing really makes refactoring easy so.
Jeff Terrell: let's talk about testing all right i'm going to do an extended testing DEMO i'm going to include testing doubles and dependency injection.
Jeff Terrell: we're going to look at some of the trade offs between unit tests and integration tests see some of the ways, these are things I talked about last lecture feels like so long ago, but.
Jeff Terrell: Before the midterm presentations before fall break I was talking about testing and you might remember some of the things that I talked about were like unit tests just test a single unit of code.
Jeff Terrell: Integration tests are testing more than one unit together, making sure that they are integrated together correctly.
Jeff Terrell: But let's dig in and see all these things.
Jeff Terrell: Time to do some real work.
Jeff Terrell: Okay.
Jeff Terrell: So yeah, so this is going to be an example of a tests in a javascript project and node js project node is just a way of running javascript outside of the browser.
Jeff Terrell: I am going to look at different trade offs of like unit testing versus integration testing and whether to mock or not to mock mock as a kind of testable so we'll talk about tests devils will see an example of dependency injection.
Jeff Terrell: And I actually have all of these all of this code committed and public in get lab so feel free to check that out and follow along if you're interested or, if you want to just play around with it on your own time that that code is available.
Jeff Terrell: The commits are actually really.
Jeff Terrell: verbose I would say they're they're intended to be kind of a tutorial style so.
Jeff Terrell: Even if you didn't have the benefit of seeing this lecture you would still be able to look at that testing tutorial and look at the actual commits.
Jeff Terrell: And those kind of tell the story about what i'm doing and why and what the trade offs are without you know, seeing a presentation, or something as well.
Jeff Terrell: If you do clone this repo in case you don't know don't have javascript like node js development experience, then you will have to say in PM install this is assuming that you have node installed and mpm installed and game is the node package manager.
Jeff Terrell: But um yeah if you want to follow along that would be how and I, of course, already have this installed on my on my machine i'll be summarizing lessons at the end, as well as talking about lessons along the way.
Jeff Terrell: So i'll pause every once in a while and say like you know here's something we learned.
Jeff Terrell: Okay.
Jeff Terrell: So i'm gonna go see let's go here.
Jeff Terrell: Is that big enough everybody said hard to see.
Jeff Terrell: Because in the back row yeah okay we're good on zoom.
Jeff Terrell: Okay, see a thumbs up great Thank you.
Jeff Terrell: Okay, so I am in I have cloned this repo.
Jeff Terrell: And so you can see i'm i'm in the same repository that I described and I have you might remember this from when we talked about get I have an alias defined forget l.
Jeff Terrell: My alias is it means log dash dash dash dash decorate dash dash one line if you want to create that alias for yourself, you can do that through the get config command or by editing the your get config file.
Jeff Terrell: But anyway, get l is going to tell me a list of commits, this is the initial commit going up to the most recent commit, which is what master points to.
Jeff Terrell: OK so i'm going to basically what the structure of this DEMO is going to be i'm going to walk through the commits in order.
Jeff Terrell: And I might skip a couple that are less interesting, but this is kind of telling the story of of testing and looking at some of the trade offs here.
Jeff Terrell: So i'm going to skip to this one.
Jeff Terrell: And I have good seo as an alias for check out.
Jeff Terrell: check out this one show the most recent commit this is where i'm adding just for testing.
Jeff Terrell: Just as a good tool for doing testing and a node js projects different people have different preferences for what testing framework and testing runner and that kind of thing that they want to use in their project.
Jeff Terrell: If you don't have a preference on this, I recommend just I think it's a good little tool.
Jeff Terrell: But yeah This is just adding the.
Jeff Terrell: The just dependency.
Jeff Terrell: Also, adding a command for mpm test.
Jeff Terrell: So now, the command for mpm test is the same as just dash dash watch and watch is going to watch the source code for changes and anytime there's a new change to the source code, it will rerun the relevant tests.
Jeff Terrell: So it'll keep watching and stay in the foreground.
Jeff Terrell: So let's give that a shot.
Jeff Terrell: mpm test is how I actually run this.
Jeff Terrell: And this is what justice telling me it's still there it's waiting for me to enter you know, a keystroke to tell it what I want it to do it says no tests found related to files changed since last commit.
Jeff Terrell: And i'm going to hit a to run all tests.
Jeff Terrell: And it says no tests found exiting with code zero.
Jeff Terrell: And if I hit w it'll tell me the usage here, this is, this is one of the reasons I like test.
Jeff Terrell: Is.
Jeff Terrell: I can filter the tests in various ways, so I can say, I only want to run tests for this file or I only want to run this specific tests.
Jeff Terrell: You can give it regular expression patterns.
Jeff Terrell: You can run only failed tests or only tests related to change files I believe that's the default only the stuff that's changed so it's pretty nice to be able to.
Jeff Terrell: kind of zoom in and filter so that you're only seeing the tests that you want to see it at any given moment.
Jeff Terrell: Right now, there are no tests so that's probably not as interesting.
Jeff Terrell: So what i'll do next let's look again it's my in fact i'll make an alias for this.
Jeff Terrell: i'll.
Jeff Terrell: master okay.
Jeff Terrell: Alright, so right now we're here on the fourth commits This is where we added just and i'm going to go to the next commits okay check out that.
Jeff Terrell: And here I added a new test Okay, this is in a new directory test.
Jeff Terrell: This one is called standard these tests dot J S, so I what I didn't show you is that I actually have.
Jeff Terrell: Three files in here, I have i'll start with some here, I have a function some which just computes the some of the numbers in some array that's passed in this is a javascript code, this is a function.
Jeff Terrell: I have a main function.
Jeff Terrell: And this does what you would expect to confuse the mean of the numbers in an array that array has passed into the main function.
Jeff Terrell: And then, I have a standard deviation function, which is kind of the point of this repo and Center deviation is going to use some and mean in order to do what it needs to do.
Jeff Terrell: And so now, I have a test for standard deviation as of this commit.
Jeff Terrell: And i'm saying the standard deviation function for.
Jeff Terrell: The numbers one, three and five should equal to.
Jeff Terrell: So let me actually restart just because.
Jeff Terrell: Justice smart enough to notice when files change but it's not smart enough to notice the new directory, it was created, with a new test file in it.
Jeff Terrell: see if I can move this way here.
Jeff Terrell: Here we go.
Jeff Terrell: i'm going to run all tests and it found standard deviation test js justice going to look for anything that ends in tests js and it looks like that test actually passes.
Jeff Terrell: Then I break this down just a little bit here in my test file I need to require the standard deviation function, so that I can actually test it.
Jeff Terrell: And then, this describing it and expect stuff.
Jeff Terrell: Is what justice, providing justice, giving me a describe function and it function and expect function.
Jeff Terrell: and
Jeff Terrell: I actually really like this style of testing I like the idea that we say describe and then we give a noun the standard D function.
Jeff Terrell: And then within that describe block we say it.
Jeff Terrell: And then we give some description of a behavior that that now, and should have.
Jeff Terrell: And it says it returns, the correct standard deviation.
Jeff Terrell: And then the implementation of the behavior.
Jeff Terrell: is to expect something.
Jeff Terrell: To equal to.
Jeff Terrell: Right we're expecting standard deviation of 135 equal to, so this way of writing a test I think is very natural way of expressing tests.
Jeff Terrell: describe a noun it does this, it does that listing all the behaviors of that noun and then you have your implementation of the actual behavior in here.
Jeff Terrell: This generally is called behavior driven development being able to focus on the behaviors of a function or a class or have some unit of your code.
Jeff Terrell: And I recommend it.
Jeff Terrell: In my experience, it helps your tests be focused helps your tests be readable it helps you focus on the important things which I think are the behaviors.
Jeff Terrell: So that's one thing, just as other testing frameworks don't focus on behaviors as much, but this is kind of what I prefer.
Jeff Terrell: Questions so far.
Jeff Terrell: Okay.
Jeff Terrell: So now we have a test and it passes.
Jeff Terrell: And this is what our test output looks like we have green test output and remember the phrase and test driven development red green refactor.
Jeff Terrell: It kind of comes from this idea or well i'm not sure chicken or egg which came first but.
Jeff Terrell: The typical output, that you would expect from any sort of test runner if it if all the tests past is green and so justice doing that same thing it's giving you a color indicator of whether your tests failed or past.
Jeff Terrell: But now let's break the some function.
Jeff Terrell: and see what a failure message looks like.
Jeff Terrell: Now we have read right red green refactor so RAD is indicating that something failed.
Jeff Terrell: And what failed is the standard deviation function returns, the correct standard deviation notice how, when I specified describe and it.
Jeff Terrell: that's a pretty natural thing that the that justice telling me this is kind of a name of this test.
Jeff Terrell: slash the name of a behavior.
Jeff Terrell: And it reads like English right the standard the function returns, the correct standard deviation, and that is failing we expected to.
Jeff Terrell: But we received 1.6666 etc.
Jeff Terrell: It shows me on which line the failure occurred so that's pretty useful pretty useful feedback.
Jeff Terrell: And one of the takeaways here, let me go to this lesson number one tests notify you about broken code, this is one of the big benefits of tests and you can be notified about this.
Jeff Terrell: Maybe every five or 10 seconds as you're developing I mean you can make a small change it's safe get notified.
Jeff Terrell: make a small change it safe get notified and this can be part of your flow as you're writing so this can be something that is.
Jeff Terrell: Not just valuable you know one time, when you think you're all done with the future, this can be something that is valuable as an integral part of your development workflow.
Jeff Terrell: I talked before about how that can build.
Jeff Terrell: Get you into the mindset of creative flow, which is a lot of fun.
Jeff Terrell: Now, the problem is this test failed.
Jeff Terrell: And if we look at.
Jeff Terrell: source standard deviation.
Jeff Terrell: That means presumably somewhere in this code, possibly in the test case itself there's a failure or some sort of a bug but presumably somewhere in this code, there is a bug and So where does that bug live.
Jeff Terrell: One thing that's useful, by the way, is, we could actually just had print statements here.
Jeff Terrell: And this is actually really nice, I have a test that gets run every time I save a file, and so I can add my print statements and I have a.
Jeff Terrell: Something that gets run repeatedly and I can start to inspect, what are the various values at at this point in the test run.
Jeff Terrell: So this can actually be a really nice way to debug what's happening, you know is is this mean what we expect it to be, and if so, then maybe we move on to squared errors and look at what that is.
Jeff Terrell: and keep on moving until we figure out where something maybe isn't what it should be, but we have this being called in a deterministic way, and so we would expect every time the results to be the same, and just adding simple print statements can be a really effective way to debug.
Jeff Terrell: But one issue with this is that.
Jeff Terrell: This code is requiring code from some and mean.
Jeff Terrell: So maybe the bug is in this code here, but maybe it's actually inside some.
Jeff Terrell: Or maybe it's inside mean.
Jeff Terrell: We don't really know we have to dig deeper and figure out Where does this bug left.
Jeff Terrell: So.
Jeff Terrell: This brings us to another lesson.
Jeff Terrell: These five lines or, if you want to get pedantic these seven lines.
Jeff Terrell: Give us pretty thorough coverage of our code.
Jeff Terrell: They don't test every single thing, but they actually do test a lot, and this was relatively low effort to write this code.
Jeff Terrell: Especially once you're familiar with describing it and expect and things like that this is pretty easy to whip out a test like this and we're able to test, you know how many lines of code it's probably.
Jeff Terrell: there's 10 in this file and there's a handful and the other files as well, so it's a decent number of lines of code that we're testing, with just seven lines of tests.
Right.
Jeff Terrell: So that's relatively high leverage testing code.
Jeff Terrell: But it's kind of difficult to debug what's going on, because we just know somewhere, either in standard deviation or in some module that it depends on, we have a buck.
Jeff Terrell: So.
Jeff Terrell: This test is an example of an integration test why.
Jeff Terrell: Do we remember what integration tests are.
Jeff Terrell: yeah.
Jeff Terrell: that's right more than one component of our application and which components, do you know.
Jeff Terrell: That is why it's a standard deviation as well as some and mean, these are all three different units of our code, and so this test is testing all three of those units together, so it is an integration test.
Jeff Terrell: And so we're able to get pretty good coverage from just this one short test, but it doesn't help us very much figure out where the bug lives.
Jeff Terrell: So I think what would be good to do as a next step is to.
Jeff Terrell: start to add more tests and test, not just your standard deviation but to add tests for.
Jeff Terrell: do this.
Jeff Terrell: That tests for some and mean as well.
Jeff Terrell: So let's do that in fact that's what we have in the next commit.
Jeff Terrell: Here we still have a failed test.
Jeff Terrell: But here we actually have some interesting output, it says three to do and i'm gonna hit a to run everything.
Jeff Terrell: I mean, I guess it already was running everything, maybe, but yeah this is telling us, we have three to do so, let me look at that.
Jeff Terrell: The code that I added was for a new some test and I didn't actually implement these tests, yet, but what I did was I marked them as to do tests, meaning, this is a behavior that would be important to test, but I haven't actually written the the code for that yet.
Jeff Terrell: I actually recommend doing this in general, especially if you're going to do test driven development, which I think is a good practice to get into I recommend trying to list out the behaviors of code before you actually write the code.
Jeff Terrell: And it turns out.
Jeff Terrell: This has convenient output in your test window it's nice to have that test window open at all times kind of like I have here, you can just always be getting that feedback.
Jeff Terrell: And a good test runner is going to give you a visual indication that you have a certain number of to do tests that you haven't written yet, but intend to, but this is also a really good way to just collect your thoughts about what you need to implement.
Jeff Terrell: As you start to do the quality to the Max thing and get progressive refinement down to the level of actually writing lines of code.
Jeff Terrell: This is a great way to like stop at one level and just list out all the behaviors that some function should have.
Jeff Terrell: And then you can start writing the first test and write the code to make that pass right the second test write the code to make that pass.
Jeff Terrell: Right, the third tests write the code to make that pass so that would be test driven development that's a really.
Jeff Terrell: it's a flowing way to do it, you really get into a flow that way, so I recommend that and that's actually lesson number three listing behaviors is a great way to start development of a feature.
Jeff Terrell: Questions so far comments.
Jeff Terrell: let's also add some pending tests for.
Jeff Terrell: Some.
Jeff Terrell: Are where are these pending tests.
Jeff Terrell: Right now, we actually implemented, the tests for some they were a test to do's now they're actually tests.
Jeff Terrell: So we expect.
Jeff Terrell: To return zero given an empty array so we implemented that test.
Jeff Terrell: We expected it to return the only item of one item array that's what some should do right, and then we expected it to return the sum of multiple numbers, if you give it multiple numbers so some of one, two and three is six.
Jeff Terrell: All right, and now we see we have both of our test suites failed meaning both of those test files.
Jeff Terrell: And three out of our four tests have failed at this point and we can scroll up in this window to see exactly what failed.
Jeff Terrell: This is helping us get a little bit closer to understanding, where our bug is, of course, we know that the bug is actually in some because.
Jeff Terrell: This commit right here said so, but if we didn't know that you know, imagine that we're running some code and running the tests and we figure out that there are certain number of failing tests, we want to understand what's broken in our code.
Jeff Terrell: i'm getting you know, three failures out of four total and that it's a little bit harder to figure out what what to do, from this point.
Jeff Terrell: Now, if we happen to remember that standard deviation depends on some or we do some investigation and remember that because we see that require line.
Jeff Terrell: Okay yeah That would be a helpful indication that maybe there's at least a bug and some that needs to be fixed and maybe if we fix that that would fix the bug and standard deviation as well.
Jeff Terrell: But we'd have to do some digging to understand that, first, something we can do is.
Jeff Terrell: Create unit tests, even for modules that have dependencies.
Jeff Terrell: So we'll do that.
Jeff Terrell: But.
Jeff Terrell: Before we get there let's fix the bug.
Jeff Terrell: And our bug was actually that we started counting in the sun from one instead of from zero.
Jeff Terrell: so simple little thing just an off by one error, but now all of our tests pass and we have that Nice green output, so that feels good.
Jeff Terrell: let's add some tests for mean.
Jeff Terrell: Now we have three different behaviors that we've listed for the main function.
Jeff Terrell: notice that i'm giving kind of some base cases here, like some of the more trivial inputs, to be sure that those return reasonable results.
Jeff Terrell: So mean should return undefined if you're given if it's given an empty array.
Jeff Terrell: And should return, the only item of the one item array you know, given a an array of launched return one.
Jeff Terrell: And then I should actually give you the actual mean have multiple numbers.
Jeff Terrell: Now all of our tests are passing or could looks good.
Jeff Terrell: But again, if we break some we're in this case where.
Jeff Terrell: six out of seven of our tests fail and all three of our test suites fail.
Jeff Terrell: So that can be kind of overwhelming imagine a real project with 100 different tests.
Jeff Terrell: Or maybe several hundred and.
Jeff Terrell: You make a change, and you know, maybe you're you're not in a good habit of making a small change and rerunning the test suite or maybe the test suite takes five minutes to run and so it's hard to get that quick feedback.
Jeff Terrell: But something changed you're not quite sure what you run the test, and then you got 30 broken tests say Oh, my goodness, I have to dig through all this code to figure out where that bug is.
Jeff Terrell: So what we'll do.
Jeff Terrell: Is we will use mocks.
Jeff Terrell: And, starting with the mean test i'll show you what that looks like.
Jeff Terrell: And, in fact, let me do it this way.
Jeff Terrell: Just provides an ability to mark out a dependent module and suggest this going to go into this module.
Jeff Terrell: and replace all of the functions with.
Jeff Terrell: Something that just can keep track of and intercepts and things like that, so we do that, first, and then we require some.
Jeff Terrell: And then in our mean test we can intercept so that this one I I suppose we don't ever call some, I guess, we could say.
Jeff Terrell: You know mock return value to be zero or something like that, if we wanted to but.
Jeff Terrell: The here, we would actually call some.
Jeff Terrell: And we want to mock the return value to be one what this is basically saying is hey just if some gets called in this code here.
Jeff Terrell: I want you to intercept that call don't allow it to actually hit the some function for real and just quickly return one without actually calling any code at all.
Jeff Terrell: So that makes sense, so i'm i'm short circuiting the call from me to some.
Jeff Terrell: Because mean call some right.
Jeff Terrell: pause it right there.
Jeff Terrell: But during the test run i'm saying I don't want you to call it, I want you to.
Jeff Terrell: Just short circuit that and give a particular return value, and this is pretty important to understand this will help you understand what mocking is and test doubles and show that this is how we're going to do unit tests, this is really one of the.
Jeff Terrell: Actually it's actually not the only way to do a unit test for something that has dependencies the other way would be dependency injection which I will also show you, but this is a one of the ways that people do.
Jeff Terrell: So now, with the mock return values.
Jeff Terrell: One of my test suites past.
Jeff Terrell: And now, I have three out of seven tests that pass instead of one out of seven, we can see that the mean test suite actually does pass.
Jeff Terrell: And if I do mark that here as well, which probably is a better thing to do, to be honest, since I think I will be calling some in every case, we still have a mean test suite that does pass does that make sense, why that passes.
Jeff Terrell: That makes sense, what i'm doing with mocks okay.
Jeff Terrell: So I have converted.
Jeff Terrell: mean from an integration test.
Jeff Terrell: To a unit test why.
Jeff Terrell: yeah.
Jeff Terrell: Sorry.
Jeff Terrell: It is but yeah see now it's not an integration test, so if there is a bug in mean will find it, but if there's a bug that somewhere else we don't need to know about it yeah yeah that's true yeah we converted this into a unit test because.
Jeff Terrell: This mean test, no longer depends on some.
Jeff Terrell: We intercepted the calls to some so some can be broken, in fact, some is broken right now but mean is still going to mean test is still going to pass.
Jeff Terrell: To unit test.
Jeff Terrell: And it is accurately telling us there's no problem with the mean code.
Jeff Terrell: That is the correct response right there is a problem with the some code, but there's not a problem with the mean code and so now our test output is a lot less noisy.
Jeff Terrell: Because we have tests that are more accurately telling us where the bug is.
Jeff Terrell: That makes sense that's a pretty important point.
Jeff Terrell: go over to my lessons here.
Jeff Terrell: So with integration tests, a single bug and a dependency can cause of multiple tests to fail that's not the case with unit tests, if you have a unit test it's only testing that unit and it's only going to fail.
Jeff Terrell: If there's a bug in that unit.
Jeff Terrell: So integration tests can be kind of noisy in the test output if there's a bug.
Jeff Terrell: we've also seeing less than five test doubles such as marks marks are kind of testable testable is make testing easier.
Jeff Terrell: The idea of the devil is kind of coming from stunt doubles and movies, like if you have a stunt double that person is taking on too dangerous tasks and assistance and is supposed to kind of fill in for the actual actor, so that the actor doesn't have to take that risk on themselves.
Jeff Terrell: And the testable is kind of doing a similar thing making testing easier and filling in for something else.
Jeff Terrell: Okay, one more lesson here mocks a kind of testable that you interrupt dependencies and convert integration tests into unit tests.
Jeff Terrell: So that's a pretty powerful technique for testing to be able to convert an integration test to a unit test, by the way, this can also speed up your tests.
Jeff Terrell: With some we didn't save a whole lot of operations right we had fairly small arrays, and these are pretty Nice, you know low level just additions, so we didn't save a lot of work there, but imagine that you're you have a dependency that does some pretty complex stuff.
Jeff Terrell: And you have to call it, you know, a bunch of times, or something like that, I mean that can really throw your tests down so sometimes it's nice to be able to just knock that out.
Jeff Terrell: and speed up your test gets faster feedback.
Jeff Terrell: i'm going to finish this out and do mocks in the standard deviation test as well.
Jeff Terrell: And now.
Jeff Terrell: This is great so to have our test suites pass.
Jeff Terrell: The standard deviation test suite passes.
Jeff Terrell: The mean test suite passes and now our tests are accurately telling us that the bug lives in some.
Jeff Terrell: So our test output is actually really helpful at this point it's telling us, there is a bug but you don't need to worry about it in mean or standard deviation it's only in the some module.
Jeff Terrell: And so, then we fixed that bug.
Jeff Terrell: Actually, before I do that, let me just show.
Jeff Terrell: All I did there was, I said oh yeah, this is actually another important point.
Jeff Terrell: Right, let me show this.
Jeff Terrell: Okay So here we did in a Center deviation test we needed to mock both the sub module and the mean module.
Jeff Terrell: And we need to to mock the return value of the main function and the return value of the some function, and this is kind of important all right if we're passing if we say standard deviation of 135.
Jeff Terrell: We might think that we should return the some.
Jeff Terrell: function, so that it returns nine right one plus three plus five is 998.
Jeff Terrell: But this song has been called in such a way that we are summing.
Jeff Terrell: The sum of squared errors, not the sum of the numbers.
Jeff Terrell: So let me show you that code.
Jeff Terrell: We have.
Jeff Terrell: A squared errors, so we take the mean we'll figure out how much different is each item from the mean we square that number, so we always have positive numbers here.
Jeff Terrell: And then, when we call some is the sum of the squared errors okay and that's something that we use in the standard deviation formula.
Jeff Terrell: And so now all of a sudden, this is a, this is a reason why people do not like Marks all right, people say you should not use marks for this reason.
Jeff Terrell: Now all of a sudden that test has to know implementation details a standard deviation.
Jeff Terrell: Right this test has to know a lot more than it had to know before, when it was just an integration test.
Jeff Terrell: Now it's got to understand how is it calling some.
Jeff Terrell: And that gets into the details of how the standard deviation function actually works and Some would argue, and I think they have a point that that's too much knowledge for a test to have.
Jeff Terrell: A test should not have to know that.
Jeff Terrell: So look there's no right answer here right, these are all trade offs, this is a common theme in this course, we have trade offs.
Jeff Terrell: We have things intention which with each other there's no wrong answer we just have to decide what fits the current use case what fits the needs and the constraints in front of us.
Jeff Terrell: But this is an important constraint and.
Jeff Terrell: important characteristic of mocks to be aware of.
Jeff Terrell: Questions about this.
Jeff Terrell: Okay.
Jeff Terrell: But anyway, um.
Jeff Terrell: Now our tests are correctly telling us.
Jeff Terrell: That some is where the problem is and we go off and we fixed the some bug.
Jeff Terrell: which by the way, was we just returned.
Jeff Terrell: Extra stuff besides the accumulator.
Jeff Terrell: kind of contrived I know, but now we fixed that bug and all of our test suites are green so that's great.
Jeff Terrell: Okay.
Jeff Terrell: And before we go further, let me just take a poll here.
Jeff Terrell: How are we feeling about a code driven lecture.
Jeff Terrell: Is this better than the typical slide style extra that I do is it is it worse it's more effective for you to learn less effective for you to learn.
Jeff Terrell: interested in whatever feedback, you want to share with me there.
Jeff Terrell: Okay, and just for me to see here.
Jeff Terrell: Okay, so roughly even split between more effective and about the same so okay so maybe Maybe I should do more of these in the future, thank you for that feedback.
Jeff Terrell: Active there we go.
Jeff Terrell: Okay.
Jeff Terrell: Alright, so I got ahead of myself here let's go back to our code to go for commits to get through here.
Jeff Terrell: doing all right on time.
Jeff Terrell: Okay now i'm adding a top level scripts to run the program okay.
Jeff Terrell: Oh wait, I want to.
Jeff Terrell: Okay sorry.
Jeff Terrell: Good show.
Jeff Terrell: So I added a new.
Jeff Terrell: Top Level script Oh, is there a question.
Jeff Terrell: How long does it usually take to run tests, if we have a lot of them yeah, this is a really good question.
Jeff Terrell: I have heard people say.
Jeff Terrell: You should do a lot of mocking, even though there are some downsides of it, for example, the test stuff to know too much, but the reason to do that is so that you can get your entire test suite down to a sub second even for a relatively full featured web APP.
Jeff Terrell: that's one relatively extreme view but I actually kind of liked that view because I really think there's a lot of value in having fast responses from your test suite so that you can quickly know that I break something or not.
Jeff Terrell: Now, justice, going to let you filter stuff and so sometimes practically speaking you're not you don't need to run the whole test suite you just need to run the stuff that is relevant to the changes that you're making right now.
Jeff Terrell: And some it's easier to get that under a second or so than it is to get your entire test suite down to a second but.
Jeff Terrell: But, to answer your question to me.
Jeff Terrell: It really depends a lot on what kind of tests you're doing and I actually have a project that i'm working on, now that the whole test suite takes about three minutes to run.
Jeff Terrell: And the tests are very high quality they're actually browser tests, so they fire up a browser and they they go in Cyprus and.
Jeff Terrell: Tests like form submission and things like that, so I have a lot of confidence that the code is correct, if the tests we passes, but.
Jeff Terrell: I really don't have much of a feedback loop from the tests when i'm doing my development so that's definitely a downside, and something that i'd like to change in time but.
Jeff Terrell: yeah in in in practice what i've seen is anywhere from in some cases it's like sub second a pretty common window would be somewhere between like.
Jeff Terrell: For the whole test suite maybe one to 210 or 15 seconds and then sometimes depending on how much the tests are using like an end to end test or browser test it can even be multiple minutes.
Jeff Terrell: In that case, sometimes you know the you can run the unit tests separately or maybe the unit and the smaller integration test separately from the end to end tests and save that, for the very end.
Jeff Terrell: it's good question.
Jeff Terrell: Okay, so we just added this little run that js file and all this is doing is basically running a unit test on i'm sorry not a unit testing integration test on standard deviation.
Jeff Terrell: it's not doing any marketing so standard deviation is going to call whatever it calls, including some and mean.
Jeff Terrell: And all we're going to say is console log program seems to work if there was all we got was to, otherwise we say program is broken.
Jeff Terrell: So pretty simple We certainly could make this a test in just so that it came up in the test output here but i'm actually pulling it out of the output to make a point, so let me run this.
Jeff Terrell: Can I need to say node.
Jeff Terrell: js and it says yeah program seems to work.
Jeff Terrell: Okay.
Jeff Terrell: So everything's good our test suite passes are separate into n test script is telling us that the program seems to work so that's good.
Jeff Terrell: But something broke.
Jeff Terrell: Our test suite.
Jeff Terrell: Actually passes.
Jeff Terrell: But the end to end testing script tells us that our code actually is broken.
Jeff Terrell: So what happened there.
Jeff Terrell: And i'm going to pause that for a second and come back to jenny's question again.
Jeff Terrell: One thing to me that I have wondered actually is, why is just taking three and a quarter seconds to run these pretty small tests and I don't know if that might be because maybe just not Marcus slow or what I haven't taken the time to actually investigate that but.
Jeff Terrell: But three seconds is feeling long to me, and maybe i'm.
Jeff Terrell: Maybe i'm an unusual user maybe not but I really want it to be sub seconds that i'm not waiting even a couple of seconds for the tests to tell me if my code works or not.
Jeff Terrell: And starts to feel annoying if i'm having to constantly wait on these tests, even if it's only for a couple of seconds so So if I were doing this for real I would want to investigate Okay, why is just being a slow, as it is and seemed like it should take that long.
Jeff Terrell: But back to this Okay, why is.
Jeff Terrell: Why is our program broken this script seems pretty.
Jeff Terrell: Reliable I mean it looks like correct code right just getting a standard deviation function.
Jeff Terrell: I cost and deviation with one, three and five.
Jeff Terrell: And that should be two should be the standard deviation of those three numbers and then, if should be two equals to then say program seems to work, otherwise it's a program is broken, so I don't think there's anything wrong with this code.
Jeff Terrell: And our unit tests are not giving us any useful output here so.
Jeff Terrell: What is actually happening.
Jeff Terrell: let's.
Jeff Terrell: i'm gonna.
Jeff Terrell: i'm going to say cheat and look at what changed but it's really not cheating, by the way, if you're if you encounter a bug.
Jeff Terrell: And you know that this bug only happened recently, or it is only happening in the latest commit look at the depth of the committed you know that's not cheating that's just narrowing down the.
Jeff Terrell: The search space for your bug so I don't consider that cheating at all So what did we actually do.
Jeff Terrell: looks like we made a change to the some function.
Jeff Terrell: So now it is a function that doesn't have any named parameters, but it just uses this key word in javascript called arguments that can access the arguments have a function.
Jeff Terrell: And so it looks like instead of being passed an array now you're supposed to just pass numbers directly into some.
Jeff Terrell: And if we look at the test suite for some it's exactly what we see here we don't pass an empty array.
Jeff Terrell: We just passed zero arguments to some and that's.
Jeff Terrell: that's what's um.
Jeff Terrell: should be equal to zero, and if we have one item if we're trying to some one item used to be that we would pass that one item in an array but now we just pass that one item directly as the only parameter to the function and the only argument.
Jeff Terrell: Likewise, with multiple numbers basically we're just stripping off these brackets right it's not an array we're not passing a single argument to the function we're passing some arbitrary number of arguments to that function.
Jeff Terrell: So that's our change now why did that break and why did it break only the.
Jeff Terrell: end to end test, but not the.
Jeff Terrell: unit tests anybody know.
Jeff Terrell: yeah.
Jeff Terrell: The connection is broken yeah that's right yeah.
Jeff Terrell: So here's a graphic representing the problem.
Jeff Terrell: We have a unit test for me.
Jeff Terrell: And we have test coverage for that unit.
Jeff Terrell: We have the some function, and we have a unit test for some and so some is is covered with tests, however, mean calls some and that calling that invocation is not present in our test suite anymore, and that is where our bug is.
Jeff Terrell: That makes sense, this is really pretty cool our bug is hiding in between our unit tests.
Jeff Terrell: See because mean.
Jeff Terrell: mean is still passing the array to some.
Jeff Terrell: Right so it's calling it the wrong way we changed the interface of some.
Jeff Terrell: And we were smart enough to also change the tests for some, so that we used a new interface, but we forgot to change the interface of all of the colors of some in the actual code base.
Jeff Terrell: And because we had isolated unit tests for all of our units, we never tested that it was being called correctly.
Jeff Terrell: And so we lost that we introduced a bug.
Jeff Terrell: that's less than seven without integration tests of some sort bugs can hide.
Jeff Terrell: In the interrupted linkage between units that linkage that the mocks interrupt as exactly where a bug can hide.
Jeff Terrell: Now I will point out, this is going to be harder to do in some languages than others, so, for example, if we were using typescript.
Jeff Terrell: typescript would actually catch this the compiler which I catch it not the tests, really, but the compiler would.
Jeff Terrell: And this would not be a problem.
Jeff Terrell: And in the same way if I actually changed the name of the some function to let's say add.
Jeff Terrell: The code isn't going to compile whenever we try to load the mean.
Jeff Terrell: module node is going to tell us yeah it's trying to call this function some that doesn't exist, and so we would find out about that error in that case too, so.
Jeff Terrell: So there's only certain kinds of bugs that can hide in between the the linkage there in between the the mocked calls and depending on which language you use there might it might be harder and harder, maybe even impossible to have about of this kind.
Jeff Terrell: And i'm gonna go ahead and go to less than eight as well.
Jeff Terrell: Having some sort of an end to end test, or at least a maybe a small set of integration tests can be really useful to augment the unit tests.
Jeff Terrell: But if you remember the lecture from last time on testing you don't want to have everything be an end to end test, because not only does it take longer to run.
Jeff Terrell: But you have the combination common a tutorial explosion of different cases to consider if you've got one module that can vary in two ways another module that can vary in two ways two a's and two a's and two ways than your.
Jeff Terrell: end to end test is going to need to account for all the different combinations of ways to to to the fifth different combinations and so that just gets really impractical really fast.
Jeff Terrell: To test variation where it lives, like in a unit test, but maybe have a single end to end test just to make sure that everything is hooked up correctly.
Jeff Terrell: That would be my recommendation.
Jeff Terrell: Okay, so let's revert that last.
Jeff Terrell: break.
Jeff Terrell: In our test suite still passes.
Jeff Terrell: program seems to work now in our end to end test which again could just be another test case in test but.
Jeff Terrell: I separated it from just to make a point.
Jeff Terrell: Okay now let's see dependency injection okay.
Jeff Terrell: So.
Jeff Terrell: check the time good.
Jeff Terrell: Now we have this case where the client has come along and said hey I want to get an email anytime somebody computes standard deviation.
Jeff Terrell: which sounds pretty silly right but let's just say there's some kind of an effect that needs to happen and you don't want that effect to happen every time you run the tests So how do you account for that.
Jeff Terrell: What you can do is pass a send email function in to your standard deviation function.
Jeff Terrell: Okay, and if if it's not no, then I will call it and give it a to a subject of body.
Jeff Terrell: And that presumably will actually send the email but send innovation itself.
Jeff Terrell: it's just calling the function that it was given it's not actually sending email we presume that that would be the effects just based on what we've named things here.
Jeff Terrell: check out the test for standard deviation.
Jeff Terrell: We have this variable sent email that we initialize to know.
Jeff Terrell: And then we create a function fake send email.
Jeff Terrell: Which when given an argument assigns the argument to our local variable sent email.
Jeff Terrell: And then we call standard deviation and we give it that function that we created right.
Jeff Terrell: And after that we can make expectations on what sent the email should be.
Jeff Terrell: And we see on the right hand side that this actually does work and what's neat about this is that in our real code that's deployed out in the wild or whatever.
Jeff Terrell: yeah you can actually be sending those emails but in tests land you're actually because you get to pass in that dependency.
Jeff Terrell: The dependency in this case being the send email function, you get to pass that in, and so you can pass something different, and during testing that maybe you do during a real run.
Jeff Terrell: This is called dependency injection because you are injecting that dependency into the code I.
Jeff Terrell: injection is kind of a fancier word then maybe is needed, but that's what it's called an industry via we're just passing that dependency in as an argument, rather than having it be sort of hard coded to call that.
Jeff Terrell: That makes sense dependency injection it's very short coverage of a topic that some people spend a lot of time on in their code and I use it occasionally, it can be really a useful technique to know.
Jeff Terrell: Okay well that's dependency injection, this is another way to help your code be testable so i'm trying to give you different ways, like mocks and test doubles or one way dependency injection is another way, and these are ways of writing a test suite that is good.
Jeff Terrell: And this is something that I think many people at your stage don't know how to write a good test suite as something that becomes really important in industry.
Jeff Terrell: is writing tests for your code, I mean it's becoming more and more rare in my experience to find any serious company that you're going to be doing software development work for that doesn't care about tests, and so this is kind of a big deal when you get into a real job but.
Jeff Terrell: I would encourage you to be thinking about this in your project as well, and not consider your code done until you have tested it and refactor it.
Jeff Terrell: Right, so the lesson here is dependency injection can make effectual code easier to test.
Jeff Terrell: So that send email was an effective, you know in typically would actually send an email, but we don't want to do that in the test suite so we were able to control that effect with dependency injection.
Jeff Terrell: Alright, so there's our lessons learned from the testing DEMO tests notify you about broken code it's a very huge value proposition for tests.
Jeff Terrell: And then we got into some of the trade offs of integration tests versus unit tests integration tests provide good coverage for low efforts right we just wrote five lines of test code and we were able to cover a lot of.
Jeff Terrell: of implementation code, but implement integration tests can be difficult to debug.
Jeff Terrell: And if you're starting out on some feature or on some function in our class a really useful way to start, that is by writing listing all of the behaviors that that function or class or unit should have.
Jeff Terrell: With, for example, test to do in just.
Jeff Terrell: Number four with integration tests, a single bug in a dependency can cause multiple tests to fail so that test output can be pretty noisy but unit tests don't have that feature.
Jeff Terrell: test doubles make testing easier like stunt doubles for movies.
Jeff Terrell: marks are kinda testable and they let you interrupt dependencies and convert integration tests into unit tests.
Jeff Terrell: Even for code, even for units that depend on other things you can use mocks to interrupt that dependency and have a unit test.
Jeff Terrell: But if all you have are unit tests be aware that bugs can hide in between your units and that's where some kind of integration test, such as an end to end tasks which would be kind of the ultimate integration tests integrating all of your units.
Jeff Terrell: can be pretty useful to use to augment just the unit tests.
Jeff Terrell: But if you are going to do an end to end test just remember to test the variation where it lives in the units, not in the end to end test and finally dependency injection can make effectual code easier to test.
Jeff Terrell: Any questions about testing before we wrap up.
Jeff Terrell: Okay let's finish up with takeaway questions, and when you finish this you can go.