navigate site menu

Start learning with our library of video tutorials taught by experts. Get started

Foundations of Programming: Test-Driven Development

Foundations of Programming: Test-Driven Development

with Simon Allardice

 


Prove your code is working every step of the way using a formalized test-driven development (TDD) process. TDD can be done in every modern programming environment, and for desktop, mobile, or web apps. In this course, Simon Allardice teaches you exactly how to get started with TDD: what makes a good test, why we're more interested in failure than success, and how to measure and repeatedly run tests.

The course explores the jargon of TDD—test suites, test harness, mock and stub objects, and more—and covers how TDD is used in the most common programming languages and environments. Plus learn to create, run, and manage the tests and move to a test-first mindset.
Topics include:
  • What is test-driven development?
  • Using unit testing frameworks
  • Creating tests
  • Using assertions
  • Creating multiple test methods
  • Naming unit tests and test methods
  • Testing return values
  • Setting up and tearing down
  • Introducing mock objects
  • Measuring code coverage

show more

author
Simon Allardice
subject
Developer, Programming Foundations
level
Beginner
duration
1h 50m
released
Jun 11, 2013

Share this course

Ready to join? get started


Keep up with news, tips, and latest courses.

submit Course details submit clicked more info

Please wait...

Search the closed captioning text for this course by entering the keyword you’d like to search, or browse the closed captioning text by selecting the chapter name below and choosing the video title you’d like to review.



Introduction
Welcome
00:04 Hi. I'm Simon Allardice, and welcome to
00:06 foundations of programming, test driven development.
00:09 Now, this is programming, and you should never just hope that your code works properly.
00:14 You should be able to prove it, and prove it again and again, every step of the way.
00:18 From the very first lines of code you write, all the way through to deploying
00:21 an application. And the best way to prove it is with
00:25 automated tests. But this isn't the kind of testing you
00:27 only do at the end as part of a quality assurance state.
00:30 Test-driven development, or TDD for short, is a way of doing automated
00:35 testing that is built-in to your day-to-day routine.
00:38 It becomes an integral part of everything you do.
00:41 And in this course, we'll see how to get started with test driven development.
00:46 First, by clearing up some misconceptions about TDD versus other kinds of software testing.
00:52 We'll then explore the basic ideas and jargon of TDD, working with tests and
00:58 test fixtures and text suites, setting up and tearing down and mock objects.
01:03 We'll see what makes a good test. We'll then explore what software exists
01:08 to help you create, run and manage your tests.
01:11 And perhaps most importantly, see how to move to a test-first mindset, to take
01:16 your testing from being an afterthought into something that drives your everyday development.
01:21 So, let's get started.
01:22
Collapse this transcript
What you need to know
00:01 This is a course you should watch once you feel reasonably comfortable
00:04 developing in a general purpose object-oriented programming language.
00:08 Something like Java, C Sharp, Objective C, Python, and so on.
00:13 Because I expect at least at least object or development skills here to be able to
00:17 write and understand write methods, conditions, iterations.
00:23 I'm going to talk about being able to write and understand TDD so I can talk
00:26 about how to add TDD practices on top of it.
00:30 A question I sometimes get is, does test-driven development replace or
00:34 conflict with other things? I have been learning or hearing about
00:37 like object-oriented design or refactoring, or agile methodologies.
00:42 And no, test-driven development doesn't conflict with those at all.
00:45 In fact, it's entirely complementary. And many of what might be considered best
00:50 practice skills and techniques are professional enterprise developers.
00:54 Things like refactoring, Scrum, are often found hand-in-hand with using TDD.
01:00 So, how are we going to learn this? As with most of these foundations of
01:03 programming courses, I want you to find this one useful for many different languages.
01:08 But test-driven development isn't just some idea.
01:11 This isn't an academic ivory tower, theoretical thing you only do on a whiteboard.
01:17 This is an intensely practical, hands-on, in the code technique.
01:21 So, I will show it being used in a few different languages.
01:24 But regardless of language or environment, it is based on some core
01:28 ideas that really don't care which language you use.
01:31 So expect that when I can, I will teach this as generically as possible.
01:36 Often using either pseudocode or simple Java code.
01:39 But, we'll get more into that in a moment.
01:41 With that in mind, let's cover exactly what test-driven development is and clear
01:46 up some of the misconceptions and misunderstandings people have about it.
01:50
Collapse this transcript
1. Introduction to Test-Driven Development (TDD)
What kind of testing is this?
00:01 You may, right now, have the wrong idea about this course.
00:04 So understand this is not a course on how to test software in some kind of generic sense.
00:11 Because testing is a vague word in software development, there's lots of
00:15 different kinds of testing we could do. We need another word alongside it to make
00:19 it more specific. Some of the better known kinds of
00:21 software testing would be things like. Beta testing, providing a finished or
00:26 nearly finished application to a group of users, and seeing what problems they come
00:30 up with. There's performance testing using
00:33 profiling tools to measure if we're getting acceptable response times.
00:37 Is this application running as fast as it should be, or at least as fast as it
00:41 needs to be? This stress testing, one kind of
00:44 performance testing where we want to know how well the code works on the heavy
00:47 load, so this web application works fine with one person, what about a 100 or 1000
00:52 or 10,000 at the same time. There's other kinds of testing, we have
00:57 got integration testing, testing one app integrating with external other systems,
01:02 there's exemptions testing, there's regression testing, there's usability testing.
01:07 Well, this course isn't about any of these.
01:09 We're talking here only about unit testing.
01:14 Testing we do as programmers not as end users.
01:17 We are testing the code itself not just the results we might get from clicking
01:22 buttons on a user interface. So this is about us testing the
01:26 individual units of our code. The smallest logical piece as possible.
01:30 So we're proving that a single class works the way that class is suppossed to.
01:34 More than that, we're proving that individual methods work the way they should.
01:39 But if we pass in these particular values into that particular method, we will get
01:45 this specific result back. And we go ahead and prove that this is true.
01:49 But this is not the kind of testing where you act as an end user as a finished application.
01:55 I mean, we might do that. But that would be later.
01:58 Sometimes much later. We don't wait to have a finish
02:01 application, we are doing this right from the start.
02:04 We are testing a code as we write it. We might not have a user interface yet.
02:08 We may not have written most of our classes yet.
02:10 We are still testing our code so this course is about unit testing but more
02:16 than that its about having automated unit test because if you want to test down to
02:21 the level of the individual methods in our application you don't want to have to.
02:25 Manually type method cords into a command line window, and then check the results
02:29 against some massive book of tests. We don't want to do any of this manually
02:33 again and again, that would be completely painful.
02:37 So we will automate this, we will write code that tests our application code.
02:43 So we'll have our application code and saved right alongside it, and considered
02:47 just as important. Are simple, repeatable testing code.
02:51 Now that might sound like a huge amount of additional work.
02:54 It really isn't. As you'll see, writing tests is done very simply.
03:00 It requires minimal code, minimal logic to write a test and we'll have it so that
03:04 we can easily write these tests, save them, and then run them repeatedly at the
03:09 press of a button. We need it to be as easy to to run our
03:12 tests as it is to compile our code, or run our application.
03:17 And as we build our application we build our unit tests right along side it.
03:22 So we can run our unit test right along side it.
03:24 So we can run those tests ten 20 or 100 times a day.
03:26 Now among other benefits, having automated unit test allows us to easily
03:31 validate that any change we make at one place whether that's tomorrow or six
03:36 months down the line. We can verify that it doesn't break
03:38 something we did earlier or it makes life much easier when building application,
03:43 adding features, fixing bugs. So with test driven development we're not
03:47 beta testing, stress testing, acceptance testing, ability testing, we're unit
03:52 testing but, that is not all we are doing with test driven development there's one
03:57 more idea that we are missing and that's up next
04:00
Collapse this transcript
What is TDD?
00:01 The next couple of hours focuses on deeply on creating and using these
00:04 automated unit test. But this course isn't called foundations
00:08 of programming unit testing, it's Foundations of Programming Test-Driven Development.
00:13 And let me be very specific, doing unit testing is not the same thing as doing
00:18 test-driven development. You see, having these automated unit
00:22 tests, it's great, it's amazingly helpful, very worthwhile.
00:25 And we're going to do those unit tests, but to do TDD, we take that idea one step further.
00:31 So, what's the difference? Well, when most developers first
00:35 encounter this idea of automated unit tests of writing code that tests our
00:40 code, they understandably make the assumption that this is how the process goes.
00:44 First, we would write a bunch of our normal application logic.
00:48 And then, we would write our automated unit test to check and verify the logic
00:53 that we just wrote. So as an example, we might write a method
00:57 called calculate loan. We'll add some functionality to that,
01:00 compile that. And then after we've written, we'd think
01:04 about creating a few tests, what kind of values might I pass in and verify those
01:09 results is what we expect? And this is unit testing.
01:12 We are testing and validating an individual method down to the individual
01:17 unit in the code, but this is not test-driven development.
01:21 Understand that TDD has the same piece two elements a piece of application for
01:25 that logic but the test for that unit. It turns the process completely around.
01:30 What test developers asks of us as developers is to write the test first
01:36 before we write the application logic. That might sound counter-intuitive, if
01:41 not indeed impossible. But Simon, I hear you say, I can't
01:44 exactly test a method I haven't written yet.
01:46 Actually, you can, and in test-driven development, we do, and not just once or
01:52 twice, but all the time. We will write tests that attempt to
01:56 instantiate an object, where we haven't written a class for that object yet.
01:59 We will write tests that call a method that doesn't exist and we will run those tests.
02:04 And the first time we run those tests, they should fail depending on the
02:08 language, they may not even compile or they might run and then tell us, well, I
02:12 can't find this method, I can't find this class.
02:16 But we want the test to fail, because after all, if it doesn't fail, we have
02:20 some other kind of problem going on and this is the fundamental first step of
02:25 every day test-driven development. The core distinction between doing TDD
02:29 and not doing TDD. That before we write any new code, we
02:34 first write a failing test and only after it fails do we write the application
02:39 logic to pass that test. And we write the minimum necessary code
02:44 to just pass the test. One thing it immediately removes is the
02:48 common situation where we create a new class or a new method, and end up staring
02:53 at blank screen, trying to juggle in our heads all of the things this might need
02:57 to do today and tomorrow and in the future.
03:00 All of this speculative code that we're trying to come up with that is quicksand
03:04 for every developer. Now, just pass the test, this one test.
03:08 It keeps us focused, this gives us clarity on exactly what we're doing at
03:12 any one point. Don't do anything more than pass this
03:15 small test and this is what is meant by test-driven development.
03:20 The tests drive our development. So TDD is not just development that uses
03:26 unit tests. Test-driven development as a process and
03:29 technique is all about the priority and the position that we give to those unit tests.
03:34 Now, for all of who are looking for is to know more about automated unit testing,
03:38 you will find this course very helpful because that is what we're doing.
03:42 But just know that I will take a TDD approach to unit testing, shifting the
03:48 idea of testing as an afterthought, something that we only do later, to
03:53 putting the tests up front. Figure it out first, let it drive what
03:57 you write. I'm saying this multiple times, because
03:59 for most developers this is a very subtle change in priority that has a dramatic
04:05 impact on the way that you approach and write code.
04:08 So this course is focused on automated unit testing.
04:10 Having a systematic, repeatable process that is totally integrated into our
04:16 regular project and with TDD, what we'll use these unit tests to drive everything
04:22 else that we do.
04:22
Collapse this transcript
Common questions and concerns
00:01 I'm going to take a moment to deal with a couple of questions that you may already
00:04 have depending on your background. Because test room development is
00:08 something when I teach it's common to get initial push back.
00:11 If i have a group of very experienced developers encountering TDD for the first time.
00:16 I expect quite a lot of resistance because it does feel different to the way
00:20 they're used to working. It's like suddenly driving on the wrong
00:23 side of the road. You're doing all the same things, but
00:27 everything feels little unnatural. It feels alien.
00:30 So expect that. And want to avoid is taking that initial
00:34 weirdness as a reason to And validate any of this before you begin.
00:38 So do take care that you're not trying to come up with a this does not apply to me factor.
00:44 The, I don't really understand what it is yet, but I'm pretty sure test driven
00:47 development won't work for me, or for my project, or for my team or for my environment.
00:53 By all means, be critical. Bring your brain.
00:57 But do try this. I've never met a developer that hasn't
01:00 found it worthwhile to just take a few hours to work through these ideas.
01:03 And typically, the response that I get at the end, from even the most skeptical
01:07 upfront developer is okay, that wasn't what I thought it was going into it, and
01:13 yes I can see how this would be really useful.
01:16 But here's a handful of common questions and concerns I get upfront.
01:20 First, I have heard that test-driven development doesn't work for everything.
01:26 Well, that's absolutely true, there are certain problems in programming where
01:30 automated unit test are not the only thing you need to guarantee the code is perfect.
01:36 Some situations with multi-threading, security options testing user interfaces,
01:43 some parts of game development are well-suited and we will talk more about this.
01:47 But bear in mind, unit testing does not replace all other kinds of testing and
01:54 isn't intended to and even in places where unit testing may not apply to 100%
01:59 of your code. It may still be very worthwhile for 80 or
02:02 90% of them. And the next thing that people wonder is,
02:06 so am I supposed to write all my tests before writing any code?
02:10 No, not at all, let's get a sense of proportion here.
02:13 If you're thinking that this breaks down as January, write all your test, have a
02:19 big test fest and then in February start writing code that is way off.
02:24 It's not even Monday write a test, Tuesday write code to pass the test.
02:29 No, it's more like Monday at 9 a.m. Monday at 9 a.m.
02:35 and 20 seconds. See that test fail.
02:38 Monday 9 a.m. and 30 seconds, start writing code to
02:42 pass the test. Very small steps repeated often.
02:47 Creating tests isn't and should never be any kind of major road block, barrier or
02:52 even speed bump to writing code. It should be the tiniest amount of work.
02:57 You're just about to write a new method. You pause, take a few seconds.
03:01 You think, how would I call this method to prove that this is about to work, or
03:06 that it doesn't work? And you would write that test.
03:09 You would verify it fails, and you would then start writing code to pass the test.
03:14 Now, another question I will sometimes get is, we have a team of testers, so do
03:19 we use them To write these unit tests. Now, this used to be quite common in
03:24 large scale development. But these days, if you have the wonderful
03:27 luxury of having an independent team of testers or even just separate people on
03:32 your own team, well that's usually for a different kind of testing.
03:36 It's for a quality assurance stage or acceptance or integration with other
03:40 systems and this is not what we're talking about here.
03:43 We are talking runway level, day-to-day, minute-to-minute programming.
03:48 If you're writing code, you need to write your own unit test.
03:53 Using anybody else would impose a completely different drag on the system.
03:58 Sure, you would still use your testers but not on this.
04:02 But the most common resistance I get either, in person or online is really
04:09 just a misrepresentation. Its the all or nothing logical fallacy
04:13 that you will also hear when people talk about scrum or agile methodologies or
04:18 design patterns or any other software technique.
04:21 Oh, the TDD fanboys say this fixes everything and I know it doesn't so we're
04:26 not going to use it, which is kind of like saying, well, anesthetic doesn't fix
04:31 every problem in medicine so we're not going to use that either.
04:34 Well, it's true; it doesn't fix everything.
04:37 But it's very nice to have sometimes. But if it makes you happy, I guarantee,
04:42 test-driven development will not by itself fix every one of your software
04:46 development issues. I also promise that object orientation won't.
04:51 That design patents won't. That agile methodologies won't.
04:54 But I also guarantee that all of these skills are excellent to have.
04:58 They're great for your development ability, your competence, and your
05:01 confidence about what you're doing. They're great for your career.
05:04 There is simply no downside to knowing how to do test-driven development.
05:09 Alright, enough. Let's get into what we need to get
05:13 started with it.
05:14
Collapse this transcript
2. Getting Started
Using unit testing frameworks
00:00 When I said that a large part of what we're doing here is writing code that
00:04 tests our code, your brain may have even wandered off on a little tangent.
00:08 And thought about what that new code might look like.
00:11 And perhaps you thought, well if I'd written a new class and I wanted to test
00:14 it I guess I could create another new class call this one Tester.
00:18 In it I'll instantiate that new class I'd just written.
00:22 I'll call a method on that new object, I'd check the result and have a condition
00:26 that would. Fire off a message, either way.
00:28 You could do this. It is reasonably simple code.
00:31 But it would be very tedious code to have to write a lot of this, and we will not
00:36 have to do this. Instead, there are unit testing
00:40 frameworks we can use. Things like JUnit for Java, NUnit for .NET.
00:45 unittest for Python. These are libraries of code.
00:48 Already written, already proven that help us do automated unit testing.
00:52 Providing a lot of that basic plumbing. The duplicated structure we'd otherwise
00:56 have to write. Now, it would be easy to assume that if
00:59 you learned how to do this in Python and then had to go to Java, or to C++, or
01:04 Objective-C, you'd have to learn a whole new approach to testing.
01:07 But, luckily, that is not the case. And I can make this course work for
01:11 multiple languages. Because most of these testing frameworks
01:15 are based on the same ideas, the same common ancestor.
01:19 So, there are enormous similarities between unit testing in Python, unit
01:23 testing in Java, unit testing in .NET, and Objective-C and many more.
01:28 Why? Because history, that's why.
01:31 Back in the 90s, a gentleman by the name of Kent Beck developed a simple unit
01:35 testing framework now referred to as SUnit in the Smalltalk programming language.
01:40 And this provided a basic structure of a helping developers easily create and run
01:44 unit tests without duplicating a lot of this unnecessary code.
01:48 Now SUnit wasn't and isn't particularly complex or even large, but it formalized
01:53 some terms and concepts that have become part of the common unit testing
01:57 vocabulary we will explore. Things like Test fixtures and setup and teardown.
02:03 And this became very popular in the Smalltalk world and was converted from
02:07 Smalltalk into a version for Java called JUnit, which was and still is the most
02:13 popular and widespread unit testing framework.
02:16 It really took off as JUnit, so the same idea was converted for .NET, and
02:21 converted for Python, and for C++. And there's a version for Objective-C.
02:26 So, we have NUnit, PyUnit, CppUnit, OCUnit, and many more.
02:31 And these shared the same core ideas of how to create, run, and manage your
02:36 automated unit tests. And there are now dozens and dozens of
02:40 unit testing frameworks, in pretty much any language you could wish for.
02:44 And there's often several competing frameworks for the same language.
02:47 If I look at the Wikipedia page for the list of unit testing frameworks we'll
02:51 find entries for any language you're likely to need.
02:54 And often times multiple testing frameworks for the same language.
03:00 Now, if a unit testing framework is based on those original ideas from the
03:04 Smalltalk days, it is considered an xUnit testing framework.
03:08 xUnit is this generic term to collectively group these SUnit, JUnit,
03:12 OCUnit, CppUnit together, as coming from the same ideas.
03:17 And it is xUnit style of unit testing we'll be doing in this course.
03:22 Now, are all unit testing frameworks xUnit?
03:25 Well, no they are not. xUnit style frameworks are by far the
03:29 most common but there are some competing ideas.
03:31 So, if I go to this Wikipedia entry for unit testing frameworks and pick one of
03:35 the languages like C++, what I'll see is the several different entries.
03:39 But one of the columns here is basically asking, is this an xUnit style testing framework?
03:45 Most of the time. That is going to be yes.
03:48 Not all of the time, but most of the time.
03:50 Now I will not in this course be comparing any of the different per
03:55 language options. I will leave that as an exercise for the viewer.
03:58 But (UNKNOWN) to say you don't really have to worry about all the different
04:02 options for all the different languages. Because most languages have one typical
04:07 xUnit framework that is associated with it.
04:09 And I will use the most common one when doing any demos.
04:13 So, unit testing frameworks are there for just about every conceivable language and
04:17 environment although the culture. And community that evolves and exists
04:21 around different languages deeming that its uptake and usage can be quite different.
04:26 Unit testing is extremely common in the Java world.
04:30 If you're a Java developer looking for a job, the expectation that you would know
04:34 how to use JUnit is pretty high. And that's much higher, than say, an
04:39 average Objective-C developer being expected to know OCUnit.
04:43 An much of this is, simple history. JUnit was the first unit testing
04:47 framework, to take the Smalltalk ideas to a wide commercial audience, the first to
04:52 really popularize these. The first books on test driven
04:55 development were Java focused, and it really snowballed from there.
04:58 So, although the ideas originated in Smalltalk, most of the xUnit frameworks
05:04 are really based on JUnit and it's popularity, rather than the official
05:08 Smalltalk ancestor. It might sound like your first task is to
05:12 spend hours going through dozens of different options for the different
05:17 available languages. And identifying the unit testing library
05:21 that you're going to work with, but usually you won't have to.
05:24 Because if you were working with a general purpose programming language,
05:28 unit testing frameworks are probably already there.
05:30 They're baked into your language, or at least your IDE, making it very easy to
05:35 get started without downloading or installing anything.
05:39 As an example, if I have the standard eclipse IDE for doing Java.
05:44 And I don't have any kind of project created here.
05:46 I just jumped over to eclipse. What I'm going to find if I go to my File
05:50 option, is the option to create a new JUnit Test Case, so JUnit support is in
05:57 there already. If I'm on the PC side with visual studio,
06:00 with C# or VB.NET, I also have built in support for creating tests already there.
06:07 And even when doing Objective C development on the Apple side, which
06:10 doesn't have a huge culture of test driven development, the OC unit testing
06:15 framework has been baked into XCode since 2005.
06:19 I can just create a new project and one of the options that I'll find is to
06:22 include unit tests when I'm doing that, and I have full support for OC unit, unit test.
06:29 And unit test support is actually included with the standard library in
06:33 Python as it is with Ruby. But the only place you won't always find
06:37 it is with more informal casual languages, say scripting languages like
06:41 JavaScript, where the demand for unit testing is no where near as common.
06:45 And you wouldn't expect built in support for that.
06:48 In that case you might find surfing through this list of unit test frameworks
06:52 useful, so you can find an external unit testing library and download that yourself.
06:57
Collapse this transcript
Understanding assertions
00:01 Before I write my first line of testing code, I want to talk about the most basic
00:05 word in unit testing, one that we will use all the time and that word is assert.
00:10 To assert is to state something positively.
00:14 I assert that the earth moves around the sun.
00:17 I'm not asking a question. This is not an if.
00:22 I'm not inviting opinion. I'm not trying to change or alter
00:25 anything, I am simply stating something to be true.
00:28 Now, these assertions can be positive. I'm asserting something is true.
00:32 I assert there are only 30 days in April. Yeah, but assertions could also be
00:37 negatively, so I'm asserting something is not true.
00:40 I assert the book War and Peace was not written by Ernest Hemingway.
00:46 But I'm not presenting any of these as opinion.
00:48 I'm saying these are facts. Now, it is possible an assertion I make
00:52 could be wrong. But if my assertion is wrong, then there
00:56 is something fundamentally flawed with whatever I'm talking about.
01:00 So we take this idea over to programming. We can make assertions at any point in
01:04 our code. At this point in my code, I assert these
01:08 two strings are equal. At this point in my code, I assert this
01:12 integer is positive. At this point in my code, I assert this
01:15 object is not null. I'm not asking questions.
01:19 These are not if statements. I'm not inviting opinion.
01:22 I'm not trying to change any of these things.
01:24 I'm simply stating something to be true. Now, an assertion is sometimes referred
01:29 to as a sanity check in code. It is a simple way for us to stick a flag
01:34 in the ground to explicitly state that we have a fundamental assumption about what
01:38 is true in our code at a particular line. You might think, well, aren't I doing
01:43 this already? I mean, I check a lot of things in my
01:45 code with if statements and switch statements, but we are not talking about
01:50 the general flow of a program. And we're not even talking about graceful
01:54 error handling or exception handling. You still do those things.
01:58 But assertions are different. If an assertion fails, then your code is
02:03 broken, or your assumptions about what is going on, they're fundamentally flawed.
02:06 Something is wrong in your development and you need to fix it now.
02:10 You need to find out why that thing you're asserted is not true.
02:14 So an assertion failing is not an issue to be gracefully and programmatically
02:19 handled in your code. It is a reason for your program to error
02:23 immediately on that line. And we want to fail as soon as possible.
02:27 There is no point in going forward. Because, if we continue on but our
02:31 earlier logic is flawed, our code isn't correct, we may have really bad side
02:36 effects, but only feel the impact of those much much later and have to retrace
02:40 our steps through multiple methods and classes, so the sooner we find and fix
02:44 it, the better. So you don't use assertions to
02:47 programmatically manage a complex situation you might do with exceptions or
02:53 air handling. And you don't use assertions to generate
02:57 helpful diagnostic dialogue boxes for the end user.
03:00 Because assertions aren't for the engineers here, this is code that is only
03:05 for us as programmers. In almost all languages, if you've
03:09 written an assertion in your application's source code, they are
03:12 stripped out of production code, using a compiler directive or even just check box
03:17 in your IDE. So those assertions will be ignored in
03:20 any shipping code, because an end user should never see the effect of an
03:24 assertion in code. There's only two possible options for an assertion.
03:29 If what you assert is true, nothing happens.
03:32 No messages are generated. It's what we expected, it's business as usual.
03:36 We just keep going on to the next segment But if what you had said is false,
03:40 there's a fundamental problem in the code.
03:42 Shut everything down. Fail, and fail immediately.
03:46 So how do we actually do this in a language?
03:48 Well, let's see that next.
03:49
Collapse this transcript
Using assertions in programming
00:00 Many languages have the assert keyword built directly into the language itself
00:05 or the foundational framework of that language without even needing an external
00:09 unit testing framework or library. For example in Java or at least in
00:13 version 1.4 of the language alment we have he assert keyword.
00:16 Anywhere in a regular message you can just use the assert keyword and give it
00:22 an expression so something like Assert x greater than 10.
00:25 That's it. This doesn't need anything else.
00:28 We execute this line just like this. If the variable x is greater than 10, we
00:33 will continue to the next line. If it's false, this immediately throws an error.
00:37 Now, we're not trying to run this assert and then follow it with an if statement
00:42 to check the result of doing the assert, we simply assert something.
00:46 And only if the assert fails will we notice any impact.
00:50 Likewise we don't then try to handle this, we don't add code to attempt to
00:54 gracefully react to this situation as we might do with exception handling and
00:58 having multiple (UNKNOWN) finally blocks, it's really just this little assert
01:03 statement, self contained by itself wherever we need it...
01:07 There's a couple of other things we can do with the assert key word syntax and
01:10 java but it's not necessary to get into language specifics just yet.
01:15 So let me show an equivalent in, say, objective C.
01:19 Here it's the N S assert key word this is because many things in objective C come
01:23 from the old next step days. And we have this format.
01:27 NSAssert, then the expression, the condition that we're checking.
01:31 And optionally we can add a string that will show up as a log message if this
01:36 assertion fails it would look something like this.
01:38 We are asserting that x is greater than 10.
01:41 If this assertion fails, we'll output a log message with an error saying x is not
01:46 more than 10. And other languages have a similar keyword.
01:51 So is this what we're doing in this course?
01:53 Well, no, certainly not just this. You could include this kind of simple
01:58 code, just an assertion statement here and there, directly in your application
02:02 logic in your own classes, your own methods, as a sanity check to cause an
02:06 immediate error when testing and debugging.
02:09 And there is some value to that. But I wouldn't dignify a simple, assert
02:14 statement with the term unit test. It's really just a one-line sanity check.
02:18 because what we're doing in this course is not just adding an assert here and
02:22 there, directly in our normal application code.
02:25 We will be creating entirely new test classes, entirely separate unit tests.
02:31 Now we're still going to be doing a search.
02:33 But because we'll be using unit testing frameworks you will find most of them
02:37 provide multiple additional assert methods to make it easier to read when
02:42 we're asserting something to be true or to be false or to be equal.
02:46 So in Java as an example, with the JUnit framework, rather than the kind of basic
02:51 Assert keyword built directly into the language.
02:53 When we're using this framework you might see lines like Assert equals, so that
02:57 takes two arguments, two parameters so as an example if we said assert equals 1,1
03:03 this would pass do nothing. If we said 1,2 that assertion is false we
03:08 would fail, we would immediately throw an error.
03:10 So you were just passing whatever two objects, two variables you are assuming
03:15 to be equal. And there are even some specialized
03:18 methods for checking equality, like assertArrayEquals.
03:21 And this could take two object arrays, two integer arrays, whatever you have.
03:25 But we have other assert methods. We have things like assertNotNull.
03:30 We are saying this object is not null. If the object is Null, this would throw
03:35 an error. The flip side of that, you might be
03:37 asserting that something is Null. Also, as you know, when comparing
03:41 objects, there's a big difference between having two objects that are equal in
03:45 value and having two separate references to the same object.
03:50 So in JUnit, if we wanted to check that two object references are actually the
03:55 same underlying object, we have a special assert: assertSame.
03:59 And its flip side assetNotSame, which would be different from asserting them to
04:04 be equal to each other. And more generally we have things like
04:07 assertTrue with a condition or assertFalse with a condition.
04:11 Now all of these assert methods are void, they don't return a value you just call
04:16 them directly. Passing in whatever parameters or
04:19 conditions that you want to assert. They either pass and continue onto the
04:23 next statement or they fail and throw an arrow.
04:26 And you're not supposed to gracefully handle that arrow.
04:28 You're supposed to understand it and fix it.
04:31 Now there are a few other assert methods and there are versions where you can add
04:35 your own descriptive strings. To provide a useful message if an
04:38 assertion fails but this will do as an example for now.
04:42 I'm not trying to get you to remember all of these methods, I'm just showing one of
04:47 the benefits of using a unit testing framework.
04:50 So while that example was in Java, expect exactly the same thing.
04:54 Using a unit testing framework in other languages as well.
04:56 And the reason I show these right now and talk about assertions early on is to keep
05:02 in mind that while we'll cover a few different ideas and techniques, the end
05:06 goal of a unit test is to support us making some kind of assertion.
05:10 That if we create this object and then call this method passing in these values,
05:15 we then assert a result. And because whatever I insert I assume to
05:20 be true. Successful assertions, successful tests
05:24 simply continue. We don't need to report them, we don't
05:27 need to log every successful test we are taking success as assumed.
05:32 The only ones we want to bring our to attention to of the assertions the fail.
05:36 But these are unit testing frame works will do more than just help us make
05:40 assertions even specialized one. They'll also help us do the initial set
05:44 up if we need to create new objects or use sample data in our tests.
05:49 They help us do sample data in our tests. They help us string multiple tests
05:53 together so we could run multiple tests at the same time.
05:56 But running lots of tests comes a little later.
05:58 We need to start to see what one particular test would look like.
06:02
Collapse this transcript
Creating a test
00:00 I'll talk later about how you might add unit tests to an existing code base, but
00:04 I'm going to start first from a completely blank slate with a TDD test
00:09 first mindset, to write a test before I write any application code.
00:13 So I'm beginning with nothing. No code written at all.
00:17 And let's say what I have in mind is to make a very simple banking application.
00:21 Okay, I get it. That's a little conventional.
00:24 It's a little dull. But I'm not looking to make a cool
00:27 project here. I'm looking for clarity on these ideas.
00:30 I'm with a bank account. We have concepts everybody understands.
00:33 Like balances, withdrawals, deposits, and so on.
00:37 And you might have do a little bit of up front object oriented design.
00:41 Sketch some things on a white border. Even have A UML diagram or some use cases
00:46 and user stories. And that would be fantastic because those
00:49 would make it much easier to come up with your tests.
00:52 But let us begin by imagining the simplest bank account class in the world.
00:58 And even a very straightforward UML version of this so it's just a field to
01:02 hold balance, there's a deposit method, there's a withdrawal method, and yes I
01:07 know we would have more detail, we would have more properties and methods and i
01:11 know you could take this and bring up your code editor and just write this
01:16 class right now, probably one handed... But before doing that, before actually
01:20 creating this class let's quickly think about what a simple test for this might be.
01:26 So what I'm going to do is just switch to a very simple text editor, just so I can
01:31 write a couple of things down. Think about, well how would we prove what
01:34 we're about to do works. We'd create a new bank account object.
01:41 We then call the deposit method passing in, let's say 50.
01:47 And check the balance is 50. Then we withdraw 30.
01:51 Check the balance is 20. So our test is not just can we call the
01:57 deposit method, can we call the withdraw method.
01:59 It's Did that call work after we call the deposit method passing n 50, is the
02:04 balance 50? After we call withdraw passing n 30, is
02:07 the balance now 20? I'm doing here just a little bit of
02:10 thought, just taking a few seconds before I begin.
02:13 And, no, you don't need to write these always down in kind of pseudo-code plain
02:17 English in A note pad or a text edit, editor, it's just to kind of demo our
02:22 thought process here. Although, depending on how much design
02:25 we've done, or even how much I've either thought or not thought about the business
02:29 problem I'm attempting to solve. It's likely I'll write down a few notes
02:33 to myself as I'm doing this. Now sometimes they might be technical concerns.
02:39 They might be things like, what's the best data type I should be storing values in?
02:44 What's the best way to create a unique ID?
02:46 Sometimes they might be related to the business problem, so is there a
02:49 limitation on the maximum amount I can deposit at any one time?
02:53 Do I need to speak to somebody about that?
02:55 I'm just trying to write this down, so I can come back to them later.
02:57 But I am trying to stay focused on this first task, creating a new object and
03:03 making sure this deposit method works. So let's do this.
03:06 Let's do some test driven development. Write an actual failing test and then
03:10 pass the test.
03:11
Collapse this transcript
Creating a test in Eclipse
00:00 I'm going to do a test driven development cycle in Eclipse here using Java as the
00:04 language with Junit as the library but again I will be as generic as I can.
00:08 The language and the IDE is not the focus here.
00:11 So, even if you are a Java and Eclipse person focus less on the syntax and
00:15 specific menu items and just more on the overall approach.
00:19 So, I have no code at all. I have an empty project here and I know I
00:24 want to make that simple bank account class I described a moment ago.
00:28 So this is test driven development. We begin not by adding that class, but by
00:32 first adding a unit test. So I'm creating a JUnit test case here,
00:38 and I get this dialog box. Now this is a place I can often hear that resistance.
00:42 Well, how am I supposed to create a meaningful unit test?
00:45 Or even know what to name it, which is what it's asking for right now, when I
00:49 have nothing to test? Well, it is true that we have no code.
00:53 But I do have an intention, and we always have an intention when creating our test.
00:58 I know that I want to make a bank account class.
01:00 That's what I'm about to do. That's the reason I'm in this environment.
01:04 So I will name this one accordingly. It's asking me for a name here.
01:07 I'm going to call this BankAccountTest. I will talk about naming tests in a
01:13 moment, as well as some of these other options.
01:15 But I'm just going to go ahead and click Finish.
01:18 Eclipse is just popping up a dialog box making sure that I can add any necessary
01:22 libraries, that's fine. Assume the equivalent in other languages.
01:27 So it's created this file, BankAccount Test.
01:29 And it is its own independent class. And eclipse has provided me with a bit of
01:34 default code, this one method here. Now I could actually go ahead and run
01:39 this class right now, if I right click it over here, I could choose to run as Junit test.
01:45 It runs, and we have officially what's a failure, this red bar here, and I'll come
01:50 back to that in a moment. because what's happening is if I want to
01:53 run this as a unit test, it's going to look inside this class and run any method
01:57 that has this at sign Test annotation. Other languages have their own
02:02 equivalent, a little marker that we can add to a method to say, hey this is a
02:06 unit test. So, I'm going to jump in here and take
02:10 this bit of provided skeleton code, this failure here, and just add my own test.
02:15 I know that what I want to do is create a new instance of this new BankAccount class.
02:24 I want to then call the deposit method and check whether that worked.
02:32 Now even as I'm typing I can see that I'm getting several detected errors and
02:36 Eclipse can see, well there is no BankAccount class.
02:39 We're not even able to compile. Eclipse, like many development
02:43 environments does have some options where it can help us generate some of this code.
02:47 If I mouse over this I've got options to create the class, bank account, and I'm
02:52 going to go ahead and let it do that because right now we couldn't go ahead
02:55 and run. Create class bank account I am just
02:59 going to go ahead and accept all the default options for right now I am trying
03:01 to stay simple as possible. So we have this now bank account class
03:05 absolutely fine jump back over to the test I will not getting any complaints on
03:09 that first line but I am getting complaints on the second because it's
03:13 detecting that there is no deposit method in the bank account class.
03:17 We do have another quick fix available. So for purposes of time, I'll select that.
03:23 It's gone ahead and added a public void deposit method here that takes a
03:27 parameter of one integer. I'm going to leave it as that for right now.
03:32 Jump back over to my test code and it's finally complaining about this last line here.
03:37 What I want to do is the assert. I'm using the assert equals method in
03:41 Junit which takes two parameters the two things you're trying to compare.
03:45 And I want to compare the balance in the account object with the explicit value
03:49 fifty.Again it's giving me an option to do a field here.
03:53 I could just manually type it myself. I am intentionally adding the simplest
04:02 thing that could possibly work. In my final code, would balance of a bank
04:06 account class be a public integer? Well, almost certainly not, but I'm not
04:10 worrying about that right now, I'm just trying to get this test to run.
04:14 Well, I'm not getting any complaints any more about it, so the code seems
04:19 syntactically correct, so I'm going to go ahead and run it.
04:23 Over here I have my Junit window, and I'm actually going to drag this to the lower
04:27 section so I can see my code when I have them there.
04:30 I'm going to right click my Bank Account test, and just say, run as J-unit test
04:37 Save and launch, the test fails. My first real failing unit test and in
04:43 Eclipse with Junit I'll see this bar down here, the red bar.
04:46 Not all IDE's and unit testing frameworks have GUI support to show you a red bar
04:52 when your test fails. Sometimes you just have log messages, you
04:55 have 17 succeeded one failed but it is quite common.
04:59 The idea of a red bar for failing tests. A green bar for successful tests.
05:04 And sometimes you'll hear the three word phrase red green refactor as a quick
05:10 summary of the test-driven development cycle.
05:12 Red, make your test fail. Green, make your test pass.
05:16 Refactor, make the code right. And then just rinse and repeat this.
05:20 But where red, the test runs, but it fails.
05:23 Why is the assertion failing? And that's what is failing here.
05:26 Well it's because my deposit stub may actually exist.
05:31 I can call it, but it doesn't do anything.
05:33 I didn't add any functionality. Deposit being passed in with an integer
05:37 really what I need to do is add that to the balance.
05:43 I'll save that. I want to run this again.
05:45 I could right click the bank account test class, or I could use the Menu option
05:50 here and select to run this as a Junit test.
05:54 It runs again. Now we have the green bar.
05:56 We have passed the first test. Now here's the thing, if I had not been
06:00 talking and talking this would've taken me what?
06:03 About 30 seconds if that and this is an example of how fast you would expect to
06:08 work in test driven development.
06:10
Collapse this transcript
3. Working with Tests
The process of TDD revisited
00:00 There's several ways the basic idea of test driven development can be described.
00:04 We have this phrase red green re-factor as a quick summary of the TDD process.
00:11 Red, make a test that fails. Green, make that test pass.
00:16 And then re-factor. Make it right.
00:18 And this isn't done once. This is a cycle.
00:21 We repeat that throughout the lifetime of our project.
00:24 We're taking a different approach. I could even perhaps say that test room
00:28 development has two simple steps. Step one, before you write any new code,
00:33 you first write a failing test. And step two, pass the test then go back
00:37 to step one and keep repeating this. This is technically accurate, this is TDD
00:43 but that's too simplistic, it doesn't really give us any guidance.
00:46 I could break this apart a little bit and say instead that test-driven development
00:50 has six steps. Step one, we write a test.
00:54 Step two, we watch that test fail. We go red bar.
00:57 Step three, we will quickly write an application code to pass the test.
01:01 And we're talking here about the simplest thing that could possibly work.
01:05 Step four, pass the test. Go green.
01:08 Now step five, importantly we now refactor it.
01:11 We knock that code into shape. Particularly this idea of removing duplication.
01:16 That sounds like a throwaway phrase here but it's really quite important.
01:19 I will talk a lot about what removing duplication means in the context of
01:24 jumping between test code and application code.
01:28 And then after we've refactored, we want to make sure we keep at a green bar, we
01:32 pass that test again. But whether I want to use two steps or
01:37 six steps or I'm sure I could come up with the ten rules of test-driven
01:42 development or the five phase of TDD however I wanted to do it.
01:45 As the test-driven development is a simple idea.
01:48 Test then code. A very small test then a small amount of code.
01:52 And repeat that hundreds or thousands of times throughout a project.
01:57 And notice both with the demo that I did a moment ago and as we go forward this
02:01 one thing, how quickly and continuously we shift from writing test code and to
02:07 writing application code and back again. This is not as some people initially fear.
02:11 We create a massive test project. We work just on that for a while.
02:16 And then we close that all down. We switch everything over to regular code.
02:20 We boot that up. We work on that for a while.
02:22 Close that all down. Switch back over to the test.
02:25 Run the test. No.
02:26 This is instant. In test-driven development we do start on
02:30 the test first but we're often over to the application code in seconds.
02:34 And then you start flipping almost continuously back and forth between the
02:38 task code and the application code. This is and must be very lightweight to
02:43 switch between them or you just won't do it.
02:45 But it's applying this idea. Okay, that's what test driven development
02:49 is, red, green re-factor and then repeat that.
02:53 But how do we do it? That's the issue now.
02:55 So what makes a good test, how many tests should I have, how do I know when I have
03:00 enough, how much code do I need to pass the test successfully.
03:04 What do I do when the situation changes. What parts of my code are tested like
03:10 this and parts aren't. What do I do with my test when I'm done?
03:14 And it's these questions and quite a few others that we'll be getting into in the
03:18 rest of the course. A lot of the subtle impacts and changes
03:21 that come from that simple shift in priority of how we approach development.
03:25
Collapse this transcript
Adding tests and removing duplication
00:00 So let's keep going. Test driven development is and should be
00:03 always about very quick cycles, so I know that this current test works where we're
00:08 depositing and checking. I'm going green bar, if I look at the
00:11 notes that I had we have the next task which is withdrawing.
00:14 So making sure that I am in my test code here...
00:18 I'll add a line to call the withdraw method and then do another assert.
00:23 Not surprisingly we're getting a complaint here that is detecting there is
00:31 no withdraw method. If I mass over I have got the quick fix
00:34 to create the method in my bank account class I will do that.
00:39 I'll leave that as is. Which means it's got no actual implementation.
00:43 Just save that and run this test again. Excellent we've gone red bar, we've failed.
00:51 We need to go green. So over in my test, what I'm asserting is
00:54 that after we have withdrawn 30. We're then going to check the balance for
00:59 being equal to 20. So if I flip over to the actual class
01:02 itself, well I'm going to intentionally write some terrible code here.
01:06 Because here's the quickest possible way I could make this work.
01:10 Just set balance to 20 go ahead and run this test again.
01:16 Now we go green bar. So we've gone red.
01:19 We've made it fair. We've gone green, we've made it past.
01:21 Now it's re-factored, we make it right. And particularly removing duplication.
01:27 See some of our code already smells. Things like using a public integer for
01:31 the balance. But this particular line stinks to high
01:35 heaven in our actual bank account class because now we're always going to set the
01:39 balance to 20. So, here's what we mean by removing duplication.
01:43 Usually, when we talk about code duplication, we're talking about blocks
01:46 of code being duplicated within class. Now, we should notice those anyway.
01:51 But in test driven development, the extra thing to be attentive of is duplication
01:55 of code, or particularly of data, between our application code and our test code.
02:02 Now, here's the thing: we have this little piece of literal data being
02:06 written here, the number 20 that exists both in the test code and in the
02:09 application code. Of course, this withdrawal method should
02:12 not be setting to this fixed value. It should just be subtracting it from
02:17 whatever the parameter in this is being passed in.
02:20 Now while this is obviously a really simple example and you're very unlikely
02:25 to have written this kind of level of really bad code.
02:28 It's the habit of starting to notice any kind of duplication between your test and
02:34 your code that's an essential habit to get into.
02:36 Particularly if you are talking about things like literal values.
02:41 Now as we're doing this, it is very common to see things that we want to take
02:44 note of, but we're trying to stay focused on one test at a time.
02:48 So I'm trying to make my withdrawal method works right now.
02:51 But let's say this public integer balance is really bugging me, well, what I would
02:55 probably just do is add that as a note to myself in my little list here.
03:03 And you do want to have some kind of to do list, some way of persisting these.
03:07 Whether that's a causal text file or a formalized (INAUDIBLE) list of tasks or
03:12 even just scribbled things on a post it, test driven development doesn't dictate this.
03:16 You need some way to persist open issues, and you want to be able to do this quickly.
03:20 I don't want to have to create a new online bug case or bug report for every
03:25 single thing that comes to mind. I just need to be able to scribble them
03:28 down so I can come back to them. Some of these I'll be able to fix myself.
03:32 Some maybe a prompt for discussion with other team members.
03:35 So, jump back over here. So let's try running this test again.
03:39 It's still telling me I'm not always saving.
03:41 Let me just check that check box so we always save before launching.
03:45 And we've gone green bar. So red green re factor.
03:48 So flipping very quickly between the test code and the application code.
03:53 Saving it running it just repeatedly in a matter of seconds.
03:57 And being conscious of anything that comes to mind and starting to write that
04:00 stuff down. We're not trying to avoid having any issues.
04:04 The idea is that TDD will help us ask and then answer a lot of these design
04:08 questions as we're working our way through them.
04:11
Collapse this transcript
Testing privacy
00:00 So in my simple text-based to-do list here, I really need to start organizing
00:04 it a little bit to make sure that I can keep track of which things have actually
00:08 been done and which things are still to-do.
00:11 because the process of moving from one state to the other is going to be
00:15 actually pretty quick. So, I have this note here that balance
00:18 should be private, now I could argue this is not really adding any new
00:22 functionality, it's just a re-factoring, an improvement to the existing code.
00:27 So I'm going to jump over to my bank account class here, where I've got public
00:31 int balance. Just double checking that all my tests
00:34 are running as little JUnit tests. Yeah, we've got green bar.
00:38 So go ahead, make a change to the code. Change this to private.
00:42 Save that. Run the test again and we've got errors.
00:47 I don't even get as far as running that test.
00:50 If I jump over into the test code what I can see is the two places where I'm
00:54 trying to directly access the balance field are not letting me do this anymore.
00:59 Now this is a good thing, this is good object oriented practise to make as many
01:04 things private in your class as possible. So how we deal with it, and this is one
01:08 of those areas that's going to differ a little bit based on language.
01:11 But the idea is, I want this balance to be readable from outside of this class
01:15 but not directly changeable from outside of the class.
01:19 So I'll keep this field as private, and just add a simple getter method to get
01:24 that value. I'm not going to create a setter because
01:31 I don't want anything to be able to directly change this balance field
01:34 without going through either the deposit or withdrawal methods, or any other
01:38 method that I create later on. So, jump back over to the test.
01:42 We'll just change these, and there are often quicker ways with fixits to clean
01:49 this up, but I wanted to make sure I only had a getter and not a setter.
01:52 Save that. Go ahead and run this.
01:56 We got green bar, we're good. Again, a very simple example.
02:00 But the idea of how, a quick change to our code to improve it, the benefit of
02:05 having these unit tests is I can easily see if there's, some kind of other impact
02:09 that I wasn't immediately envisioning. So just having these tests, being able to
02:13 run them all the time, very, very useful.
02:15
Collapse this transcript
Creating multiple test methods
00:00 I'm looking at my unit test code. And right now, my test is this one method
00:04 just called test, which is testing two methods in my bank account class.
00:08 The deposit method and the withdrawal method within a CERT for each one.
00:11 And while this is a simple and easy enough test to read, it is more common to
00:16 create separate methods in the unit test code, testing the separate methods in the
00:20 application code. So I'm going to split this up into one
00:23 test for deposit. And a different test for withdraw.
00:25 Because we really want our test to be small, self-contained, simple, easy to
00:30 read, easy to change. And if I get into the habit of mixing
00:33 multiple tests together for multiple methods in my application code.
00:37 Then soon they really won't be. Now for purposes of time, I'm just going
00:41 to copy this entire method signature and duplicate it.
00:45 Using JUnit in Java, we have this at sign test annotation, which is what is telling
00:50 JUnit this is a test, go ahead and run this method.
00:53 I still can't have two methods with exactly the same name.
00:56 I'll call this one test withdraw and the first one test deposit.
01:01 It is not essential to have the word test at the start and we'll talk a little bit
01:06 more about naming in the next video. So I'm going to pull the withdraw out of
01:10 the test deposit version so it's just limited to that one.
01:14 And then in withdraw, what I'd actually like to do is create an object, a new
01:19 bank account object, and start it off with a balance of 75.
01:22 Then, I want to withdraw 50 from it and assert that the result is going to be 25.
01:29 Now, this exposes one issue here that i can't create a bank account class within
01:34 an immediate open balance. I don't have the ability to try and put
01:38 in say 75 in here when I'm instantiating it.
01:41 It's immediately going to complain. Well, I'd like to be able to do that, so
01:45 I'm going to go ahead, hover over this. Eclipse will give me the option to create
01:49 a constructor. I could obviously just type that myself,
01:53 it's pretty easy code. And in this constructor, which it's
01:56 jumped me over to the bank account class, I'm simply going to use it to set balance
02:00 to whatever was just passed in. So, let's jump back over into the test code.
02:06 We started off with 75, we withdraw 50, 25, looks good.
02:09 But if I go ahead and run this, I have problems.
02:13 Because the fact in Java that I've created a new constructor that takes an
02:16 integer, means that the default constructor I was using in the previous
02:21 test, is no longer going to work. Not a useful thing for having tasks.
02:25 So, I will let Eclipse give me the quick fix for this, to create the empty
02:30 constructor, and in that in the code, I'll just explicitly set balance to zero.
02:35 (SOUND) Back and run our test again, we have green bar.
02:40 So the basic withdrawal does seem to work.
02:43 And we've got two separate methods here. So you may wonder, is it meant to be a
02:49 one-on-one relationship between one method In our test code and one method in
02:54 our application code. Well, that is a start, but no.
02:58 As soon as you start building methods with a little more to them, with more
03:02 logic in your application, with conditions and switch statements and
03:05 multiple paths, well, what is much more common is that each method in your
03:09 application code, your regular code, may have several test methods associated with it.
03:15 Each test focusing purely on one significant path, one significant option,
03:20 that your code might execute. Well, let's go through an example.
03:25 So if I jump over to my to-do list that I was messing around with, I did have this
03:28 note to myself. What about negative amounts?
03:31 So let's say I talk with my colleagues and we decide quite generously that we're
03:35 going to allow our bank accounts to be overdrawn.
03:38 But we will add a $5 penalty every time we make a withdrawal and the balance is negative.
03:44 And yes, this is intentionally simple. We're focusing here on how we would test
03:49 additional behavior that we're adding to the system.
03:51 Well we are test driven development, so it's test first.
03:54 I'm going to add a new test method. So we will have two methods.
03:58 That are going to be testing different parts of this withdraw method in our
04:02 actual application code. Again we can't call on the same name so I
04:06 have testWithdraw and I also have testWithdrawWithPenalty.
04:10 And again I will talk again about naming in the next movie.
04:13 With this one, I'm going to create a new class, I'd like to start the class off
04:17 with a balance of 10. Then I am going to withdraw 20 from it.
04:22 That should take us to minus 10, negative 10.
04:25 But if we are successfully subtracting another five for the penalty I should be
04:30 able to assert that the result is negative 15.
04:33 This code looks okay. It should be compiling correctly, we'll
04:36 go ahead and run this unit test. We've got red bar, so we need to go red,
04:42 green, kind of the expected failure here. That it should have given us a penalty,
04:46 but I haven't added that yet. So, jump over into the application code,
04:50 find the withdraw method, that's where I'm subtracting from balance, and I'm
04:55 going to say, if the result is negative, we are going to subtract a further five.
05:04 Run the test again, and we go from red bar to green bar.
05:10 And this test class now has three separate tests then.
05:13 Testing deposit once, testing withdraw twice with vector behavior.
05:17 So, that starts getting us into the question, how many tests do we need to write?
05:22 And the answer is, how many do you need so you can relax and be confident that
05:26 your code works. With deposit, for example, I don't need
05:29 to have multiple tests here, to first verify I can add 50.
05:33 And then another test to verify I can add 51, and then another test to say I can
05:37 add 55, because if this one works, we're good with the basic behavior of this
05:42 deposit method. But I needed to for withdrawal, because
05:45 we have a major condition that needs tested.
05:48 And that is the intention here. Every significant path that is in your
05:52 application, whether that's an if else, or switch, or usage of polymorphism or a
05:58 loop that may run in one situation but not in another, well, they should all
06:02 have different tests. A question might be, in more complex
06:06 code, how would you know that you've done enough, when it's not so easy to just
06:09 recognize you have tested every significant path that's in your code.
06:14 And there are tools available that can measure your unit test against the
06:18 detectable paths through your code. This is known as code coverage and I will
06:22 come back to that later. But as for first getting into this.
06:25 A better rule of thumb is a phrase that you will sometimes hear in regard to test
06:30 driven development. And that phrase is test until fear turns
06:34 to boredom. Whether you wnat to call it fear or
06:36 tentativeness or concern. We are writing complicated structures in
06:40 code and we realize we are not infallible.
06:43 We all have the best of intentions. But sometimes what we write does not do
06:47 exactly what we intended it to do. So add another test.
06:50 And we're never just trying to duplicate existing tests.
06:53 We're trying to simply make sure every significant path is being tested at least once.
06:58 That we have in short written all the tests we wish we had.
07:04 Now, an important idea here. I have three methods in this testing code
07:09 and it is important that these methods should be considered independent of each other.
07:13 Let me say that again. Your test methods should be considered
07:17 independent of each other. These should be able to run in a random
07:21 order, doesn't matter whether testDeposit runs before or after testWithdraw or testWithdrawWithPenalty.
07:28 No test method has dependencies on another test method.
07:32 They should be self contained, isolated from each other.
07:34 Because if we have an assertion failure, we need to be able to look directly at
07:39 that test; not trying to figure out if the, order of the 3, or the 27, or the
07:44 500 tests that ran before it, had any impact.
07:47 It shouldn't matter. So if I add a new test or if I later
07:51 delete a test because it's not needed any more, there is no impact on the others.
07:55 But one thing we haven't talked about is naming these well.
07:58 So let's do that next.
08:00
Collapse this transcript
Naming unit tests and test methods
00:00 If you've been in programming for more than about, oh, 5 minutes, you'll know
00:04 that naming conventions can become almost a religious issue.
00:07 But, with unit testing, there's a bit more importance to it than just personal
00:12 or team or even company preference. Because depending on the language, the
00:16 names that you use can make the difference as to whether your test even runs.
00:20 I'm going to show simple examples in four different languages in the next few
00:24 minutes, but it is objectively worthwhile for us to begin by showing some Java in
00:29 JUnit, simply because, that's where most of the other xUnit testing frameworks
00:33 took their lead. So first let's talk about creating new
00:36 unit tests. So in the examples I've done so far I've
00:40 had the bank account class and its corresponding bank account test class.
00:45 And this isn't exactly a rule, but a very good guideline to begin with, is that you
00:49 would create a separate unit test, a separate class for each new class you
00:54 write in your project. So when we were about to add a bank
00:57 account class, we first added bank account test.
01:00 If I added a new person class I would first go ahead and add a new person test
01:05 Junit test case, so it's common convention just to take the name of a
01:10 class she want to add and adding the unit test just put the word test after it.
01:14 Sometimes, you'll see the test case suffix instead of just test, and
01:19 sometimes you will see tests plural instead of singular.
01:22 But with Java, it's usually more common to just see test at the end, some people
01:27 even put it at the front. I preferred at the end.
01:30 And once you've actually created this new class, this new unit test, you have the
01:35 individual testing methods inside of it. Now, it used to be the case that in j
01:39 unit you had to begin each test method with the word test, because that's how
01:44 JUnit worked. It would be based on the name of the method.
01:47 It would go through these classes looking for methods that began with the word test.
01:52 However, since JUnit 4 released, which was in 2006, it's not necessary to do
01:57 that because we use this at sign test annotation instead and this is how JUnit
02:03 knows what methods to treat as tests. You can call these methods whatever you want.
02:08 But it's certainly not unusual to still see the individual test methods begin
02:13 with test as I had in my example over here called BankAccountTest, although, it
02:17 really doesn't have to have that. If I wanted to change this to just be
02:21 Deposit or Withdraw, that would be perfectly acceptable.
02:24 But, as I will show in this video, some other languages still do rely on using
02:29 test as a prefix for your test methods. Beyond that, you really just want to be
02:35 readable and understandable. And because you often want to test the
02:38 same method in your application code, multiple times in your test code for
02:43 multiple different situations. It is very common to see something along
02:46 these lines. That you would begin with the name of the
02:48 unit being tested, meaning the name of the piece of code, usually just the
02:52 method name. And then a bit of extra information to
02:55 describe what's special about this test, if anything.
02:58 So if I had a method called Withdraw, if I'm working in a language that requires
03:03 test at the start, I might call my testing method testWithdraw.
03:07 Otherwise, if it's a basic call, I might just call my testing method withdraw as
03:11 well, have them both have the same name. But, more likely, is there's something
03:15 special about the particular test. I want to withdraw and make sure that
03:20 we're going to end up with a negative balance; make sure we're going to end up
03:23 with a penalty. So I would describe that extra bit of
03:26 information, so withdrawWithPenalty. In this case, I'm using CamelCasing,
03:31 although, you may also see a format using underscores, to separate the name of the
03:35 unit being tested with what is special about this particular test.
03:39 So, even something like this. Withdraw is what we're testing, and the
03:43 situation that we care about is there's a penalty added if it's a negative balance.
03:47 But really, hopefully, what's becoming apparent is the idea that you want to use
03:51 the method name to tell the difference between the test that you're doing now
03:55 and the one before it or the one after it.
03:57 So just focus on making it readable, understandable, because you'll probably
04:01 find more of an impact based on the company that you are working for or any
04:05 style guidelines that you have or just the general way that things are named in
04:10 your chosen language. And just make sure that if you're working
04:13 with other developers that you're all roughly on the same page.
04:16 Now, because I've been using Java up till now this is actually a good point to show
04:21 three other languages. Now, I'm going to show objective C, some
04:24 C Sharp, and some Python. Now, if these aren't languages you're
04:27 familiar with, don't worry too much about that.
04:29 And I'm not trying to get you to learn the syntax of them.
04:32 What I'm trying to do is give you some exposure to, both, the core similarities
04:36 and a couple of notable differences with xUnit testing frameworks.
04:40 So, let's kind of recap the Java example with JUnit.
04:44 And here, it really is all about the @Test annotation.
04:48 When we're creating a unit test class, we don't need to inherit from any particular class.
04:53 It's a pretty normal Java class. We add this @Test, we can call the method
04:58 anything we want, but we're just here to get set up so that we can make some kind
05:02 of assert, and here, I'm using the assert equals method in JUnit.
05:07 If I jump over to C Sharp, C Sharp has the annotation equivalent.
05:12 We mark the method though, instead of using @Test, it's this test method word
05:17 in square brackets. This is the test method attribute.
05:20 Although, it also uses the test class attribute on the class itself, in my
05:25 experience it's more common in the dot net world to see the name of the unit
05:29 test class end in tests plural, rather than test singular, but there's no rule
05:34 that says this must be the case. Instead of the Assert Equals in Java, we
05:38 have the Assert.AreEqual method but, as you can see, otherwise, it's almost
05:43 identical switching over to Objective-C. Couple of differences here, mainly
05:48 because of the Objective-C syntax, but one notable thing.
05:52 Using the OC unit testing framework and Objective-C still does require that the
05:57 method be prefixed with the word, test. This is how JUnit used to be.
06:01 So instead of just Deposit, it is testDeposit.
06:03 That would be required, it wouldn't run properly without it.
06:06 And if you notice, the assertion here, instead of just AssertEquals, it's STAssertEquals.
06:12 OCUnit, the library I'm using here, came from an earlier library called Send Test,
06:16 and that's where the ST prefix comes from.
06:19 And, finally, I'll jump over to Python, and Python does have unit testing built
06:24 into its standard library. That library used to be called PyUnit,
06:27 like most of the other xUnit libraries. SUnit, JUnit, NUnit, but is now referred
06:33 to as just unittest, all one word. And in Python, the unittest will end with
06:39 TestCase, not just Test, because it inherits from the TestCase class built
06:44 into Pythos. So this is what you would typically see.
06:46 But Python also does require that the testing methods, the individual methods,
06:51 begin with the word test. So here it's test_deposit.
06:56 And it has as you might expect, it's own assert equal equivalent.
07:00 So there are some naming impacts across different languages and some conventions
07:05 of the language itself that will really have more of an impact.
07:07 But once you're past figuring out if your language requires the testing methods to
07:11 begin with the word test or if you can use an annotation or an attribute as in
07:16 Java or C sharp. They're really very similar.
07:18 It all comes back to being able to make an assertion.
07:22
Collapse this transcript
4. Individual Techniques
Testing return values
00:00 My current basic implementation of the withdrawal and deposit methods in the
00:04 bank account class, don't return values, they're both void.
00:07 But those methods do have an effect on the state of the bank account object I
00:11 can then measure. So my test is to create that new object
00:15 to call one of those methods. And then what I assert, what I test, is
00:19 the assumed side effect. Now quick sidebar here, you'll slowly
00:23 recognize that tests start to take the same general approach.
00:26 We create an object or two, we do something to that object, we test the result.
00:31 And just as we can use the phrase red, green, refactor to describe the overall
00:36 process of test and development. Each individual task can typically be
00:39 summarized using three words beginning with A, the three A rule.
00:43 To arrange, to act, and to assert. So, to Arrange is to get something set
00:49 up, to manipulate. In this case, we want to create our bank
00:51 account object. Then we Act, we change it.
00:54 We do something to it. And then we Assert, we check the result.
00:57 We check it worked. Now, not all arrange, act, and asserts
01:01 can be done with one line each, some will require more.
01:04 But it is another reminder that each of your tests are intended to be self contained.
01:09 And that you should be thinking about what each of these three a parts means
01:13 successfully for every individual test you create.
01:16 All right, end sidebar. Back to this.
01:18 We are testing here the effect of a void method.
01:21 But if I decided that this method should have a return value, and say just return
01:26 the new balance directly, I would want to test that.
01:29 And I could assert that directly. In this case, done in two lines, we
01:33 create a new instance of the bank account.
01:36 And then we'll call assertEquals expecting here that the call to
01:39 acc.withdraw will return 25. So if your methods return a value, you
01:45 test that. If your methods affect the state of an
01:47 object, you test that too. And depending on the behavior you need,
01:51 you might require tests for both the return value and the side effect of a method.
01:55 As an example so I decide the next step is I need this withdraw method to refuse
02:01 certain withdrawals. So this is the way I'm going to decide to
02:05 test it. I'll instantiate this new object and I'm
02:08 going to expect that if I make a call to withdraw passing in a huge amount that
02:12 should be disallowed. This will actually return false.
02:15 So I'm going to use the assertFalse method here.
02:18 Now, I'm assuming that if withdraw returns false, it doesn't change the
02:22 balance at all. But if I was at all worried or concerned
02:26 that there was any way the object might be affected, and I need to make it isn't.
02:30 I may add another assert, in this case I am going to assert equals to check the
02:34 balances unchanged. Again the key here is you want to test
02:38 until fear turns to boredom. And how you decide to implement this new
02:42 functionality of the withdraw statement that it will return false in the right conditions.
02:46 That's completely up to you and from this point onwards, I'm not really going to
02:50 get into that. We are focusing on the test.
02:53 Not the implementation of these. But I'd fine this completely readable.
02:57 It should fail straight away. I would go ahead and start adding in my
03:00 business logic to do this. But I would also find it fine that within
03:04 this test I want to continue on, and actually verify a successful result as well.
03:10 So I'm going to do an assertTrue, that if we call acc.withdraw passing in the
03:14 number 1. If the account already has a 100 in the
03:17 balance it should return true. It should also effect the state of the object.
03:22 So we'll add another assertEquals verifying that the balance is now 99.
03:27 Now there's a subtle distinction that I want to point out here, that I've really
03:30 got two tests going on both, having two assertions each.
03:34 One calling the withdraw method and one calling getBalance.
03:37 But both assertions are tests for the withdraw method.
03:41 And testing that it returns true or false when it needs to.
03:44 And I'm then testing the impact that it has on on the object.
03:47 And this is what I mean by subtle distinction.
03:49 If I was reading somebody else's test code and I just focused only on one of
03:54 these assertEquals lines. I might say oh, here we're testing the
03:58 getBalance method. But I am not interested in the
04:00 functionality of the get balance method I am just using it to test the
04:04 functionality of the withdraw method. But this does lead to a common question.
04:08 Do I need to specifically test my getter and setter methods?
04:13 Usually, no. But I will talk more about that in a few
04:16 other questions at the end of this chapter.
04:18
Collapse this transcript
Creating a test for expected exceptions
00:00 It's common in our application to create methods that deal with incorrect input.
00:04 Or some other issue by throwing a known exception, which can then be caught, and
00:09 handled elsewhere in the application. Now to test this individually, meaning
00:13 we're testing this happening at the UniTEST level, we need a way to fully
00:17 expect when an exception can occur. Now this is one of the areas in uni
00:21 testing where the way you do this will differ a little based on the language.
00:25 So lets take a look. Starting in JUnit I am creating a
00:29 calculator class here and I want to check its divide functionality.
00:33 Now I'll have some other tests to check it works correctly with good data.
00:37 But here I want to check its behavior if we pass in bad data.
00:40 In this case asking it to divide by 0. So I want this divide method to actually
00:46 throw an exception. I'll write this test first, I'll run it
00:51 and it will fail because the functionality doesn't exist yet.
00:53 That's fine. I go ahead and write the divide method.
00:56 Now I'm not going to jump over into that, I don't want to get into syntax there.
01:00 Just expect that my imaginary divide method will check the input values.
01:04 And if it detects wrong input, it will throw an illegal argument exception,
01:08 which is a common way of doing this in Java.
01:11 I'll come back and run this test again and it will fail but this time that
01:15 failure is because I have successfully thrown an illegal argument exception and
01:20 nothing caught it. But here's the problem.
01:22 Yes, failure is good. We want to begin with a red bar but I do
01:25 need every test to go green. So I need this test to pass when we get
01:30 an illegal argument exception from calling c.divide.
01:34 Now there's two things that may be going through your mind here.
01:37 First, you may have noticed that we don't actually have any kind of assert method
01:41 here so you might wonder is there a special assert.
01:44 Is there an assert exception method and no or at least that's not the way we do
01:49 it in JUnit. That is true in other languages.
01:52 Now alternatively, if you're comfortable with exception handling in Java, you
01:56 might think, okay, do we write our own try-catch-finally blocks right here in
02:01 this test? And, no, we don't, there's an easier way.
02:04 What I do is I add an extra piece of information to the @Test annotation at
02:10 the top. In this case, the (expected=IllegalArgumentEception.class).
02:16 What this tells JUnit is that if any code in this test method throws this specific
02:21 exception and no other kind of exception, we will go green bar.
02:26 If it throws any other kind of exception we will still fail.
02:28 And there are a couple of other ways you can do this in JUnit but this is typical
02:33 and this will now become sorted a green bar passing test.
02:36 Over in .NET with C# it's a very similar idea.
02:41 If we're expecting our divide method to throw an exception, we'll fix this by
02:45 adding a new attribute to this method. This expected exception attribute,
02:50 describing the exception we're expecting to see.
02:52 And again, the assumption here is the code we're writing to pass this test will
02:56 explicitly throw this exception in these particular circumstances.
03:01 Now an objective C. Well objective C developers do not use
03:04 exception handeling anywhere near as much as Java or .net developers.
03:09 Historically exceptions in the apple world are reserved for very serious and
03:13 typically unrecoverable errors not general handeling of flow through the program.
03:18 But there is a specific assert method in OCUnit, in this case STAssertThrows, is a
03:24 couple of versions of this. If you expect an exception to occur and
03:28 you want to test that, that your test will only work if this is the case.
03:32 Now I show it here for comparison but in objective C, you're very unlikely to want
03:37 to generate or expect an exception in this kind of circumstance.
03:42 And lastly, Python. Well, Python also has a specific assert
03:47 method to use if you expect an exception to occur.
03:50 In this case if the divide method checks it in parameters then it will raise a
03:55 value error, which is the usual one you do in Python.
03:58 If you received arguments with invalid values, so this is how your task would
04:03 specifically say you are expect to be able to raise that error expecting a
04:07 value error if I call the divide method passing in 5 and 0.
04:11 And this is how you can go green bar when this occurs.
04:15 So as you see, there are a few different syntax options here but we go back to the
04:19 idea that when we assert, we can assert in multiple ways.
04:23 Most usually we are asserting a positive outcome, asserting some kind of success.
04:29 But also as needed, we can insert a negative outcome that if we pass in this
04:33 bad data to this particular unit of code, we fully expect this error or exception
04:39 to happen. And if it doesn't happen then that's
04:42 something we want to be notified about.
04:44
Collapse this transcript
Setting up and tearing down
00:00 We've explored a couple of concepts already.
00:02 First, that for each of the, what you might think of as regular classes in your
00:07 application, you would typically create separate unit test class files.
00:11 And in each unit test class you'd have multiple simple self contained test methods.
00:18 Each testing a specific path through the methods in the relevant application class.
00:22 And we've also seen that these individual test methods themselves usually consist
00:27 of the three A approach. We arrange, we act, and we assert.
00:32 We set up some objects and values. We do something to them, then we check
00:36 the results. Now what is very common is that multiple
00:39 test methods in the same unit test class, end up beginning with a very similar
00:44 arrangement of data, a very similar set up.
00:47 Often, they're going to repeat the same code to initialize the current object
00:51 under test with some simple data. Now here, I'm just creating a BankAccount
00:55 object inside each Test method. Well, I might be able to do it in one
00:59 line, but often you need multiple lines to set up an object in some meaningfully
01:04 realistic state. So, we know duplication is bad, so you'll
01:08 be glad to know there is a way to simplify this.
01:10 X unit testing frameworks include the idea of special methods, usually called
01:15 set up and tear down. So in the same unit test class we would
01:20 add these methods. And this is the usual method signature
01:23 you would see using JUnit. Now in JUnit, the method names here, set
01:28 up and tear down, don't actually matter. We have these annotations, at sign before
01:33 and at sign after, that, like the at sign test annotation we've seen already.
01:39 These are what are telling JUnit what roles these methods play.
01:42 So adding these mean that the setup method will be called before each test,
01:47 and the tear down method is called after each test.
01:50 You do not need both. You can use one or the other or both or neither.
01:54 It is much more common to require a setup method than it is to have at tear down method.
02:00 So in that, I just do whatever method I need.
02:02 In this case, if I wanted to share the idea of just setting up the bank account
02:06 class and setting its initial balance, well, first what I'm going to need is
02:10 just to declare a bank account reference at the class level, so I can have one
02:14 available across multiple methods. This still is Java.
02:18 Then in my set up method I will instantiate that to a balance of 100, and
02:22 now I can just go ahead and remove that code from all of the individual testing methods.
02:27 Okay. It doesn't save an awful lot here but
02:29 with more involved setup routines helps avoid a lot of duplication.
02:34 Now, here's the really important idea about setup and teardown that a lot of
02:39 people miss the first time around. They read these methods, as having this
02:45 kind of effect, that if you have setup and tear down, setup will be called at
02:49 the start, then your testing methods will be called and then teardown will be called.
02:53 But really it's this. It's before and after every single test method.
02:59 If you have these methods, JUnit, or whatever other testing framework that
03:04 you're going to use, well actually call setup before each test method and
03:09 teardown after each test method. And once again, I will remind you that
03:13 your testing method should be completely independent of each other, that JUnit or
03:18 whatever unit testing framework you're using will book end them with setup and
03:22 tear down but, they should be able to run in a completely different order and it
03:26 wouldn't matter at all. Now, if what you actually wanted was a
03:29 method that would only run once at the very start of all the test methods and/or
03:34 once at at the end of all the test methods, no matter how many test methods
03:37 you had, you can create another couple of methods.
03:41 So, if you wanted this typical name we would use as setup before class and
03:44 teardown after class. Again, in JUnit, it's all about the annotations.
03:50 So we have the @BeforeClass annotation and the @AfterClass annotation.
03:55 This can be useful but out of the four available, the setUp, tearDown,
03:59 setUpBeforeClass, and tearDownAfterClass, you will find that setUp is the one you
04:04 use most often. So I'm going to do a quick comparison of
04:07 the other languages to show that while the syntax may be different, the ex unit
04:11 ideas are the same everywhere. So, if I just over to .NET.
04:16 If we're using the built in Microsoft unit testing library instead of using at
04:20 sign after an at sign before, you would add the TestInitialize and TestCleanup
04:24 attributes to your methods for setup and teardown at a per test level.
04:30 There is also class initialize and class cleanup attributes that can be added to a method.
04:35 Whereas, in OCUnit, in Objective C, it is based purely on the name of the method.
04:41 So you actually need setup and teardown methods, but these are provided in any
04:44 sample unit test class that you would make.
04:48 And likewise in Python, it is also based purely on the name of the method.
04:53 You would need the set-up and tear-down methods.
04:55 Now when you start to flush out your unit test classes to the point where you don't
04:59 just have a couple of test methods but also have setup and teardown when
05:03 necessary, you'll hear this occasionally referred to as a test fixture.
05:09 Now it is true that there is quite a few terms in unit testing that almost get
05:14 used interchangeably, just even the word itself is sometimes a little vague.
05:19 But you've got test case, test class, test fixture that often seems to be used
05:24 and doesn't really matter which one that you're using.
05:26 But most typically and most formally when the term test fixture is used it refers
05:32 to the idea that not just the individual test methods but the entire set of tests
05:36 for one class including any associated set up and tear down.
05:41
Collapse this transcript
Common questions on individual tests
00:00 I want to finish up this section by going through a few questions and issues that
00:03 are common to hear at this time including a couple of things I referred to earlier.
00:08 We'll begin with the question do I need to test things like the get and set
00:13 methods of properties? And this really depends if you have
00:17 simple getters and setters that are just the equivalent of returning or setting
00:21 internal balances. Or if you're using a language that
00:24 generates or synthesizes them, then no, these don't need testing.
00:28 There is no point at all to creating specific unit tests for this kind of
00:33 stuff because there's simply nothing you could do if it failed.
00:36 You're trying to test everything that could break and that you could then fix.
00:41 You're not trying to test the language itself, you're testing your own logic.
00:46 So it's fine to assume that somethings will just work, that a return statement
00:50 will work. That if you add two and two, you will get four.
00:54 That's not the kind of stuff that needs tested.
00:56 Now if however you need a custom setter method that contains branching logic or
01:02 that might change an internal value and then affect another object, well then by
01:06 all means sure, create a test to make sure your logic works.
01:12 Next up, what about private methods? Do these need to be tested?
01:15 Well, usually no with a couple of caveats.
01:18 In most languages you couldn't do this anyway.
01:20 If your unit test is in a separate class file, you wouldn't be allowed to test a
01:24 purely private method of another class. Now there is some debate on unit testing
01:29 private methods. And there are some x unit testing
01:32 frameworks that allow you to test private methods using language features like
01:37 introspection and reflection. But I'll admit I'm not a fan of directly
01:41 testing private methods. Instead directly test a public method and
01:46 just make sure there is a test or multiple tests that you can do to a
01:50 public method to verify the impact of any private method that calls.
01:55 Next question. Can I combine multiple test classes
01:58 together to run everything at once? Well, sure.
02:02 Bundling together multiple test classes or test cases or test fixtures, whatever
02:08 you want to call them is usually referred to as a Test Suite.
02:11 And it could be done in all unit testing frameworks that I know of.
02:15 There is often support for it in an IDE and in fact a couple of development
02:19 environments will just go ahead and run every single one of your tests by default
02:24 when you click the Test option. However, beyond saying yes, you can
02:29 bundle these up, I am not going to spend time on test suites here because early on
02:34 these shouldn't be a major focus. And test suites can actually be a
02:38 distraction for people learning test-driven development.
02:41 It's not that bundling tests together is a bad idea.
02:44 But it often leads to this innocent sounding, understandable but deceptively
02:49 dangerous question. How can I control the order of my unit tests?
02:54 And you never want to enforce any order of execution of unit tests because that
02:59 leads to dependencies. Or these tests only work if they come
03:03 after this set or before this set of tests.
03:06 And once you introduce dependencies, you can't then quickly add or change new
03:10 tests without reviewing other classes first and you simply won't do this.
03:15 So this innocent-sounding question answered any other way than, you don't,
03:20 is in danger of totally derailing TDD as a development practice.
03:24 We need to stay focused on creating small tests that are self contained and
03:29 isolated that could run in any order. And remember that when unit testing we
03:34 are not writing tests that test the application.
03:38 We are testing the individual units of code and we need to always do our best to
03:43 minimize any dependency, minimize any coupling between different parts of the
03:48 application or between the application and other systems.
03:52 And in the next chapter what I'm going to talk about are specific things to watch
03:56 for and avoid and a few situations where we're going to need to fake our results.
04:00
Collapse this transcript
5. Additional Topics
Introducing mock objects
00:00 Our entire aim in unit testing is to be able to test pieces of code in isolation.
00:05 We're not writing tests that attempt to use the full application, but rather to
00:09 end up with hundreds, even thousands of separate unit tests, each one testnig a
00:14 single small part of the system, independently of the others.
00:17 Now, when the class, the component, whatever you'd like to call the thing
00:21 that you're looking at. The current unit under test.
00:24 When that contains totally self-contained behavior, it's quite straightforward to test.
00:29 You can create new tests directly for this class and its methods without caring
00:33 about what any of the other classes do. Or even if any other class has existed at all.
00:38 But let's face it, you don't have classes that exist purely in a vacuum.
00:42 As soon as you've gone beyond the trivial these will need to interact.
00:46 They will interact with objects of other class types.
00:48 They'll interact with databases, with websites and web services, with the file
00:53 system and some of the things that they'll need to interact with are difficult.
00:57 Some are slow, some are unreliable Quite a few are not under our control.
01:01 They may return different values every time they're called.
01:04 And if we're trying to do test-driven development and build our tests alongside
01:08 building our application, some of these objects may not even exist yet, they just
01:12 haven't been written. And in unit testing we want to minimize
01:16 any dependencies between the unit we're currently testing and anything else.
01:21 I actively want to avoid testing multiple components at the same time.
01:25 Because if I write a test that instantiates a dozen objects of different types.
01:29 Loads information from the web, saves to a database, writes to the file system,
01:33 and I run that. I make an assertion, and the assertion
01:37 fails, I don't where to look. I've introduced multiple points of failure.
01:42 My so-called unit test is now testing much more than just this unit.
01:47 So what do we do? Well, the answer is not just avoid
01:50 testing any part of your unit that interacts with anything else.
01:53 We have to think about the goal here. And what we'd like to be able to do when
01:57 testing a unit is just assume that every other part of this is perfect and reliable.
02:03 So we can focus our test purely on the current unit.
02:05 And if a problem occurs, we know exactly where that problem is.
02:09 And one technique for this Is mock objects.
02:13 We replace usage of other objects, other systems, these external dependencies,
02:18 with fake or mock implementations that we can be sure will repeatedly behave the
02:23 way they are meant to. That instead of passing a query to a real
02:26 database, we pass a query to a mock version that's just code, it's just in
02:30 memory and will reliably return the results we want our unit to work on.
02:34 That we can even replace a call to an object that doesn't exist yet with a call
02:38 to a mock version of that object that behaves exactly as the real one should do.
02:43 So there's a few classic reasons to look at a mock object.
02:47 The first being that the real object hasn't been written yet.
02:49 That's the easiest one. After that it's what you're calling, if
02:53 it needs a UI or it has human interaction we can't wait for somebody to interact
02:58 with some external system if we want to run our unit test 100 times a day so we
03:03 could emulate what that is meant to return, if it's slow or difficult to set up.
03:08 One of the most common reasons for using mock objects is if you are interacting
03:12 with some external resource like a file system or a data base you're loading
03:16 something over the network. You're trying to save results to a
03:19 printer because these are difficult to either test that you are intending to
03:25 happen has happened. Or they're not exactly repeatable.
03:28 If we're saving things to a database and we're trying to do that 100 times a day,
03:33 actually changing the state of the database, that's going to be a difficult
03:37 thing for us to test in any kind of lightweight fashion.
03:40 And again, we're focusing on the current unit.
03:43 Yes, we might be interested at some point that the database is working as expected
03:47 But when we're testing a different unit, we want to take that as a given in which
03:50 case it's very useful to be able to mock up some of that basic database behavior.
03:55 And very common leads, anything with non-deterministic behavior.
03:59 And that could be something like calling a web service where we might get a
04:03 different response every time or we might even get a network error.
04:06 Calling something that's going to give us some data back, that may change from
04:10 moment to moment or day to day. So what may this look like in a test?
04:14 But lets say I wanted a test on my current unit, and it's going to call a
04:19 web service object to get a weather forecast and then do some operations on
04:23 the results. Well this could be non deterministic I'm
04:26 not sure what its going to return and it could unexpectedly give me network errors.
04:30 But that's what I'm interested in testing.
04:33 I want to take the fact that this network service that returns a weather forecast
04:37 will just work so I can then bring back the result and work on those results and
04:42 assert some behavior after the fact. So what I could do is define a mock
04:47 version, create a new class called MockWeatherService.
04:51 Then instantiate that object, writing that class so it will return a
04:55 repeatable, prearranged response from this getForecast call.
04:59 So I then go ahead and use it as if I was using the real service, but I always get
05:03 a reliable response. I don't have to worry about network
05:06 connections or anything else. And once again, an important but subtle distinction.
05:10 What I'm doing in this test is I'm not interested in testing the actual weather service.
05:15 I'm intending on taking it as successful, taking it as a given.
05:20 I'm interested in getting some results back for it, and using those results.
05:24 There's two things we often do with mock objects.
05:27 We want them to return expected values, and do it quickly and repeatedly.
05:31 But we also often want to use them to verify that how we are calling these
05:36 objects is correct. That if we are going to be calling a web
05:39 service, are we positive That we're going to pass the right data into that.
05:43 And one way I could do this is adding method to my mock object class to tell it
05:48 to expect a certain value. So when we're getting everything
05:51 arranged, I could tell it, you're going to expect this zip code, 85253.
05:56 Then later on in the test when I call be getForecast, passing in a property of my
06:01 current object, I could verify that this is actually the case.
06:04 So then by calling this getForecast method, my mock object itself can assert
06:09 that what was passed in was correct and fail if it wasn't, alerting me that
06:12 perhaps the initial state of my data in this unit isn't what I thought it was.
06:18 Now there's a couple of terms that you'll hear when you start talking about mock objects.
06:22 One is the distinction between fake objects and mock objects.
06:26 There are a couple of other terms like dummy objects, but let's just cover the
06:30 usual difference between fake and mock when people are talking about them.
06:33 A fake object is the simplest kind of mock object these are dumb.
06:38 They just have a pre-written Implementation of the object that they
06:41 are supposed to represent, so they have the same method signatures returning
06:46 pre-arranged, pre-written responses. And if people are making a distinction
06:50 between fake objects and mock objects, that usually implies that some code is
06:55 inside the mock object that doesn't just return values.
06:59 But also asserts that any interaction with it is corret.
07:02 That how we are calling this object and what we're passing into it can be verrified.
07:07 So, a mock object often contains assertians that verify any input in a way
07:12 that any fake object somtimes does not And while you mainly use mock objects to
07:17 return repeatable successful values, you can also use them to simulate difficult
07:23 to emulate situations. In this case, I might have a way to call
07:26 my mock weather service object that will reliably result in an emulated network error.
07:31 So I can test that in my unit, I will successfully deal with that response.
07:37 Now there is nothing that would stop you from just writing your mock objects
07:41 yourself as regular classes in your programming language.
07:44 Creating a mock or a fake object that responds the way you need it to, and just
07:48 instantiating and using that in your test.
07:51 But there are several mock object frameworks that we can use to help in
07:54 this process. Now these aren't part of the unit testing
07:57 frameworks we've been using, they're actually seperate.
08:00 And I'll cover a few in just a moment. The benefits are that they provide some structure.
08:04 They can make it easier for you to define your mock objects, and depending on the
08:08 framework that you'd use, sometimes they will remove the need for you to create an
08:12 explicit custom class, but can help you dynamically generate what you need using
08:17 either interfaces in the language, or perhaps an abstract class signature.
08:22 They can help generate method stubs or auto-generate method stubs.
08:25 And quite importantly they can often provide some of the most commonly needed
08:29 mock objects, particularly dealing with any kind of output from your program.
08:33 So you can direct output to a mock network stream or a mock printer stream
08:38 or file stream and then explicitly check the result so you're verifying the way
08:42 your unit is sending data out to those objects.
08:46 Is exactly what you expected. Now there are several different available
08:50 mock object frameworks and these aren't as identical as the general x unit
08:55 frameworks so they are worth taking a look at indepentendly to see what they
08:59 offer your particular project. Java has several popular mocking
09:03 frameworks include jmock there's easymock framework.
09:08 There's mockito. Mockito is a little different from the
09:12 others and it tries to allow you to dynamically generate your mock objects
09:16 rather than explicitly writing classes for them all the time.
09:20 Over in dot net the Microsoft Fakes framework is actually built into visual
09:25 studio that supplies quite a lot of these ideas although there are other options
09:29 you can select including mock or mock-you.
09:33 If I jump over to the Objective-C site, not as many options here.
09:36 Probably the better known one is OCMock. And over on Python, there is a library
09:42 called mock that is part now of the Python standard library.
09:45 So expect multiple options in pretty much any language that you're working in.
09:50 Of course, mock objects aren't for everything.
09:52 They do introduce some level of risk. If you're happily using a mock object
09:57 because the real one hadn't been written yet, and it is then written with
10:00 different behavior than you expected, you're going to run into problems.
10:04 But they are definitely a tool to make use of when unit testing.
10:08
Collapse this transcript
Measuring code coverage
00:00 One number that's often measured when using automatic unit test is Code Coverage.
00:05 Simply put, this is a percentage measurement of exactly how much of your
00:08 application code is being successfully hit by your unit test.
00:13 It's certainly not a guarantee of perfection just because you have executed
00:17 a line doesn't mean you've tested every possible combination of data and options
00:22 that could have gone into that line. But code coverage will certainly let you
00:25 know what you're missing. Even the most basic code coverage reports
00:29 will typically tell you different numbers for how many of your classes are being
00:32 tested, and within those, how much of your methods are being tested, and the
00:36 blocks, and even individual lines of code inside those methods.
00:40 Now as you might expect, this is something that is done with a tool that
00:43 can perform this analysis. And there are a lot of code coverage tools.
00:48 Some are free, quite a lot are commercial.
00:50 And the options are much better in enterprise-heavy environments, say Java
00:54 and .NET, than they are in languages like Objective C or Python.
00:59 But as a quick summary what I'm looking at right now is a code coverage report
01:03 generated by a tool called EMMA. EMMA is a free Java code coverage tool,
01:09 it's very popular in the Java world. There are also things like plugins for this.
01:13 You can have something called, EclEMMA, which is an Eclipse plugin, which will
01:17 integrate that properly into Eclipse and start showing you the visual impact of this.
01:21 In this case, it is green lines show code that is being hit by a unit test, red
01:26 lines are showing code that is not being hit by a unit test, and yellow is where
01:30 you might have a line that's partially being hit.
01:33 There are also commercial tools such as Clover from Atlassian.
01:38 These are more involved with many more option for reporting but they have a
01:41 price to them. Over on the .net side of things if you're
01:44 using premium or ultimate editions of Visual Studio, there are actually code
01:49 coverage tools built into the task manager.
01:51 Though aside from that there are several third party options, mainly commercial
01:56 ones are the better known ones such as dot cover and NCover.
02:00 Though as you'll see from looking around different code coverage tools are
02:03 obviously targeted at different kinds of audience, so take a look at this and see
02:07 which one might suit what you're doing best.
02:09 Now over in Objective-C and Python, the story is a little weaker.
02:13 With Python, the most common is coverage.py, which you can find from the
02:17 Python site itself. And this will generate you those numbers.
02:21 There are also options in XCode to generate code coverage files, but that
02:25 gets a little specific and not very useful for this course to get into.
02:29 So take a look at our Unit Testing in XCode course for more on that.
02:34 Again, code coverage tools aren't a guarantee of perfection but particularly
02:38 if you can get one that can show you visually which lines of code are or are
02:42 not being hit by your unit test, they're very worthwhile to let you know when
02:46 there are chunks missing in exactly where they are.
02:49
Collapse this transcript
TDD recommendations
00:00 There are a few more concepts we could get into about test-driven development,
00:04 but my first suggestion is not yet, because you should be able to take what
00:09 we've covered in this course and begin, get started.
00:12 Test-driven development is not something that requires guru knowledge.
00:15 It really is getting these few ideas down and then jumping in, starting to develop
00:20 the habit of writing simple tests, and particularly, the habit of writing the
00:23 tests first. And we've covered all the basic aspects
00:26 of test and development. Sure, there may be things you need to
00:29 add, more specific situations you'll have to explore.
00:33 But those are likely to more about the unique circumstances of your application
00:37 and your environment. So here's a few recommendations and
00:40 guidelines as you get started with this. First off, numbers.
00:44 Now, these aren't rules, but a general expectation would be you'd have one test
00:49 case or test fixture or test class, whichever you prefer per regular
00:54 application class. And in that, 3, 4, maybe 5 test methods
00:59 per class method. Sure, you can do more or less as needed
01:03 but here's the thing, if you find yourself going way beyond this say, 38
01:07 test methods for a single class method, it's going to be a clue that class method
01:11 is doing way too much and has too much responsibility.
01:14 It should be split up, and likewise, if you're averaging only one test method for
01:20 each class method. I'd wonder where your logic is, where is
01:23 your branching? Where are your conditions?
01:25 And, are you actually testing them? And that leads us to, what to test?
01:30 Well, as hopefully, it's becoming obvious, the driving idea is that you
01:33 test every single path through the code. And yes, that means a separate test for
01:38 every branch of an if statement. Every if, else, and, or, every case statement.
01:44 A test for every for and while, and do loop in a method.
01:48 And a test for every use of polymorphism, where it's being used to achieve
01:52 different results. And that's the real answer to the early
01:55 question, well, how many tests should I have, is how many do you need to test all
01:59 the paths through the code. And as the phrase goes, test until fear
02:03 turns to boredom, 'til you're confident that all your paths are being tested.
02:08 And use code coverage tools to verify that what you think you are testing has
02:12 some bearing on the actual reality of what you are testing.
02:15 Now, what to avoid? Always think small, self-contained,
02:20 isolated, and repeatable. So unit tests, as a rule, should not A,
02:26 interact with a real database or a file system.
02:29 That's going to interfere with repeating. It's going to rely on or change external
02:34 state and we want to avoid that wherever possible.
02:37 Use mock objects when necessary. Now, here's the thing.
02:40 If you're feeling this resistance, thinking well, surely, there are times to
02:43 test the database. Yes, absolutely there are.
02:46 But that is functional testing, or integration testing, or regression testing.
02:50 This is not unit testing. Next, they should not require any
02:55 nontrivial network communication, that will be another dependency, mark this out
02:59 if necessary, you are testing this unit. You are not testing the network.
03:04 Unit test should not require any environment changes.
03:07 If you need to change configuration files back and forth when you're running you're tests.
03:12 Well, there's two problems here. A, you're not likely to continue to do
03:16 this so you won't run your test as often as you should, And be, again you would be
03:20 relying on some kind of external state affecting your unit test.
03:25 And again, I'll go back to the idea of independent and isolated unit test should
03:30 not have and certainly not require dependencies on the state of any external system.
03:36 Your unit tests shouldn't call any complex, any non-trivial collaborator objects.
03:41 Again, this is all about clarity on what you're testing.
03:43 If those objects need tested, the unit test should be for those objects.
03:48 Here, we're testing this unit, not this unit and a bunch of others at the same time.
03:53 Much of these recommendations come back to one core idea, unit testing is not
03:59 like other kinds of testing. Don't let your unit tests slowly decay
04:03 into or become confused with integration tests or functional tests or application
04:09 level tests. There is a place for those.
04:11 But that is a very different mindset and a different approach from the day-to-day
04:16 test-driven development routine we want here.
04:19 Now, if you're working with an existing code mix, a project written without unit
04:23 tests, and you're now intending to add TDD practices to that Now there's a
04:28 couple of ways you could go about this. Approach number 1 would be to try and add
04:32 a complete set of unit tests. So you could decide to go for 100% code
04:38 coverage right out of the gate and write all of your unit tests in one go.
04:42 But in a large project, writing nothing but unit tests for weeks, is a totally
04:47 soul sucking death march, and this never works well, simply because the code
04:52 wasn't written to be tested, and that matters.
04:55 As you're beginning to see, test-driven development is not primary about a
05:01 testing process. This is a design process.
05:04 TDD changes the way you think about and the way you write your application code
05:09 not just your testing code,so you can't just come along, drop a bunch of unit
05:13 test onto existing code and call it test driven development...
05:17 So brick number 2, a better idea at unit test as you need them.
05:21 This is a much more workable plan when adding to an existing legacy code base,
05:26 particularly as you do any refactoring for intended addition.
05:30 So if you're attempting to work on an existing class, you first add a few unit
05:34 test that will attempt to prove and validate existing functionality so that
05:38 you know if you break anything, and once you got that in place in the current unit.
05:42 Start the normal red green refactor cycle.
05:46 Beginning by adding a failing test for the new functionality you want to add.
05:51 Sure, this way is going to take a long time to get to a significant level of
05:55 code coverage, but it's a much more realistic and manageable approach for
05:59 existing projects.
06:00
Collapse this transcript
Conclusion
Next steps
00:00 While I've been keeping this course as generic as I possibly can, we can only
00:04 apply these ideas in some specific language, some specific environment.
00:09 So I'm going to cover a few resources for moving forward using a particular
00:13 language if you haven't already been doing that.
00:15 Now these recommendations obviously pale into insignificance if you're working in
00:20 an environment that already has some test driven development or at least automated
00:24 test processes in place. So, getting started with Java.
00:29 Well, with Java, the 400 pound gorilla of unit testing is still JUnit.
00:33 And JUnit.org has a very useful and wiki and reference that really does cover
00:38 almost everything that you would need on a day to day basis, when creating an
00:42 using tests. It starts off with things like quick
00:45 references for the available assertion methods.
00:49 With the example shown here, where there're optional error messages that you
00:52 can add. There's information about test runners,
00:56 how to actually run these tests. Although, if you're using most common
00:59 IDE's, running your JUnit tests is built directly into the program.
01:04 And it continues on to go through things like exception testing that we've already covered.
01:09 And there's a few advanced and Java-specific sections, things like how
01:12 to use Java with Maven, the Java build manager, and so on.
01:16 Now, if you're using Visual Studio 2012, the best single place to get started is
01:22 the page on verifying code review unit tests in the MSDN library.
01:26 This is a great resource because it actually expects that you are comfortable
01:30 with the ideas that we have covered in this course.
01:32 And then just takes you through using these ideas in visual studio with C Sharp.
01:37 So there's a walkthrough down here on creating and running basic unit tests,
01:41 there's also sections on using Microsoft's Visual Studio test explorer.
01:46 There's information on code coverage tools, and even on using the Microsoft,
01:51 fakes framework, which is the equivalent of creating mock objects.
01:55 Jumping over to Objective C, well, for this, I'm actually just going to point
01:58 you to Ron Lisle's course, Unit Testing iOS Applications here in the lynda.com library.
02:04 And most of the ideas here work for both iOS and Cocoa applications.
02:08 And this course covers not just the OCUnit framework that's built into Xcode,
02:13 but also the GHUnit alternative framework many apple developers prefer.
02:18 Now with Python, the best to bookmark is simply the unit test section of the
02:23 Python docks, as it's build into the standard library.
02:26 In this single page covers 99% of everything you'd ever need to know when
02:31 doing unit testing and Python, including some very straight forward examples and
02:36 there's a useful link right at the top of the page that takes you directly to the
02:40 list of Python Assert methods. Now those were the languages that I'd
02:44 explored in this course, but just one other.
02:47 If you are using Ruby, a language that I haven't really talked about here.
02:51 You know that there was an X Unit style testing framework called Test Unit
02:55 bundled into the language for a long time up to Ruby 1.8.
02:59 Although with Ruby 1.9 that was replaced by another unit testing framework called minitest.
03:05 And I'm looking here at the Ruby toolbox website, which is showing the popularity
03:09 currently, of unit test frameworks. We can see test unit, which is a fairly
03:13 common XUnit-style framework, and minitest, which does include XUnit-style ideas.
03:18 But, it's worth pointing out that currently the most popular testing
03:22 framework with Ruby is not an x-unit style framework.
03:26 It's a framework called RSpec that supports something they call
03:29 Behavior-Driven Development or BDD rather than Test-Driven Development or TDD.
03:36 Although, know that if you are a Ruby person who had been watching this course,
03:39 most of the ideas in RSpec in Behavior-Driven Development are
03:44 extensions of, or reactions to things in test-driven development.
03:48 So you should still find everything in this course useful if you decide to jump
03:53 into looking at RSpec. And finally, whatever language you are
03:56 using, I would recommend taking a look at my Foundations of Programming:
04:00 Refactoring course here at lynda.com, as refactoring and test-driven development
04:05 are two programming practices that really do go hand in hand.
04:09 So thanks for joining me for Foundations of Programming, Test-Driven Development.
04:14 May your tests go red, and then green, and stay green.
04:18 See you next time.
04:19
Collapse this transcript


Suggested courses to watch next:


Are you sure you want to delete this bookmark?

cancel

Bookmark this Tutorial

Name

Description

{0} characters left

Tags

Separate tags with a space. Use quotes around multi-word tags. Suggested Tags:
loading
cancel

bookmark this course

{0} characters left Separate tags with a space. Use quotes around multi-word tags. Suggested Tags:
loading

Error:

go to playlists »

Create new playlist

name:
description:
save cancel

You must be a lynda.com member to watch this video.

Every course in the lynda.com library contains free videos that let you assess the quality of our tutorials before you subscribe—just click on the blue links to watch them. Become a member to access all 104,069 instructional videos.

get started learn more

If you are already an active lynda.com member, please log in to access the lynda.com library.

Get access to all lynda.com videos

You are currently signed into your admin account, which doesn't let you view lynda.com videos. For full access to the lynda.com library, log in through iplogin.lynda.com, or sign in through your organization's portal. You may also request a user account by calling 1 1 (888) 335-9632 or emailing us at cs@lynda.com.

Get access to all lynda.com videos

You are currently signed into your admin account, which doesn't let you view lynda.com videos. For full access to the lynda.com library, log in through iplogin.lynda.com, or sign in through your organization's portal. You may also request a user account by calling 1 1 (888) 335-9632 or emailing us at cs@lynda.com.

Access to lynda.com videos

Your organization has a limited access membership to the lynda.com library that allows access to only a specific, limited selection of courses.

You don't have access to this video.

You're logged in as an account administrator, but your membership is not active.

Contact a Training Solutions Advisor at 1 (888) 335-9632.

How to access this video.

If this course is one of your five classes, then your class currently isn't in session.

If you want to watch this video and it is not part of your class, upgrade your membership for unlimited access to the full library of 2,024 courses anytime, anywhere.

learn more upgrade

You can always watch the free content included in every course.

Questions? Call Customer Service at 1 1 (888) 335-9632 or email cs@lynda.com.

You don't have access to this video.

You're logged in as an account administrator, but your membership is no longer active. You can still access reports and account information.

To reactivate your account, contact a Training Solutions Advisor at 1 1 (888) 335-9632.

Need help accessing this video?

You can't access this video from your master administrator account.

Call Customer Service at 1 1 (888) 335-9632 or email cs@lynda.com for help accessing this video.

preview image of new course page

Try our new course pages

Explore our redesigned course pages, and tell us about your experience.

If you want to switch back to the old view, change your site preferences from the my account menu.

Try the new pages No, thanks

site feedback

Thanks for signing up.

We’ll send you a confirmation email shortly.


By signing up, you’ll receive about four emails per month, including

We’ll only use your email address to send you these mailings.

Here’s our privacy policy with more details about how we handle your information.

Keep up with news, tips, and latest courses with emails from lynda.com.

By signing up, you’ll receive about four emails per month, including

We’ll only use your email address to send you these mailings.

Here’s our privacy policy with more details about how we handle your information.

   
submit Lightbox submit clicked