[Script Info] Title: [Events] Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text Dialogue: 0,0:00:17.06,0:00:19.74,Default,,0000,0000,0000,,ERIK MICHAELS-OBER: OK. Is the mic live? Yeah?\NWe're good. Dialogue: 0,0:00:19.74,0:00:26.74,Default,,0000,0000,0000,,OK. Hi everybody. Welcome. Thank you for coming.\NSo, Dialogue: 0,0:00:28.89,0:00:33.99,Default,,0000,0000,0000,,this is gonna be a talk about tools. And Dialogue: 0,0:00:33.99,0:00:37.97,Default,,0000,0000,0000,,there's this common expression that says that\Na carpenter Dialogue: 0,0:00:37.97,0:00:41.72,Default,,0000,0000,0000,,is only as good as his or her tools. Dialogue: 0,0:00:41.72,0:00:43.60,Default,,0000,0000,0000,,I'm not a carpenter, but that makes a lot Dialogue: 0,0:00:43.60,0:00:46.19,Default,,0000,0000,0000,,of sense to me. If your hammer is made Dialogue: 0,0:00:46.19,0:00:49.32,Default,,0000,0000,0000,,out of feathers, you're not gonna be able\Nto Dialogue: 0,0:00:49.32,0:00:51.49,Default,,0000,0000,0000,,build very much. Dialogue: 0,0:00:51.49,0:00:54.86,Default,,0000,0000,0000,,And I really think the same thing is true Dialogue: 0,0:00:54.86,0:00:58.87,Default,,0000,0000,0000,,for programmers. I know that that is true.\NThe Dialogue: 0,0:00:58.87,0:01:02.96,Default,,0000,0000,0000,,tools that we use really enable us to do Dialogue: 0,0:01:02.96,0:01:06.07,Default,,0000,0000,0000,,our job. And we use so many tools, it's Dialogue: 0,0:01:06.07,0:01:08.51,Default,,0000,0000,0000,,easy to sort of take for granted the tools Dialogue: 0,0:01:08.51,0:01:10.21,Default,,0000,0000,0000,,that we have and the tools that we do Dialogue: 0,0:01:10.21,0:01:13.23,Default,,0000,0000,0000,,use. And so I think it's worth sort of Dialogue: 0,0:01:13.23,0:01:15.16,Default,,0000,0000,0000,,thinking about the tools that we have and\Nhow Dialogue: 0,0:01:15.16,0:01:18.95,Default,,0000,0000,0000,,they help us improve as a programmer. And\Nthinking Dialogue: 0,0:01:18.95,0:01:21.78,Default,,0000,0000,0000,,about what new tools we can use. In this Dialogue: 0,0:01:21.78,0:01:25.80,Default,,0000,0000,0000,,case, I'll be talking specifically about mutation\Ntesting and Dialogue: 0,0:01:25.80,0:01:27.96,Default,,0000,0000,0000,,how that, as a tool, can really help us Dialogue: 0,0:01:27.96,0:01:31.100,Default,,0000,0000,0000,,all improve as programmers. Help us write\Nbetter tests. Dialogue: 0,0:01:31.100,0:01:35.06,Default,,0000,0000,0000,,But, I think, I just want to sort of Dialogue: 0,0:01:35.06,0:01:36.98,Default,,0000,0000,0000,,take some time to reflect and, and set a Dialogue: 0,0:01:36.98,0:01:39.78,Default,,0000,0000,0000,,little bit of a context for the tools that Dialogue: 0,0:01:39.78,0:01:41.63,Default,,0000,0000,0000,,we use every day and sort of, I think Dialogue: 0,0:01:41.63,0:01:43.85,Default,,0000,0000,0000,,take for granted a bit. Dialogue: 0,0:01:43.85,0:01:49.74,Default,,0000,0000,0000,,So, the first one is an editor. And it Dialogue: 0,0:01:49.74,0:01:52.35,Default,,0000,0000,0000,,seems like a very simple tool, right. You\Njust Dialogue: 0,0:01:52.35,0:01:53.61,Default,,0000,0000,0000,,type in text and it just shows up on Dialogue: 0,0:01:53.61,0:01:57.50,Default,,0000,0000,0000,,the screen. But it's incredibly sophisticated.\NIf you've ever Dialogue: 0,0:01:57.50,0:01:59.18,Default,,0000,0000,0000,,tried to write a text editor, if you've ever Dialogue: 0,0:01:59.18,0:02:01.49,Default,,0000,0000,0000,,read the source code of a text editor, most Dialogue: 0,0:02:01.49,0:02:04.19,Default,,0000,0000,0000,,text editors are like millions of lines of\Ncode Dialogue: 0,0:02:04.19,0:02:08.20,Default,,0000,0000,0000,,to implement what seems like a relatively\Nsimple thing. Dialogue: 0,0:02:08.20,0:02:09.88,Default,,0000,0000,0000,,And they help us. They provide us with things Dialogue: 0,0:02:09.88,0:02:14.68,Default,,0000,0000,0000,,like syntax highlighting, auto completion.\NAnd this directly helps Dialogue: 0,0:02:14.68,0:02:17.94,Default,,0000,0000,0000,,us write better programs, right. We avoid\Nbugs. We'll Dialogue: 0,0:02:17.94,0:02:20.70,Default,,0000,0000,0000,,realize a bug in our editor before we, before Dialogue: 0,0:02:20.70,0:02:23.23,Default,,0000,0000,0000,,we deploy it to production. Before we even\Nrun Dialogue: 0,0:02:23.23,0:02:25.81,Default,,0000,0000,0000,,tests, we'll find a bug in our editor. Because Dialogue: 0,0:02:25.81,0:02:29.66,Default,,0000,0000,0000,,our editor tells us about it. Dialogue: 0,0:02:29.66,0:02:36.66,Default,,0000,0000,0000,,This is an early version of Vim. So it Dialogue: 0,0:02:36.91,0:02:38.90,Default,,0000,0000,0000,,can, it can be really easy to forget sort Dialogue: 0,0:02:38.90,0:02:40.99,Default,,0000,0000,0000,,of what these tools used to look like, right. Dialogue: 0,0:02:40.99,0:02:44.05,Default,,0000,0000,0000,,This is how people used to write code. And Dialogue: 0,0:02:44.05,0:02:45.63,Default,,0000,0000,0000,,these look more like the sort of tools from Dialogue: 0,0:02:45.63,0:02:47.38,Default,,0000,0000,0000,,the wood shop than the tools that we're used Dialogue: 0,0:02:47.38,0:02:51.01,Default,,0000,0000,0000,,to using. So this is an early punch card Dialogue: 0,0:02:51.01,0:02:54.96,Default,,0000,0000,0000,,machine. The photo was taken in the, in the Dialogue: 0,0:02:54.96,0:02:59.23,Default,,0000,0000,0000,,computer history museum in Mountainview, California.\NAnd I can Dialogue: 0,0:02:59.23,0:03:01.26,Default,,0000,0000,0000,,tell you for a fact that I would not Dialogue: 0,0:03:01.26,0:03:03.27,Default,,0000,0000,0000,,be a programmer today if this is how we Dialogue: 0,0:03:03.27,0:03:05.70,Default,,0000,0000,0000,,still had to write programs. And I suspect\Nthat Dialogue: 0,0:03:05.70,0:03:08.53,Default,,0000,0000,0000,,many of you would not be programmers if this Dialogue: 0,0:03:08.53,0:03:11.60,Default,,0000,0000,0000,,was sort of the state-of-the-art in how it\Nwas Dialogue: 0,0:03:11.60,0:03:12.19,Default,,0000,0000,0000,,done. Dialogue: 0,0:03:12.19,0:03:14.93,Default,,0000,0000,0000,,And so I think, like, I want to make Dialogue: 0,0:03:14.93,0:03:17.25,Default,,0000,0000,0000,,the case that sort of both the quality and Dialogue: 0,0:03:17.25,0:03:20.55,Default,,0000,0000,0000,,the quantity of software would be much worse\Nthan Dialogue: 0,0:03:20.55,0:03:22.59,Default,,0000,0000,0000,,it is today, if not for sort of the Dialogue: 0,0:03:22.59,0:03:28.19,Default,,0000,0000,0000,,continued evolution of, of our tools. Dialogue: 0,0:03:28.19,0:03:30.46,Default,,0000,0000,0000,,Another tool I use every day is an interactive Dialogue: 0,0:03:30.46,0:03:34.64,Default,,0000,0000,0000,,debugger. So, sort of allows you to step through Dialogue: 0,0:03:34.64,0:03:37.25,Default,,0000,0000,0000,,your code, line by line, and better understand\Nhow Dialogue: 0,0:03:37.25,0:03:39.06,Default,,0000,0000,0000,,it works. You can kind of get inside the Dialogue: 0,0:03:39.06,0:03:42.63,Default,,0000,0000,0000,,code, right. I'm not gonna spend too much\Ntime Dialogue: 0,0:03:42.63,0:03:48.37,Default,,0000,0000,0000,,talking about debuggers. Sort of a public\Nservice announcement, Dialogue: 0,0:03:48.37,0:03:51.58,Default,,0000,0000,0000,,next week, not next week. This week. Next\NThursday. Dialogue: 0,0:03:51.58,0:03:55.36,Default,,0000,0000,0000,,This Thursday. In this same room, I believe,\Nis Dialogue: 0,0:03:55.36,0:03:59.70,Default,,0000,0000,0000,,a great talk on debugger-driven development\Nwith Pry. So, Dialogue: 0,0:03:59.70,0:04:01.81,Default,,0000,0000,0000,,if you're interested in hearing more about\Nthat, you Dialogue: 0,0:04:01.81,0:04:03.36,Default,,0000,0000,0000,,should go to that. Dialogue: 0,0:04:03.36,0:04:07.21,Default,,0000,0000,0000,,So, what do we do when our code is Dialogue: 0,0:04:07.21,0:04:11.05,Default,,0000,0000,0000,,slow? What's the tool for that, right? We\Nhave Dialogue: 0,0:04:11.05,0:04:14.46,Default,,0000,0000,0000,,profilers that tell us where time is being\Nspent Dialogue: 0,0:04:14.46,0:04:17.16,Default,,0000,0000,0000,,when we execute our code. And I wouldn't even Dialogue: 0,0:04:17.16,0:04:20.75,Default,,0000,0000,0000,,know how to start optimizing the program if\NI Dialogue: 0,0:04:20.75,0:04:22.99,Default,,0000,0000,0000,,didn't have a profile, right, profiler. I\Nwould be Dialogue: 0,0:04:22.99,0:04:26.57,Default,,0000,0000,0000,,a terrible optimizer without a profiler. I\Nguess I Dialogue: 0,0:04:26.57,0:04:30.36,Default,,0000,0000,0000,,would like start putting in, you know, t equals Dialogue: 0,0:04:30.36,0:04:33.08,Default,,0000,0000,0000,,time dot now, and then, like, at the end Dialogue: 0,0:04:33.08,0:04:36.25,Default,,0000,0000,0000,,of whatever I wanted to measure, I would subtract Dialogue: 0,0:04:36.25,0:04:39.57,Default,,0000,0000,0000,,the current time from the start time. But,\Nthat's Dialogue: 0,0:04:39.57,0:04:42.65,Default,,0000,0000,0000,,crazy. Like, instrumenting your entire code\Nthat way is, Dialogue: 0,0:04:42.65,0:04:46.65,Default,,0000,0000,0000,,yeah. Like, I wouldn't really know how to\Noptimize Dialogue: 0,0:04:46.65,0:04:48.59,Default,,0000,0000,0000,,code without a profiler. I wouldn't be as\Ngood Dialogue: 0,0:04:48.59,0:04:51.59,Default,,0000,0000,0000,,at it. None of us would be. Dialogue: 0,0:04:51.59,0:04:57.49,Default,,0000,0000,0000,,And another sort of tool that is very prevalent Dialogue: 0,0:04:57.49,0:05:00.53,Default,,0000,0000,0000,,in the, in the Ruby community is testing.\NThis Dialogue: 0,0:05:00.53,0:05:02.81,Default,,0000,0000,0000,,is an example of someone who should have done Dialogue: 0,0:05:02.81,0:05:09.81,Default,,0000,0000,0000,,more testing. So that, again, just. Yeah.\NAll right. Dialogue: 0,0:05:11.72,0:05:15.06,Default,,0000,0000,0000,,So I think this is a good illustration of Dialogue: 0,0:05:15.06,0:05:19.59,Default,,0000,0000,0000,,how testing can save you, right. Test so that Dialogue: 0,0:05:19.59,0:05:22.31,Default,,0000,0000,0000,,you find out before you sort of run it Dialogue: 0,0:05:22.31,0:05:24.16,Default,,0000,0000,0000,,in production. OK. Dialogue: 0,0:05:24.16,0:05:26.00,Default,,0000,0000,0000,,Enough of that. Dialogue: 0,0:05:26.00,0:05:28.06,Default,,0000,0000,0000,,So, I would, I'm actually gonna make the case Dialogue: 0,0:05:28.06,0:05:30.78,Default,,0000,0000,0000,,that, in the Ruby, Ruby toolbox, or maybe\Nin Dialogue: 0,0:05:30.78,0:05:33.70,Default,,0000,0000,0000,,the Rubyist's toolbox, tests are sort of like\Nthe Dialogue: 0,0:05:33.70,0:05:35.45,Default,,0000,0000,0000,,hammer, right. Like, this is the thing you\Nturn Dialogue: 0,0:05:35.45,0:05:38.74,Default,,0000,0000,0000,,to all the time for all sorts of things. Dialogue: 0,0:05:38.74,0:05:41.97,Default,,0000,0000,0000,,We use them to prevent regressions. We use\Nthem Dialogue: 0,0:05:41.97,0:05:45.20,Default,,0000,0000,0000,,to specify behavior. And we actually use them\Nto Dialogue: 0,0:05:45.20,0:05:50.49,Default,,0000,0000,0000,,drive development. DHH doesn't do this, but\Nmany others Dialogue: 0,0:05:50.49,0:05:52.83,Default,,0000,0000,0000,,do. And find it useful. Dialogue: 0,0:05:52.83,0:05:57.31,Default,,0000,0000,0000,,So if we write tests, then we have perfect Dialogue: 0,0:05:57.31,0:06:00.25,Default,,0000,0000,0000,,code, right. If we have tests that verify\Nthat Dialogue: 0,0:06:00.25,0:06:02.88,Default,,0000,0000,0000,,our code does what it's supposed to do, then Dialogue: 0,0:06:02.88,0:06:05.05,Default,,0000,0000,0000,,at the end of the day, we have perfect Dialogue: 0,0:06:05.05,0:06:09.73,Default,,0000,0000,0000,,code. Correct? Not correct. Dialogue: 0,0:06:09.73,0:06:13.33,Default,,0000,0000,0000,,This is the fundamental logical flaw with\Ntesting, right. Dialogue: 0,0:06:13.33,0:06:17.39,Default,,0000,0000,0000,,You have some code. And you know that code Dialogue: 0,0:06:17.39,0:06:19.49,Default,,0000,0000,0000,,can have bugs. So you say I have an Dialogue: 0,0:06:19.49,0:06:23.14,Default,,0000,0000,0000,,idea, let's write some tests. But tests are\Njust Dialogue: 0,0:06:23.14,0:06:26.58,Default,,0000,0000,0000,,more code. And we know that code has bugs. Dialogue: 0,0:06:26.58,0:06:29.00,Default,,0000,0000,0000,,So we're screwed. Dialogue: 0,0:06:29.00,0:06:31.43,Default,,0000,0000,0000,,What's that? Dialogue: 0,0:06:31.43,0:06:35.67,Default,,0000,0000,0000,,Test your tests. That's right. So. I'm getting\Nthere. Dialogue: 0,0:06:35.67,0:06:36.49,Default,,0000,0000,0000,,Patience. Dialogue: 0,0:06:36.49,0:06:40.47,Default,,0000,0000,0000,,So, like, one tool that people use to sort Dialogue: 0,0:06:40.47,0:06:43.39,Default,,0000,0000,0000,,of measure the effectiveness of their tests\Nis code Dialogue: 0,0:06:43.39,0:06:49.62,Default,,0000,0000,0000,,coverage. And it's sort of a metric that's\Ndesigned Dialogue: 0,0:06:49.62,0:06:52.19,Default,,0000,0000,0000,,to tell you whether your tests do what they're Dialogue: 0,0:06:52.19,0:06:55.69,Default,,0000,0000,0000,,supposed to do. But I'll show you, in a Dialogue: 0,0:06:55.69,0:06:58.11,Default,,0000,0000,0000,,moment, why I think it's a really flawed metric Dialogue: 0,0:06:58.11,0:06:59.75,Default,,0000,0000,0000,,and why it sort of can give you a Dialogue: 0,0:06:59.75,0:07:03.27,Default,,0000,0000,0000,,false sense of security, right. A lot of people Dialogue: 0,0:07:03.27,0:07:07.18,Default,,0000,0000,0000,,think that they have 100% code coverage, and\Nthat Dialogue: 0,0:07:07.18,0:07:09.11,Default,,0000,0000,0000,,means, like, their code is perfect and bug-free.\NOr Dialogue: 0,0:07:09.11,0:07:10.92,Default,,0000,0000,0000,,if they reach that level, then their code\Nwill Dialogue: 0,0:07:10.92,0:07:13.90,Default,,0000,0000,0000,,be perfect and bug-free. But this is not true. Dialogue: 0,0:07:13.90,0:07:17.03,Default,,0000,0000,0000,,Right, like, this guy thinks he's covered\Nand he's Dialogue: 0,0:07:17.03,0:07:18.11,Default,,0000,0000,0000,,not. Dialogue: 0,0:07:18.11,0:07:20.64,Default,,0000,0000,0000,,And code coverage is actually, like, it's\Nsomething that Dialogue: 0,0:07:20.64,0:07:23.60,Default,,0000,0000,0000,,was built into Ruby, right. Like, in Ruby\N1.9.3, Dialogue: 0,0:07:23.60,0:07:25.92,Default,,0000,0000,0000,,this is something that, like, we as a programmer Dialogue: 0,0:07:25.92,0:07:28.28,Default,,0000,0000,0000,,community said, like, we want to have. And\NI'm Dialogue: 0,0:07:28.28,0:07:30.51,Default,,0000,0000,0000,,not against it. Like, I think it's good. But Dialogue: 0,0:07:30.51,0:07:32.76,Default,,0000,0000,0000,,I do think it can give you a false Dialogue: 0,0:07:32.76,0:07:34.25,Default,,0000,0000,0000,,sense of security, right. Dialogue: 0,0:07:34.25,0:07:37.72,Default,,0000,0000,0000,,I thought this was a funny Tweet. Dialogue: 0,0:07:37.72,0:07:42.81,Default,,0000,0000,0000,,So, you can have 100% code coverage and still Dialogue: 0,0:07:42.81,0:07:49.81,Default,,0000,0000,0000,,have completely bug-ridden code. So, so is\Nthere hope Dialogue: 0,0:07:50.99,0:07:54.19,Default,,0000,0000,0000,,for us? Right? Like, how do we, how do Dialogue: 0,0:07:54.19,0:07:56.96,Default,,0000,0000,0000,,we test our tests? It's sort of this problem Dialogue: 0,0:07:56.96,0:07:59.61,Default,,0000,0000,0000,,of, like, who will watch the watchers, right?\NWho Dialogue: 0,0:07:59.61,0:08:01.68,Default,,0000,0000,0000,,do we, who can we trust? If we can't Dialogue: 0,0:08:01.68,0:08:04.50,Default,,0000,0000,0000,,trust our tests, how, why, why are we even Dialogue: 0,0:08:04.50,0:08:05.93,Default,,0000,0000,0000,,writing them? Dialogue: 0,0:08:05.93,0:08:07.93,Default,,0000,0000,0000,,And I'm gonna try to make the case that Dialogue: 0,0:08:07.93,0:08:12.26,Default,,0000,0000,0000,,mutation testing is the sort of solution to\Nthis Dialogue: 0,0:08:12.26,0:08:17.84,Default,,0000,0000,0000,,problem. So just like everything else, like\Nan editor, Dialogue: 0,0:08:17.84,0:08:22.04,Default,,0000,0000,0000,,like an interactive debugger, like a profiler,\Nlike tests, Dialogue: 0,0:08:22.04,0:08:26.05,Default,,0000,0000,0000,,mutation testing is a tool. The basic idea\Nbehind Dialogue: 0,0:08:26.05,0:08:28.08,Default,,0000,0000,0000,,it is that it takes your tests and it Dialogue: 0,0:08:28.08,0:08:31.76,Default,,0000,0000,0000,,runs them against your code, and they should\Npass. Dialogue: 0,0:08:31.76,0:08:33.33,Default,,0000,0000,0000,,And if they do pass, then what it does, Dialogue: 0,0:08:33.33,0:08:35.32,Default,,0000,0000,0000,,is it takes your code and it makes a Dialogue: 0,0:08:35.32,0:08:38.88,Default,,0000,0000,0000,,modification to your code. It actually changes\Nyour code Dialogue: 0,0:08:38.88,0:08:42.53,Default,,0000,0000,0000,,at runtime. And then it runs your tests again, Dialogue: 0,0:08:42.53,0:08:45.67,Default,,0000,0000,0000,,against the modified version of your code.\NAnd the Dialogue: 0,0:08:45.67,0:08:48.33,Default,,0000,0000,0000,,idea is that when that code is modified, the Dialogue: 0,0:08:48.33,0:08:52.13,Default,,0000,0000,0000,,tests that previously passed should now fail,\Nright. Dialogue: 0,0:08:52.13,0:08:55.12,Default,,0000,0000,0000,,So the thing, your modified code is called\Na Dialogue: 0,0:08:55.12,0:08:57.49,Default,,0000,0000,0000,,mutant, and the idea is that if that test Dialogue: 0,0:08:57.49,0:09:00.54,Default,,0000,0000,0000,,fails, you kill the mutant. Right. The mutant\Ndies. Dialogue: 0,0:09:00.54,0:09:02.86,Default,,0000,0000,0000,,But if that mutant survives, then that means\Nthere's Dialogue: 0,0:09:02.86,0:09:05.19,Default,,0000,0000,0000,,something wrong with your tests. There might\Nnot be Dialogue: 0,0:09:05.19,0:09:07.31,Default,,0000,0000,0000,,something wrong with your code. But there\Nis certainly Dialogue: 0,0:09:07.31,0:09:09.64,Default,,0000,0000,0000,,something wrong with your tests. Either you\Nhave a Dialogue: 0,0:09:09.64,0:09:12.48,Default,,0000,0000,0000,,bug in your tests. You have missing tests.\NYour Dialogue: 0,0:09:12.48,0:09:16.62,Default,,0000,0000,0000,,tests are either over-specified or under-specified. Dialogue: 0,0:09:16.62,0:09:18.80,Default,,0000,0000,0000,,So this is a technique, it's very helpful\Nfor Dialogue: 0,0:09:18.80,0:09:21.58,Default,,0000,0000,0000,,sort of answering the question, what tests\Nshould I Dialogue: 0,0:09:21.58,0:09:24.62,Default,,0000,0000,0000,,write? Which I think is a question that many Dialogue: 0,0:09:24.62,0:09:27.51,Default,,0000,0000,0000,,of us struggle with. It's certainly something\Nthat beginners Dialogue: 0,0:09:27.51,0:09:29.86,Default,,0000,0000,0000,,struggle with when they're starting to program.\NLike, how Dialogue: 0,0:09:29.86,0:09:32.69,Default,,0000,0000,0000,,do I, how do I write tests? What, what Dialogue: 0,0:09:32.69,0:09:34.92,Default,,0000,0000,0000,,do I test? Right. Dialogue: 0,0:09:34.92,0:09:36.53,Default,,0000,0000,0000,,And then there's also this question of like,\Nhow Dialogue: 0,0:09:36.53,0:09:38.80,Default,,0000,0000,0000,,do I know when I'm done? How do I Dialogue: 0,0:09:38.80,0:09:42.49,Default,,0000,0000,0000,,know when the code is sufficiently tested?\NAnd I Dialogue: 0,0:09:42.49,0:09:45.84,Default,,0000,0000,0000,,think these are actually hard questions to\Nask, or Dialogue: 0,0:09:45.84,0:09:51.04,Default,,0000,0000,0000,,hard questions to answer, and mutation, mutation\Ntesting provides Dialogue: 0,0:09:51.04,0:09:54.34,Default,,0000,0000,0000,,a, a quantitative answer to those questions.\NYou can Dialogue: 0,0:09:54.34,0:09:59.38,Default,,0000,0000,0000,,say, with confidence, that this code has 100%\Nmutation Dialogue: 0,0:09:59.38,0:10:02.45,Default,,0000,0000,0000,,coverage. Dialogue: 0,0:10:02.45,0:10:09.26,Default,,0000,0000,0000,,So, just to sort of give an example, here Dialogue: 0,0:10:09.26,0:10:13.82,Default,,0000,0000,0000,,is some code. And an assertion about the code. Dialogue: 0,0:10:13.82,0:10:16.60,Default,,0000,0000,0000,,So, I have a method, foo. It takes an Dialogue: 0,0:10:16.60,0:10:20.94,Default,,0000,0000,0000,,argument whose default is true. And the actual\Nmethod Dialogue: 0,0:10:20.94,0:10:26.44,Default,,0000,0000,0000,,body for foo is either return that argument\Nor Dialogue: 0,0:10:26.44,0:10:33.09,Default,,0000,0000,0000,,fail. And my assertion says assert_nothing_raised\Nif I call Dialogue: 0,0:10:33.09,0:10:37.94,Default,,0000,0000,0000,,the method foo without passing in any parameters. Dialogue: 0,0:10:37.94,0:10:40.48,Default,,0000,0000,0000,,And so, or without passing in any arguments\Nto Dialogue: 0,0:10:40.48,0:10:47.48,Default,,0000,0000,0000,,the, our parameter, rather. And so what, you\Nknow, Dialogue: 0,0:10:48.07,0:10:52.43,Default,,0000,0000,0000,,this test will pass, right. Arg. You call\Nfoo. Dialogue: 0,0:10:52.43,0:10:55.42,Default,,0000,0000,0000,,Arg is true. And it sort of short-circuits,\Nright. Dialogue: 0,0:10:55.42,0:10:59.56,Default,,0000,0000,0000,,It sees arg. It sees the or. And this Dialogue: 0,0:10:59.56,0:11:02.86,Default,,0000,0000,0000,,test passes. So maybe you think this is a Dialogue: 0,0:11:02.86,0:11:05.55,Default,,0000,0000,0000,,good test. Maybe you think you're done writing\Nyour Dialogue: 0,0:11:05.55,0:11:08.41,Default,,0000,0000,0000,,tests. But you are not. Dialogue: 0,0:11:08.41,0:11:11.07,Default,,0000,0000,0000,,And a mutant of that code, a small modification, Dialogue: 0,0:11:11.07,0:11:13.83,Default,,0000,0000,0000,,a sort of unit modification of that code might Dialogue: 0,0:11:13.83,0:11:17.22,Default,,0000,0000,0000,,look like this. And basically what it did\Nwas Dialogue: 0,0:11:17.22,0:11:19.44,Default,,0000,0000,0000,,it just sort of took that or fail and Dialogue: 0,0:11:19.44,0:11:21.91,Default,,0000,0000,0000,,removed it. And the idea is like, if you Dialogue: 0,0:11:21.91,0:11:25.13,Default,,0000,0000,0000,,do that, at least one of your tests should Dialogue: 0,0:11:25.13,0:11:27.59,Default,,0000,0000,0000,,now, that was passing before, should now fail.\NOne Dialogue: 0,0:11:27.59,0:11:30.20,Default,,0000,0000,0000,,of your tests over that code, for that foo Dialogue: 0,0:11:30.20,0:11:33.60,Default,,0000,0000,0000,,method, should now fail. And if it does not, Dialogue: 0,0:11:33.60,0:11:37.70,Default,,0000,0000,0000,,then you are not testing your code sufficiently. Dialogue: 0,0:11:37.70,0:11:42.34,Default,,0000,0000,0000,,So, this is called a statement deletion mutation.\NThere Dialogue: 0,0:11:42.34,0:11:46.67,Default,,0000,0000,0000,,are various other types of mutation. So, for\Nexample, Dialogue: 0,0:11:46.67,0:11:49.82,Default,,0000,0000,0000,,there are mutations that would take that default\Nparameter Dialogue: 0,0:11:49.82,0:11:52.15,Default,,0000,0000,0000,,and change it from true to false, or from Dialogue: 0,0:11:52.15,0:11:56.32,Default,,0000,0000,0000,,true to nil, right. Which would also cause\Nfailure, Dialogue: 0,0:11:56.32,0:11:58.97,Default,,0000,0000,0000,,in this case. Dialogue: 0,0:11:58.97,0:12:01.29,Default,,0000,0000,0000,,There's another mutation that will take the\Nor and Dialogue: 0,0:12:01.29,0:12:04.54,Default,,0000,0000,0000,,change it to an and, right. So any time Dialogue: 0,0:12:04.54,0:12:07.52,Default,,0000,0000,0000,,there is sort of a unit in your code, Dialogue: 0,0:12:07.52,0:12:10.05,Default,,0000,0000,0000,,it takes greater than signs and changes them\Nto Dialogue: 0,0:12:10.05,0:12:12.95,Default,,0000,0000,0000,,less than or equal to signs, et cetera. Right. Dialogue: 0,0:12:12.95,0:12:15.82,Default,,0000,0000,0000,,It takes ifs and changes them to unless. It Dialogue: 0,0:12:15.82,0:12:18.18,Default,,0000,0000,0000,,will take whole expressions and negate them\Nand make Dialogue: 0,0:12:18.18,0:12:21.14,Default,,0000,0000,0000,,sure that your tests fail when the negation\Nof Dialogue: 0,0:12:21.14,0:12:25.34,Default,,0000,0000,0000,,a statement is, when, when the method returns\Nthe Dialogue: 0,0:12:25.34,0:12:28.43,Default,,0000,0000,0000,,negation of the statement instead of the statement,\Nright. Dialogue: 0,0:12:28.43,0:12:30.66,Default,,0000,0000,0000,,So that's, that's sort of the core idea behind Dialogue: 0,0:12:30.66,0:12:34.04,Default,,0000,0000,0000,,mutation testing. And so you end up sort of Dialogue: 0,0:12:34.04,0:12:37.50,Default,,0000,0000,0000,,writing these tests to cover all these cases\Nthat, Dialogue: 0,0:12:37.50,0:12:39.84,Default,,0000,0000,0000,,and then you sort of know when you're done, Dialogue: 0,0:12:39.84,0:12:42.59,Default,,0000,0000,0000,,right. Like, you know when all of your tests, Dialogue: 0,0:12:42.59,0:12:46.86,Default,,0000,0000,0000,,when, when your code is fully mutation-covered. Dialogue: 0,0:12:46.86,0:12:51.50,Default,,0000,0000,0000,,This is another Tweet. It's one from Katrina\NOwen. Dialogue: 0,0:12:51.50,0:12:53.84,Default,,0000,0000,0000,,And it's sort of this idea, it's kind of Dialogue: 0,0:12:53.84,0:12:56.71,Default,,0000,0000,0000,,like both horrifying and satisfying at the\Nsame time. Dialogue: 0,0:12:56.71,0:12:59.36,Default,,0000,0000,0000,,But if you sort of add more granular tests, Dialogue: 0,0:12:59.36,0:13:03.14,Default,,0000,0000,0000,,you'll find more bugs. And in many cases,\Nmutant, Dialogue: 0,0:13:03.14,0:13:05.35,Default,,0000,0000,0000,,which is a mutation testing framework, will\Nfind those Dialogue: 0,0:13:05.35,0:13:07.94,Default,,0000,0000,0000,,bugs for you. Right. That's cool. Dialogue: 0,0:13:07.94,0:13:10.35,Default,,0000,0000,0000,,OK. So I promised there would be live-coding.\NThis Dialogue: 0,0:13:10.35,0:13:13.56,Default,,0000,0000,0000,,is sort of. The introduction is over and now Dialogue: 0,0:13:13.56,0:13:17.07,Default,,0000,0000,0000,,we will write some code. Hopefully. Dialogue: 0,0:13:17.07,0:13:24.07,Default,,0000,0000,0000,,I'm just gonna switch to mirror display. Command\NF1. Dialogue: 0,0:13:32.95,0:13:36.87,Default,,0000,0000,0000,,That is a protip. That's great. You're a pro. Dialogue: 0,0:13:36.87,0:13:41.43,Default,,0000,0000,0000,,I clearly am not. OK. Cool. Dialogue: 0,0:13:41.43,0:13:44.46,Default,,0000,0000,0000,,Cool. And a new version of mutant was, like, Dialogue: 0,0:13:44.46,0:13:48.65,Default,,0000,0000,0000,,just released a few minutes ago, in advance\Nof Dialogue: 0,0:13:48.65,0:13:53.39,Default,,0000,0000,0000,,this presentation. I am not the author of\Nmutant. Dialogue: 0,0:13:53.39,0:13:56.57,Default,,0000,0000,0000,,It's a great library by Markus Schirp, and\NI Dialogue: 0,0:13:56.57,0:13:59.74,Default,,0000,0000,0000,,encourage you all to check it out. Version\Nzero Dialogue: 0,0:13:59.74,0:14:03.17,Default,,0000,0000,0000,,dot five dot eleven, hot off the presses. Dialogue: 0,0:14:03.17,0:14:07.89,Default,,0000,0000,0000,,So this is some code. So, like, the, this Dialogue: 0,0:14:07.89,0:14:10.58,Default,,0000,0000,0000,,sort of thrust behind this live-coding demo\Nis I Dialogue: 0,0:14:10.58,0:14:13.33,Default,,0000,0000,0000,,will not be live-coding code, I will be live-coding Dialogue: 0,0:14:13.33,0:14:16.69,Default,,0000,0000,0000,,tests. Because the idea is not to, like, mutant Dialogue: 0,0:14:16.69,0:14:18.90,Default,,0000,0000,0000,,doesn't verify that your code is correct.\NIt verifies Dialogue: 0,0:14:18.90,0:14:20.57,Default,,0000,0000,0000,,that your tests are correct. So you still\Nneed Dialogue: 0,0:14:20.57,0:14:23.42,Default,,0000,0000,0000,,to write tests, right. Tests verify that your\Ncode Dialogue: 0,0:14:23.42,0:14:26.13,Default,,0000,0000,0000,,is correct. Mutant verifies that your tests\Nare correct. Dialogue: 0,0:14:26.13,0:14:28.70,Default,,0000,0000,0000,,So this is the code. And it's pretty, pretty Dialogue: 0,0:14:28.70,0:14:32.55,Default,,0000,0000,0000,,simple. But we'll sort of walk through it\Nline-by-line. Dialogue: 0,0:14:32.55,0:14:34.24,Default,,0000,0000,0000,,Just to make sure everyone has a good understanding Dialogue: 0,0:14:34.24,0:14:39.19,Default,,0000,0000,0000,,of it. And so there's this module that represents Dialogue: 0,0:14:39.19,0:14:42.84,Default,,0000,0000,0000,,the universe, the entire universe, and inside\Nof the Dialogue: 0,0:14:42.84,0:14:45.14,Default,,0000,0000,0000,,universe we have planets. And that's what\Nthis class Dialogue: 0,0:14:45.14,0:14:49.14,Default,,0000,0000,0000,,is all about. It's a pretty simple planet.\NIt Dialogue: 0,0:14:49.14,0:14:54.92,Default,,0000,0000,0000,,takes a radius and an area as parameters when Dialogue: 0,0:14:54.92,0:14:59.04,Default,,0000,0000,0000,,it's constructed and stores those in instance\Nvariables. The Dialogue: 0,0:14:59.04,0:15:02.62,Default,,0000,0000,0000,,radius is the mean radius of the planet and, Dialogue: 0,0:15:02.62,0:15:05.74,Default,,0000,0000,0000,,in kilometers, and the area is sort of surface Dialogue: 0,0:15:05.74,0:15:10.30,Default,,0000,0000,0000,,area of the planet in square kilometers. Dialogue: 0,0:15:10.30,0:15:13.63,Default,,0000,0000,0000,,And then there's one sort of interesting method,\None Dialogue: 0,0:15:13.63,0:15:20.63,Default,,0000,0000,0000,,public method, spherical. And spherical will\Nreturn true if, Dialogue: 0,0:15:22.54,0:15:26.34,Default,,0000,0000,0000,,if the planet is a perfect sphere, or within Dialogue: 0,0:15:26.34,0:15:29.13,Default,,0000,0000,0000,,a particular tolerance of that. So the idea\Nis Dialogue: 0,0:15:29.13,0:15:32.65,Default,,0000,0000,0000,,we calculate the approximate area using four\Npi r Dialogue: 0,0:15:32.65,0:15:37.13,Default,,0000,0000,0000,,squared, which is the formula to calculate\Nthe area Dialogue: 0,0:15:37.13,0:15:43.84,Default,,0000,0000,0000,,of a sphere, and if the area sort of Dialogue: 0,0:15:43.84,0:15:47.03,Default,,0000,0000,0000,,matches that, then we know it's a sphere.\NWe Dialogue: 0,0:15:47.03,0:15:50.48,Default,,0000,0000,0000,,know it's spherical. This method returns true. Dialogue: 0,0:15:50.48,0:15:53.48,Default,,0000,0000,0000,,And if, if that's not true, then the planet Dialogue: 0,0:15:53.48,0:15:56.90,Default,,0000,0000,0000,,is not spherical. It's either oblate, like\Nthe earth, Dialogue: 0,0:15:56.90,0:16:02.11,Default,,0000,0000,0000,,or prolate, and then this method will return\Nfalse. Dialogue: 0,0:16:02.11,0:16:04.39,Default,,0000,0000,0000,,So, yeah. We just sort of calculate the approximate Dialogue: 0,0:16:04.39,0:16:07.11,Default,,0000,0000,0000,,area and then we have this ranged private\Nmethod Dialogue: 0,0:16:07.11,0:16:10.10,Default,,0000,0000,0000,,that just generates a range. We need sort\Na Dialogue: 0,0:16:10.10,0:16:12.07,Default,,0000,0000,0000,,tolerance. The idea is you don't want it to Dialogue: 0,0:16:12.07,0:16:16.90,Default,,0000,0000,0000,,be too precise, because we're dealing with\Npi, so Dialogue: 0,0:16:16.90,0:16:22.75,Default,,0000,0000,0000,,pi is, I mean, in actuality, it's a non-terminating Dialogue: 0,0:16:22.75,0:16:26.63,Default,,0000,0000,0000,,number. In Ruby, it has, like, ten digits\Nof Dialogue: 0,0:16:26.63,0:16:28.84,Default,,0000,0000,0000,,precision or something like that, right. Like\Nthe constant Dialogue: 0,0:16:28.84,0:16:29.74,Default,,0000,0000,0000,,map pi. Dialogue: 0,0:16:29.74,0:16:33.11,Default,,0000,0000,0000,,But the idea is that, like, if it's close Dialogue: 0,0:16:33.11,0:16:35.59,Default,,0000,0000,0000,,enough to a sphere, within a particular tolerance,\Nthen Dialogue: 0,0:16:35.59,0:16:39.62,Default,,0000,0000,0000,,we'll just call it round, basically. And so\Nwe Dialogue: 0,0:16:39.62,0:16:43.51,Default,,0000,0000,0000,,generate this range, which is sort of the\Napproximate Dialogue: 0,0:16:43.51,0:16:46.72,Default,,0000,0000,0000,,area that we've calculated, based on the radius\Nplus Dialogue: 0,0:16:46.72,0:16:49.47,Default,,0000,0000,0000,,or minus the tolerance, and we see if the Dialogue: 0,0:16:49.47,0:16:53.16,Default,,0000,0000,0000,,area falls within those bounds. Does everyone\Nunderstand this Dialogue: 0,0:16:53.16,0:16:55.69,Default,,0000,0000,0000,,code? I think it is pretty simple. I tried Dialogue: 0,0:16:55.69,0:16:58.11,Default,,0000,0000,0000,,to make it fit on one screen. On one Dialogue: 0,0:16:58.11,0:16:59.46,Default,,0000,0000,0000,,slide. Dialogue: 0,0:16:59.46,0:17:00.81,Default,,0000,0000,0000,,Yeah? Dialogue: 0,0:17:00.81,0:17:05.22,Default,,0000,0000,0000,,OK. So if everyone understands it, I want\Nto Dialogue: 0,0:17:05.22,0:17:06.53,Default,,0000,0000,0000,,take a little bit of a poll. This is Dialogue: 0,0:17:06.53,0:17:08.55,Default,,0000,0000,0000,,kind of like the interactive part of the talk. Dialogue: 0,0:17:08.55,0:17:10.85,Default,,0000,0000,0000,,And you have to, like, everyone has to participate. Dialogue: 0,0:17:10.85,0:17:14.83,Default,,0000,0000,0000,,That's the, that's the goal. Everyone, people\Nlike to Dialogue: 0,0:17:14.83,0:17:17.03,Default,,0000,0000,0000,,sort of sit by the sidelines and not commit, Dialogue: 0,0:17:17.03,0:17:19.34,Default,,0000,0000,0000,,but you have to commit. I'll be really angry Dialogue: 0,0:17:19.34,0:17:22.54,Default,,0000,0000,0000,,if you don't. Dialogue: 0,0:17:22.54,0:17:26.23,Default,,0000,0000,0000,,You don't want to see me angry. Dialogue: 0,0:17:26.23,0:17:28.95,Default,,0000,0000,0000,,So how many tests do you think you need Dialogue: 0,0:17:28.95,0:17:34.65,Default,,0000,0000,0000,,to fully cover this code? To cover the public Dialogue: 0,0:17:34.65,0:17:38.67,Default,,0000,0000,0000,,method, the, the spherical method, right,\Nso that it's Dialogue: 0,0:17:38.67,0:17:41.75,Default,,0000,0000,0000,,sort of fully exercised. Who thinks you need\Nzero Dialogue: 0,0:17:41.75,0:17:48.75,Default,,0000,0000,0000,,tests? Show of hands? Anybody? No. Good. I\Nagree. Dialogue: 0,0:17:48.89,0:17:52.27,Default,,0000,0000,0000,,You can't cover code without tests. So, that's\Ngood. Dialogue: 0,0:17:52.27,0:17:53.68,Default,,0000,0000,0000,,You've been paying some attention. Dialogue: 0,0:17:53.68,0:17:56.62,Default,,0000,0000,0000,,Who thinks you can do it with one test? Dialogue: 0,0:17:56.62,0:17:59.67,Default,,0000,0000,0000,,Maybe, sort of, the happy path? Right. You\Nwrite Dialogue: 0,0:17:59.67,0:18:04.37,Default,,0000,0000,0000,,a test that says, you know, you expect some Dialogue: 0,0:18:04.37,0:18:08.64,Default,,0000,0000,0000,,planet to be spherical given radius and an\Narea, Dialogue: 0,0:18:08.64,0:18:15.64,Default,,0000,0000,0000,,and it is. All good. Who thinks that's sufficient? Dialogue: 0,0:18:17.55,0:18:19.79,Default,,0000,0000,0000,,Nobody. So. Dialogue: 0,0:18:19.79,0:18:23.70,Default,,0000,0000,0000,,You can actually get C-zero, 100% C-zero code\Ncoverage Dialogue: 0,0:18:23.70,0:18:26.90,Default,,0000,0000,0000,,of this entire class with one test. With one Dialogue: 0,0:18:26.90,0:18:31.43,Default,,0000,0000,0000,,spec. Right. You won't have 100% mutation\Ncoverage, but Dialogue: 0,0:18:31.43,0:18:32.81,Default,,0000,0000,0000,,I will show you, in a minute, you can Dialogue: 0,0:18:32.81,0:18:36.27,Default,,0000,0000,0000,,have 100% C-zero code coverage, despite the\Nfact that Dialogue: 0,0:18:36.27,0:18:38.67,Default,,0000,0000,0000,,nobody in this room thinks that that is sufficient Dialogue: 0,0:18:38.67,0:18:41.65,Default,,0000,0000,0000,,to cover this code. So. I will prove it Dialogue: 0,0:18:41.65,0:18:44.26,Default,,0000,0000,0000,,to you. But you all intuitively know this\Nto Dialogue: 0,0:18:44.26,0:18:47.18,Default,,0000,0000,0000,,be the case. And yet we all idolize this Dialogue: 0,0:18:47.18,0:18:50.81,Default,,0000,0000,0000,,C-zero code coverage metric as if it means\Nsomething, Dialogue: 0,0:18:50.81,0:18:54.12,Default,,0000,0000,0000,,when really it, it's a false sense of security, Dialogue: 0,0:18:54.12,0:18:56.42,Default,,0000,0000,0000,,right. You're the guy with the umbrella in\Nthe Dialogue: 0,0:18:56.42,0:18:59.45,Default,,0000,0000,0000,,hurricane, and the umbrella is like destroyed\Nand inside Dialogue: 0,0:18:59.45,0:19:00.64,Default,,0000,0000,0000,,out. Dialogue: 0,0:19:00.64,0:19:04.73,Default,,0000,0000,0000,,OK. So how many people think you can do Dialogue: 0,0:19:04.73,0:19:10.05,Default,,0000,0000,0000,,it with two tests? OK. Somebody who's raising\Nyour Dialogue: 0,0:19:10.05,0:19:12.15,Default,,0000,0000,0000,,hand. This gentleman in the front. What are\Nthe Dialogue: 0,0:19:12.15,0:19:13.50,Default,,0000,0000,0000,,two tests that you would write? Just sort\Nof Dialogue: 0,0:19:13.50,0:19:17.64,Default,,0000,0000,0000,,roughly? Maybe the happy path and what other? Dialogue: 0,0:19:17.64,0:19:20.12,Default,,0000,0000,0000,,AUDIENCE: One that's spherical and one not. Dialogue: 0,0:19:20.12,0:19:21.62,Default,,0000,0000,0000,,E.M.: One that's spherical and one that's\Nnot. OK. Dialogue: 0,0:19:21.62,0:19:24.17,Default,,0000,0000,0000,,I think that's good. How many people think\Nyou Dialogue: 0,0:19:24.17,0:19:27.82,Default,,0000,0000,0000,,would need three to do it? K, maybe gentleman Dialogue: 0,0:19:27.82,0:19:29.58,Default,,0000,0000,0000,,there who thinks we need three. What's the\Nthird Dialogue: 0,0:19:29.58,0:19:32.54,Default,,0000,0000,0000,,you would write? Dialogue: 0,0:19:32.54,0:19:36.64,Default,,0000,0000,0000,,AUDIENCE: [indecipherable - 00:19:41] Dialogue: 0,0:19:36.64,0:19:43.47,Default,,0000,0000,0000,,E.M.: Say it again? A value for tolerance? Dialogue: 0,0:19:43.47,0:19:46.08,Default,,0000,0000,0000,,AUDIENCE: A value that will blow up the computation. Dialogue: 0,0:19:46.08,0:19:46.96,Default,,0000,0000,0000,,E.M.: That will blow up the computation. How\Nwould Dialogue: 0,0:19:46.96,0:19:49.04,Default,,0000,0000,0000,,you blow up the computation? Dialogue: 0,0:19:49.04,0:19:53.86,Default,,0000,0000,0000,,AUDIENCE: [indecipherable - 00:19:55] Dialogue: 0,0:19:53.86,0:19:56.41,Default,,0000,0000,0000,,E.M.: Passing in a string. Dialogue: 0,0:19:56.41,0:19:58.11,Default,,0000,0000,0000,,AUDIENCE: Yes. Dialogue: 0,0:19:58.11,0:20:02.03,Default,,0000,0000,0000,,E.M.: OK. Great. And what would you expect\Nthe Dialogue: 0,0:20:02.03,0:20:04.39,Default,,0000,0000,0000,,result to be, like, what would your expectation,\Nwhat Dialogue: 0,0:20:04.39,0:20:06.38,Default,,0000,0000,0000,,would you assert? Like, I pass in a string Dialogue: 0,0:20:06.38,0:20:08.70,Default,,0000,0000,0000,,and I expect. Dialogue: 0,0:20:08.70,0:20:11.65,Default,,0000,0000,0000,,AUDIENCE: An exception to be raised. Dialogue: 0,0:20:11.65,0:20:12.64,Default,,0000,0000,0000,,E.M.: An exception. OK. And if you didn't\Nget Dialogue: 0,0:20:12.64,0:20:15.84,Default,,0000,0000,0000,,an exception then that would be a problem. Dialogue: 0,0:20:15.84,0:20:17.51,Default,,0000,0000,0000,,AUDIENCE: Yes. Dialogue: 0,0:20:17.51,0:20:24.27,Default,,0000,0000,0000,,E.M.: OK. OK. Who thinks four will do it? Dialogue: 0,0:20:24.27,0:20:26.50,Default,,0000,0000,0000,,Nobody thinks four will do it. A few people Dialogue: 0,0:20:26.50,0:20:33.50,Default,,0000,0000,0000,,do. Yeah. What additional tests would you\Nadd? Dialogue: 0,0:20:33.65,0:20:40.25,Default,,0000,0000,0000,,AUDIENCE: Well, you're testing a range, so\Nyou have- Dialogue: 0,0:20:40.25,0:20:40.29,Default,,0000,0000,0000,,E.M.: Hmm. Great. Dialogue: 0,0:20:40.29,0:20:40.37,Default,,0000,0000,0000,,AUDIENCE: -so there's two sides. Dialogue: 0,0:20:40.37,0:20:41.01,Default,,0000,0000,0000,,E.M.: I really like this. So, the comment\Nwas Dialogue: 0,0:20:41.01,0:20:43.07,Default,,0000,0000,0000,,that you're testing a range, and there's sort\Nof Dialogue: 0,0:20:43.07,0:20:45.18,Default,,0000,0000,0000,,two sides. There's the, I'm on the low-end\Nof Dialogue: 0,0:20:45.18,0:20:46.68,Default,,0000,0000,0000,,the range and I am included, and I am Dialogue: 0,0:20:46.68,0:20:49.60,Default,,0000,0000,0000,,on the high-end of the range. So it would Dialogue: 0,0:20:49.60,0:20:52.80,Default,,0000,0000,0000,,be, there's two of those. Right. One for the Dialogue: 0,0:20:52.80,0:20:54.15,Default,,0000,0000,0000,,low-end and one for the high-end. Exactly. Dialogue: 0,0:20:54.15,0:20:56.95,Default,,0000,0000,0000,,So, it's sort of the happy path. The thing Dialogue: 0,0:20:56.95,0:20:59.77,Default,,0000,0000,0000,,is spherical. The sad path, the thing is not Dialogue: 0,0:20:59.77,0:21:04.58,Default,,0000,0000,0000,,spherical. And both sides of the range. I\Nlike Dialogue: 0,0:21:04.58,0:21:08.26,Default,,0000,0000,0000,,that. Good. How many people think five? Five\Nor Dialogue: 0,0:21:08.26,0:21:11.08,Default,,0000,0000,0000,,more? How's that? Five or more. OK. Lots of Dialogue: 0,0:21:11.08,0:21:12.98,Default,,0000,0000,0000,,hands for five or more. Dialogue: 0,0:21:12.98,0:21:19.59,Default,,0000,0000,0000,,So, according to mutant, which is also software,\Ntherefore Dialogue: 0,0:21:19.59,0:21:23.18,Default,,0000,0000,0000,,imperfect, you can, you can test this with\Nfour, Dialogue: 0,0:21:23.18,0:21:25.79,Default,,0000,0000,0000,,and it will not handle things like you should, Dialogue: 0,0:21:25.79,0:21:29.28,Default,,0000,0000,0000,,like, it sort of assumes that the radius and Dialogue: 0,0:21:29.28,0:21:33.84,Default,,0000,0000,0000,,area are valid, right. Like, you can, although,\Nactually, Dialogue: 0,0:21:33.84,0:21:36.19,Default,,0000,0000,0000,,maybe that's. Well, we can try it. It's a Dialogue: 0,0:21:36.19,0:21:37.85,Default,,0000,0000,0000,,live coding thing. So let's just do it and Dialogue: 0,0:21:37.85,0:21:41.31,Default,,0000,0000,0000,,see what happens. But thank you for participating\Nin Dialogue: 0,0:21:41.31,0:21:43.52,Default,,0000,0000,0000,,that. I think it was an interesting exercise. Dialogue: 0,0:21:43.52,0:21:47.17,Default,,0000,0000,0000,,But, yeah. Basically, like, mutant says the\Nanswer to Dialogue: 0,0:21:47.17,0:21:50.17,Default,,0000,0000,0000,,this question is four, right. It's basically\Nthe happy Dialogue: 0,0:21:50.17,0:21:52.28,Default,,0000,0000,0000,,path, the sad path, and both sides of the Dialogue: 0,0:21:52.28,0:21:57.65,Default,,0000,0000,0000,,range. So yeah. Let's, let's sort of show\Nhow Dialogue: 0,0:21:57.65,0:22:00.98,Default,,0000,0000,0000,,that works. Dialogue: 0,0:22:00.98,0:22:07.72,Default,,0000,0000,0000,,OK. So I'm gonna start by just making a Dialogue: 0,0:22:07.72,0:22:10.42,Default,,0000,0000,0000,,gemfile, as you do. So let me, I can Dialogue: 0,0:22:10.42,0:22:16.31,Default,,0000,0000,0000,,just sort of show. It's a very simple layout Dialogue: 0,0:22:16.31,0:22:18.60,Default,,0000,0000,0000,,so far. I have a lib directory, which contains Dialogue: 0,0:22:18.60,0:22:23.16,Default,,0000,0000,0000,,universe dot rb, which you've all seen. And\Na Dialogue: 0,0:22:23.16,0:22:26.22,Default,,0000,0000,0000,,spec directory which is empty. So, very little\Nup Dialogue: 0,0:22:26.22,0:22:28.36,Default,,0000,0000,0000,,my sleeve at this point. Dialogue: 0,0:22:28.36,0:22:35.36,Default,,0000,0000,0000,,I'm just gonna make a gemfile, as you do. Dialogue: 0,0:22:41.19,0:22:43.07,Default,,0000,0000,0000,,And at this point I'm just gonna add rspec, Dialogue: 0,0:22:43.07,0:22:45.55,Default,,0000,0000,0000,,cause I'm starting to write some tests, and\NI'm Dialogue: 0,0:22:45.55,0:22:48.13,Default,,0000,0000,0000,,gonna add mutant. Dialogue: 0,0:22:48.13,0:22:55.13,Default,,0000,0000,0000,,OK. So, and we'll bundle install. Ah. Cool.\NIt Dialogue: 0,0:22:59.28,0:23:02.54,Default,,0000,0000,0000,,just installed that new version of mutant\Nthat was Dialogue: 0,0:23:02.54,0:23:06.38,Default,,0000,0000,0000,,just released moments ago. Good. Let me just\Nsee Dialogue: 0,0:23:06.38,0:23:12.19,Default,,0000,0000,0000,,what Ruby version I'm on. OK. That should\Nbe Dialogue: 0,0:23:12.19,0:23:13.04,Default,,0000,0000,0000,,fine. Dialogue: 0,0:23:13.04,0:23:15.02,Default,,0000,0000,0000,,So. Let's write some specs. So we have the Dialogue: 0,0:23:15.02,0:23:21.37,Default,,0000,0000,0000,,spec directory. Let's write planet_spec dot\Nrb. And we'll Dialogue: 0,0:23:21.37,0:23:26.28,Default,,0000,0000,0000,,require rspec and we'll require our planet\Nfile. I'll Dialogue: 0,0:23:26.28,0:23:29.35,Default,,0000,0000,0000,,just use require_relative for that, rather\Nthan messing with Dialogue: 0,0:23:29.35,0:23:31.18,Default,,0000,0000,0000,,the load path or anything. So that's up a Dialogue: 0,0:23:31.18,0:23:36.15,Default,,0000,0000,0000,,directory in lib and I think it's called universe. Dialogue: 0,0:23:36.15,0:23:40.96,Default,,0000,0000,0000,,And now let's start writing our specs, right.\NSo Dialogue: 0,0:23:40.96,0:23:47.96,Default,,0000,0000,0000,,we're just gonna describe our planet in our\Nuniverse Dialogue: 0,0:23:48.49,0:23:55.49,Default,,0000,0000,0000,,model. And. So let's create a subject, which\Nis Dialogue: 0,0:23:59.43,0:24:02.12,Default,,0000,0000,0000,,just gonna be our planet. That's like the\Nmain Dialogue: 0,0:24:02.12,0:24:04.53,Default,,0000,0000,0000,,thing that we're gonna be testing here. And\Nit's Dialogue: 0,0:24:04.53,0:24:08.40,Default,,0000,0000,0000,,initialized with a radius and an area. I believe Dialogue: 0,0:24:08.40,0:24:12.20,Default,,0000,0000,0000,,in that order. Yup. Dialogue: 0,0:24:12.20,0:24:19.20,Default,,0000,0000,0000,,Cool. So let's create a context. And let's\Ndo Dialogue: 0,0:24:20.16,0:24:22.25,Default,,0000,0000,0000,,the happy path first, because that was kind\Nof, Dialogue: 0,0:24:22.25,0:24:24.49,Default,,0000,0000,0000,,like, we all agreed that the first path we Dialogue: 0,0:24:24.49,0:24:27.61,Default,,0000,0000,0000,,should write was the happy path. So in this Dialogue: 0,0:24:27.61,0:24:32.47,Default,,0000,0000,0000,,case, Venus is actually the happy path. Venus\Nis Dialogue: 0,0:24:32.47,0:24:36.68,Default,,0000,0000,0000,,pretty darn close to spherical. So in this\Ncase Dialogue: 0,0:24:36.68,0:24:43.68,Default,,0000,0000,0000,,we'll define the radius to be. Oops. Cool. Dialogue: 0,0:25:00.52,0:25:04.66,Default,,0000,0000,0000,,And I think I said it's in meters, yeah? Dialogue: 0,0:25:04.66,0:25:10.66,Default,,0000,0000,0000,,So it'll be that. And then the area will Dialogue: 0,0:25:10.66,0:25:17.66,Default,,0000,0000,0000,,be. Eh, let's see. Wikipedia. OK. So the surface Dialogue: 0,0:25:26.86,0:25:33.80,Default,,0000,0000,0000,,area is, what is that? Four-hundred sixty\Nmillion? Which Dialogue: 0,0:25:33.80,0:25:37.05,Default,,0000,0000,0000,,is OK. But actually, like, I would like a Dialogue: 0,0:25:37.05,0:25:39.90,Default,,0000,0000,0000,,more precise number, because, like, I don't\Nwant to Dialogue: 0,0:25:39.90,0:25:42.31,Default,,0000,0000,0000,,crank up our tolerance to some ridiculous\Nvalue to Dialogue: 0,0:25:42.31,0:25:45.00,Default,,0000,0000,0000,,make this true. So I actually found a more Dialogue: 0,0:25:45.00,0:25:48.18,Default,,0000,0000,0000,,precise number than the one that's on Wikipedia,\Nwhich Dialogue: 0,0:25:48.18,0:25:51.84,Default,,0000,0000,0000,,is this. So it's four-hundred sixty million,\Ntwo hundred Dialogue: 0,0:25:51.84,0:25:55.18,Default,,0000,0000,0000,,sixty-four thousand, seven-hundred forty.\NWhich is, you know, pretty Dialogue: 0,0:25:55.18,0:25:58.00,Default,,0000,0000,0000,,round number still, but it's more precise\Nthan the Dialogue: 0,0:25:58.00,0:26:01.13,Default,,0000,0000,0000,,one on Wikipedia. Dialogue: 0,0:26:01.13,0:26:03.29,Default,,0000,0000,0000,,And now we'll have our assertion. So we'll\Njust Dialogue: 0,0:26:03.29,0:26:10.17,Default,,0000,0000,0000,,say it's spherical. Venus is spherical. We\Nexpect our Dialogue: 0,0:26:10.17,0:26:17.17,Default,,0000,0000,0000,,subject to be spherical. Good? Is everyone\Nsatisfied? Do Dialogue: 0,0:26:18.85,0:26:20.90,Default,,0000,0000,0000,,I, like, if people see bugs, call them out. Dialogue: 0,0:26:20.90,0:26:23.42,Default,,0000,0000,0000,,Like, does this look like a good happy path Dialogue: 0,0:26:23.42,0:26:28.40,Default,,0000,0000,0000,,test? Yes? This will pass? Dialogue: 0,0:26:28.40,0:26:35.40,Default,,0000,0000,0000,,Good. Let's run it. Yup. That should work.\NCool. Dialogue: 0,0:26:39.59,0:26:42.54,Default,,0000,0000,0000,,It passed. Hooray. Dialogue: 0,0:26:42.54,0:26:45.15,Default,,0000,0000,0000,,Let's do something else. Let's open up our\Ngemfile Dialogue: 0,0:26:45.15,0:26:49.16,Default,,0000,0000,0000,,again and add simplecov to measure the C-0\Ncode Dialogue: 0,0:26:49.16,0:26:56.16,Default,,0000,0000,0000,,coverage. And I guess here we can just say Dialogue: 0,0:26:56.82,0:27:03.42,Default,,0000,0000,0000,,require simplecov. SimpleCov.start. And so\Nnow, if we run Dialogue: 0,0:27:03.42,0:27:10.42,Default,,0000,0000,0000,,our specs again, we'll get a little coverage\Nreport. Dialogue: 0,0:27:11.16,0:27:16.53,Default,,0000,0000,0000,,Tada! Dialogue: 0,0:27:16.53,0:27:19.04,Default,,0000,0000,0000,,So for those who aren't that familiar with\Nsimplecov, Dialogue: 0,0:27:19.04,0:27:24.35,Default,,0000,0000,0000,,basically it looks to make sure that your,\Nthat Dialogue: 0,0:27:24.35,0:27:26.43,Default,,0000,0000,0000,,every line of code is executed, and if you Dialogue: 0,0:27:26.43,0:27:30.38,Default,,0000,0000,0000,,test the happy path, it totally is, right?\NThe Dialogue: 0,0:27:30.38,0:27:34.21,Default,,0000,0000,0000,,class, the module is loaded, the class is\Nloaded, Dialogue: 0,0:27:34.21,0:27:41.21,Default,,0000,0000,0000,,this constant is set. We initialize. We initialize\Na Dialogue: 0,0:27:41.49,0:27:45.59,Default,,0000,0000,0000,,planet. I can turn on lines. We initialize\Na Dialogue: 0,0:27:45.59,0:27:51.14,Default,,0000,0000,0000,,planet on line nine. We invoke this spherical\Nmethod Dialogue: 0,0:27:51.14,0:27:56.14,Default,,0000,0000,0000,,on line fifteen, in the assertion. And that\Ninvokes Dialogue: 0,0:27:56.14,0:27:59.05,Default,,0000,0000,0000,,the range method. So we have, you can actually Dialogue: 0,0:27:59.05,0:28:02.35,Default,,0000,0000,0000,,see every line of code is executed precisely\None Dialogue: 0,0:28:02.35,0:28:04.29,Default,,0000,0000,0000,,time. Dialogue: 0,0:28:04.29,0:28:07.07,Default,,0000,0000,0000,,So we have, we're not over-testing. We're\Nnot under-testing. Dialogue: 0,0:28:07.07,0:28:11.07,Default,,0000,0000,0000,,We have perfect, a hundred percent C-zero\Ncode coverage. Dialogue: 0,0:28:11.07,0:28:14.05,Default,,0000,0000,0000,,But we all agreed that this was completely\Ninsufficient. Dialogue: 0,0:28:14.05,0:28:14.65,Default,,0000,0000,0000,,So- Dialogue: 0,0:28:14.65,0:28:16.45,Default,,0000,0000,0000,,AUDIENCE: Ship it. Dialogue: 0,0:28:16.45,0:28:19.45,Default,,0000,0000,0000,,E.M.: Ship it. K. Right. Dialogue: 0,0:28:19.45,0:28:21.25,Default,,0000,0000,0000,,AUDIENCE: Force push. Dialogue: 0,0:28:21.25,0:28:27.28,Default,,0000,0000,0000,,E.M.: I'm gonna delete this simplecov stuff\Ncause it's Dialogue: 0,0:28:27.28,0:28:29.13,Default,,0000,0000,0000,,garbage. Dialogue: 0,0:28:29.13,0:28:33.75,Default,,0000,0000,0000,,OK. So let's write some more tests. So a Dialogue: 0,0:28:33.75,0:28:40.75,Default,,0000,0000,0000,,planet that's not spherical is. No. That's\Nmy name. Dialogue: 0,0:28:41.01,0:28:48.01,Default,,0000,0000,0000,,Thank you. Is our home. The earth. Radius\Nof Dialogue: 0,0:28:52.59,0:28:59.59,Default,,0000,0000,0000,,the earth. Cool. I guess we could say point Dialogue: 0,0:29:06.20,0:29:13.20,Default,,0000,0000,0000,,one. Doesn't really matter. And. Oops. What's\Nthe area? Dialogue: 0,0:29:22.05,0:29:29.05,Default,,0000,0000,0000,,Cool. So in square kilometers, it's five-hundred\Nten. Five-hundred Dialogue: 0,0:29:31.91,0:29:36.52,Default,,0000,0000,0000,,ten million, rather. Dialogue: 0,0:29:36.52,0:29:38.09,Default,,0000,0000,0000,,So we, again, we could, like, try to find Dialogue: 0,0:29:38.09,0:29:40.29,Default,,0000,0000,0000,,a number that's more precise, but we actually,\Nlike, Dialogue: 0,0:29:40.29,0:29:42.64,Default,,0000,0000,0000,,the whole point of this test is to test Dialogue: 0,0:29:42.64,0:29:45.45,Default,,0000,0000,0000,,a planet that is an oblate spheroid, not an Dialogue: 0,0:29:45.45,0:29:48.46,Default,,0000,0000,0000,,actual sphere. And so in this case, we want Dialogue: 0,0:29:48.46,0:29:50.79,Default,,0000,0000,0000,,to, so like, it's fine that the numbers are Dialogue: 0,0:29:50.79,0:29:56.05,Default,,0000,0000,0000,,not within the default tolerance. And so,\Nyeah. Basically Dialogue: 0,0:29:56.05,0:30:00.12,Default,,0000,0000,0000,,we want to say, like, it is oblate. Not Dialogue: 0,0:30:00.12,0:30:06.47,Default,,0000,0000,0000,,spherical. Dialogue: 0,0:30:06.47,0:30:10.53,Default,,0000,0000,0000,,So in this case, we expect our subject not Dialogue: 0,0:30:10.53,0:30:17.53,Default,,0000,0000,0000,,to be spherical. Cool. Look good? Let's run\Nit. Dialogue: 0,0:30:21.75,0:30:27.77,Default,,0000,0000,0000,,Cool. Our tests pass. Dialogue: 0,0:30:27.77,0:30:31.99,Default,,0000,0000,0000,,So this is, like, maybe your normal workflow.\NYou Dialogue: 0,0:30:31.99,0:30:33.47,Default,,0000,0000,0000,,would do this. A few of you would stop Dialogue: 0,0:30:33.47,0:30:35.05,Default,,0000,0000,0000,,at this point. I think there were probably\Nas Dialogue: 0,0:30:35.05,0:30:37.40,Default,,0000,0000,0000,,many hands for, like, I would stop at two, Dialogue: 0,0:30:37.40,0:30:39.25,Default,,0000,0000,0000,,or probably more tests, for like, I would\Nstop Dialogue: 0,0:30:39.25,0:30:42.17,Default,,0000,0000,0000,,at two, than I would stop at four or Dialogue: 0,0:30:42.17,0:30:45.47,Default,,0000,0000,0000,,three. But let me show, let me show what Dialogue: 0,0:30:45.47,0:30:46.17,Default,,0000,0000,0000,,mutant does. Dialogue: 0,0:30:46.17,0:30:47.95,Default,,0000,0000,0000,,Let me show sort of how this mutation testing Dialogue: 0,0:30:47.95,0:30:53.64,Default,,0000,0000,0000,,stuff works. So you're gonna say bundle exec.\NOr, Dialogue: 0,0:30:53.64,0:30:57.89,Default,,0000,0000,0000,,I have it aliased to b-e. I can spell Dialogue: 0,0:30:57.89,0:31:02.04,Default,,0000,0000,0000,,that out. So this is the mutant command line, Dialogue: 0,0:31:02.04,0:31:04.91,Default,,0000,0000,0000,,and it takes a bunch of arguments. So you Dialogue: 0,0:31:04.91,0:31:07.39,Default,,0000,0000,0000,,have to give it a lib for the sort Dialogue: 0,0:31:07.39,0:31:09.37,Default,,0000,0000,0000,,of lib directory that you're testing so that\Nit Dialogue: 0,0:31:09.37,0:31:11.97,Default,,0000,0000,0000,,knows to add that to the load path. And Dialogue: 0,0:31:11.97,0:31:16.16,Default,,0000,0000,0000,,then you give it a require. So it's gonna Dialogue: 0,0:31:16.16,0:31:19.97,Default,,0000,0000,0000,,require some specific library, in this case\Nthe universe Dialogue: 0,0:31:19.97,0:31:23.80,Default,,0000,0000,0000,,library that you wrote. And then you can say, Dialogue: 0,0:31:23.80,0:31:25.99,Default,,0000,0000,0000,,like, I want to test everything in universe,\Nor Dialogue: 0,0:31:25.99,0:31:29.54,Default,,0000,0000,0000,,you can say, like, with wild cards like colon Dialogue: 0,0:31:29.54,0:31:31.65,Default,,0000,0000,0000,,colon universe star. I can make that a little Dialogue: 0,0:31:31.65,0:31:34.24,Default,,0000,0000,0000,,smaller so it fits on one line. Dialogue: 0,0:31:34.24,0:31:36.76,Default,,0000,0000,0000,,Or you can say, like, I want to test Dialogue: 0,0:31:36.76,0:31:40.70,Default,,0000,0000,0000,,specifically the planet class, or you say,\Nlike, I Dialogue: 0,0:31:40.70,0:31:42.25,Default,,0000,0000,0000,,want to test a particular method. So you can Dialogue: 0,0:31:42.25,0:31:44.99,Default,,0000,0000,0000,,say, like, I want to test spherical. Something\Nlike Dialogue: 0,0:31:44.99,0:31:47.23,Default,,0000,0000,0000,,that. Right. But we want to test the whole Dialogue: 0,0:31:47.23,0:31:48.06,Default,,0000,0000,0000,,planet class. Dialogue: 0,0:31:48.06,0:31:50.64,Default,,0000,0000,0000,,Oh, and you also, there's an option to say Dialogue: 0,0:31:50.64,0:31:53.75,Default,,0000,0000,0000,,use rspec, so it knows what test framework\Nto Dialogue: 0,0:31:53.75,0:31:59.36,Default,,0000,0000,0000,,run. This is important, because it's testing\Nyour tests. Dialogue: 0,0:31:59.36,0:32:00.63,Default,,0000,0000,0000,,And I am getting some sort of an error. Dialogue: 0,0:32:00.63,0:32:04.88,Default,,0000,0000,0000,,Ah. I am missing mutant-rspec in my gemfile.\NThat Dialogue: 0,0:32:04.88,0:32:09.63,Default,,0000,0000,0000,,is easy to fix. Right. So. Dialogue: 0,0:32:09.63,0:32:12.14,Default,,0000,0000,0000,,Rspec used to be built in. This has changed Dialogue: 0,0:32:12.14,0:32:15.64,Default,,0000,0000,0000,,recently. So basically there are other libraries.\NThere's like Dialogue: 0,0:32:15.64,0:32:18.45,Default,,0000,0000,0000,,plugin library. So if you want to write, if Dialogue: 0,0:32:18.45,0:32:20.80,Default,,0000,0000,0000,,you use some crazy test-framework, you can\Njust write Dialogue: 0,0:32:20.80,0:32:23.41,Default,,0000,0000,0000,,a gem that adds mutant support for that test Dialogue: 0,0:32:23.41,0:32:25.69,Default,,0000,0000,0000,,framework. So this happens to be the one for Dialogue: 0,0:32:25.69,0:32:28.76,Default,,0000,0000,0000,,rspec. But you can use one for test-unit or Dialogue: 0,0:32:28.76,0:32:29.59,Default,,0000,0000,0000,,anything else. Dialogue: 0,0:32:29.59,0:32:33.03,Default,,0000,0000,0000,,So. BI is just a short-cut for bundle install. Dialogue: 0,0:32:33.03,0:32:38.09,Default,,0000,0000,0000,,And we'll do this. Cool. Dialogue: 0,0:32:38.09,0:32:40.01,Default,,0000,0000,0000,,So what it is doing, you're like, what, this Dialogue: 0,0:32:40.01,0:32:42.86,Default,,0000,0000,0000,,is crazy. We only wrote two tests. Why are Dialogue: 0,0:32:42.86,0:32:45.42,Default,,0000,0000,0000,,there all those little green dots and Fs flying Dialogue: 0,0:32:45.42,0:32:52.42,Default,,0000,0000,0000,,by? So basically what's happening is we, it's\Ntaking Dialogue: 0,0:32:53.87,0:32:58.69,Default,,0000,0000,0000,,our two tests and it's running through these\Nvarious Dialogue: 0,0:32:58.69,0:33:01.21,Default,,0000,0000,0000,,mutations. In this case, it made eight-three\Nmutations to Dialogue: 0,0:33:01.21,0:33:05.45,Default,,0000,0000,0000,,our code, based on what we used, right. Like, Dialogue: 0,0:33:05.45,0:33:08.17,Default,,0000,0000,0000,,so, depending on, like, if you use an and, Dialogue: 0,0:33:08.17,0:33:09.42,Default,,0000,0000,0000,,it will convert it to an or. But if Dialogue: 0,0:33:09.42,0:33:11.54,Default,,0000,0000,0000,,you don't use that, you can't, you do that Dialogue: 0,0:33:11.54,0:33:12.19,Default,,0000,0000,0000,,mutation. Dialogue: 0,0:33:12.19,0:33:16.74,Default,,0000,0000,0000,,So, in this case, there was eighty-three mutations.\NEighty-three Dialogue: 0,0:33:16.74,0:33:18.84,Default,,0000,0000,0000,,sort of mutants. And eighty-two of those mutants\Nwere Dialogue: 0,0:33:18.84,0:33:23.77,Default,,0000,0000,0000,,killed. So there, in this case, was one that Dialogue: 0,0:33:23.77,0:33:27.20,Default,,0000,0000,0000,,was not. And you get this really cool output, Dialogue: 0,0:33:27.20,0:33:31.04,Default,,0000,0000,0000,,diff output. So it basically says, this is\Nthe Dialogue: 0,0:33:31.04,0:33:33.98,Default,,0000,0000,0000,,mutation we did that was not killed. We took, Dialogue: 0,0:33:33.98,0:33:40.28,Default,,0000,0000,0000,,what is it, line twenty-four? Was that? Is\Nthere Dialogue: 0,0:33:40.28,0:33:44.91,Default,,0000,0000,0000,,a comment? We took line twenty-five, right,\Nthis range Dialogue: 0,0:33:44.91,0:33:50.31,Default,,0000,0000,0000,,method, and we deleted the code that you wrote Dialogue: 0,0:33:50.31,0:33:51.79,Default,,0000,0000,0000,,and we mutated it in this way. We got Dialogue: 0,0:33:51.79,0:33:54.29,Default,,0000,0000,0000,,rid of that minus T. And it turned out Dialogue: 0,0:33:54.29,0:33:56.96,Default,,0000,0000,0000,,that even after we made that mutation, all\Nof Dialogue: 0,0:33:56.96,0:33:59.92,Default,,0000,0000,0000,,your tests still passed. Dialogue: 0,0:33:59.92,0:34:03.40,Default,,0000,0000,0000,,Actually, maybe it would be helpful, like,\NI can Dialogue: 0,0:34:03.40,0:34:09.53,Default,,0000,0000,0000,,show with earth. So before we do earth, this Dialogue: 0,0:34:09.53,0:34:11.75,Default,,0000,0000,0000,,is what the mutation output would look like.\NRight. Dialogue: 0,0:34:11.75,0:34:13.30,Default,,0000,0000,0000,,So. I just want to give you a sense Dialogue: 0,0:34:13.30,0:34:15.62,Default,,0000,0000,0000,,of, like, all the different mutations and\Nkind of Dialogue: 0,0:34:15.62,0:34:17.69,Default,,0000,0000,0000,,how they work and what the output looks like. Dialogue: 0,0:34:17.69,0:34:20.02,Default,,0000,0000,0000,,So if we don't have the sort of unhappy Dialogue: 0,0:34:20.02,0:34:23.42,Default,,0000,0000,0000,,path where it returns false, these are the\Nvarious Dialogue: 0,0:34:23.42,0:34:25.52,Default,,0000,0000,0000,,mutations it runs. So there was this one,\Nwhich Dialogue: 0,0:34:25.52,0:34:27.34,Default,,0000,0000,0000,,we saw earlier, where it removes the minus\NT Dialogue: 0,0:34:27.34,0:34:29.57,Default,,0000,0000,0000,,from the range and it still passes because\Nwe're Dialogue: 0,0:34:29.57,0:34:33.30,Default,,0000,0000,0000,,sort of in the top half of that range. Dialogue: 0,0:34:33.30,0:34:35.97,Default,,0000,0000,0000,,There's this other one where it gets rid of Dialogue: 0,0:34:35.97,0:34:38.03,Default,,0000,0000,0000,,the n, so the beginning part of the range, Dialogue: 0,0:34:38.03,0:34:40.05,Default,,0000,0000,0000,,and it just puts in t there. Dialogue: 0,0:34:40.05,0:34:44.29,Default,,0000,0000,0000,,Here, it actually gets rid of that call to Dialogue: 0,0:34:44.29,0:34:47.64,Default,,0000,0000,0000,,dot cover, and it turns out that, because\Nthe Dialogue: 0,0:34:47.64,0:34:49.85,Default,,0000,0000,0000,,range returns true and you haven't put in\Na Dialogue: 0,0:34:49.85,0:34:53.35,Default,,0000,0000,0000,,thing that says it should return false, that\Nthis Dialogue: 0,0:34:53.35,0:34:56.29,Default,,0000,0000,0000,,also passes, right. So, in this case, you're\Njust Dialogue: 0,0:34:56.29,0:34:58.76,Default,,0000,0000,0000,,returning the range. But that is truthy. And\Nso Dialogue: 0,0:34:58.76,0:35:02.76,Default,,0000,0000,0000,,this, this test fails. Dialogue: 0,0:35:02.76,0:35:05.08,Default,,0000,0000,0000,,If you wanted to write a more precise test, Dialogue: 0,0:35:05.08,0:35:08.13,Default,,0000,0000,0000,,instead of saying. No, I guess that's right.\NSo, Dialogue: 0,0:35:08.13,0:35:12.23,Default,,0000,0000,0000,,in this case it's just gonna check whether\Nthat Dialogue: 0,0:35:12.23,0:35:13.89,Default,,0000,0000,0000,,method is truthy or falsey, and in this case Dialogue: 0,0:35:13.89,0:35:15.97,Default,,0000,0000,0000,,it's truthy if it just returns the range.\NRight? Dialogue: 0,0:35:15.97,0:35:17.70,Default,,0000,0000,0000,,And you're not testing that it would ever\Nbe Dialogue: 0,0:35:17.70,0:35:19.77,Default,,0000,0000,0000,,falsey. Dialogue: 0,0:35:19.77,0:35:24.37,Default,,0000,0000,0000,,Also, if you just return the instance variable\Narea, Dialogue: 0,0:35:24.37,0:35:27.22,Default,,0000,0000,0000,,so if you basically throw away everything\Nexcept that Dialogue: 0,0:35:27.22,0:35:30.83,Default,,0000,0000,0000,,last argument to the cover method, this turns\Nout Dialogue: 0,0:35:30.83,0:35:34.55,Default,,0000,0000,0000,,to also, like, you have no tests that covers Dialogue: 0,0:35:34.55,0:35:38.71,Default,,0000,0000,0000,,this. And actually you can delete that whole\Nline, Dialogue: 0,0:35:38.71,0:35:41.94,Default,,0000,0000,0000,,and the previous line, approximate area, like\Nyou get Dialogue: 0,0:35:41.94,0:35:43.57,Default,,0000,0000,0000,,the same result. Like, the fact that you have Dialogue: 0,0:35:43.57,0:35:45.80,Default,,0000,0000,0000,,an approximate area and that is truthy and\Nyou Dialogue: 0,0:35:45.80,0:35:48.28,Default,,0000,0000,0000,,are only testing that this method returns\Na truthy Dialogue: 0,0:35:48.28,0:35:52.23,Default,,0000,0000,0000,,value means that this test will pass. Dialogue: 0,0:35:52.23,0:35:58.84,Default,,0000,0000,0000,,So I just wanted to show that. I can Dialogue: 0,0:35:58.84,0:36:02.03,Default,,0000,0000,0000,,bring this back. Cool. Dialogue: 0,0:36:02.03,0:36:05.11,Default,,0000,0000,0000,,So now we're in a place where, oops. OK. Dialogue: 0,0:36:05.11,0:36:12.11,Default,,0000,0000,0000,,So our tests will pass. And we have one Dialogue: 0,0:36:12.13,0:36:15.92,Default,,0000,0000,0000,,mutant that we need to kill. So does anyone Dialogue: 0,0:36:15.92,0:36:18.78,Default,,0000,0000,0000,,have an idea for how to kill this mutant? Dialogue: 0,0:36:18.78,0:36:25.78,Default,,0000,0000,0000,,AUDIENCE: Pass in a tolerance. [indecipherable\N- 00:36:27] Pass Dialogue: 0,0:36:26.54,0:36:29.45,Default,,0000,0000,0000,,in zero tolerance. Dialogue: 0,0:36:29.45,0:36:32.58,Default,,0000,0000,0000,,E.M.: So the suggestion was to pass in a Dialogue: 0,0:36:32.58,0:36:35.73,Default,,0000,0000,0000,,zero tolerance. So let's try that. So should\NI Dialogue: 0,0:36:35.73,0:36:39.62,Default,,0000,0000,0000,,just, should we make up a planet or, how Dialogue: 0,0:36:39.62,0:36:41.14,Default,,0000,0000,0000,,do you want to do that? We could do Dialogue: 0,0:36:41.14,0:36:41.76,Default,,0000,0000,0000,,Mars, maybe? Dialogue: 0,0:36:41.76,0:36:44.49,Default,,0000,0000,0000,,AUDIENCE: Venus shouldn't be spherical with\Na tolerance of Dialogue: 0,0:36:44.49,0:36:46.18,Default,,0000,0000,0000,,E.M.: Ah. Venus shouldn't be spherical with\Na tolerance Dialogue: 0,0:36:46.18,0:36:50.81,Default,,0000,0000,0000,,of zero. So that's true. So we can sort Dialogue: 0,0:36:50.81,0:36:53.74,Default,,0000,0000,0000,,of change this one to be, it is spherical, Dialogue: 0,0:36:53.74,0:36:55.44,Default,,0000,0000,0000,,give the default tolerance. Dialogue: 0,0:36:55.44,0:36:56.88,Default,,0000,0000,0000,,AUDIENCE: Yes. Dialogue: 0,0:36:56.88,0:37:01.23,Default,,0000,0000,0000,,E.M.: That's what that tests. Right. It's\Nspherical-ish. I Dialogue: 0,0:37:01.23,0:37:04.46,Default,,0000,0000,0000,,like that. Ish. Dialogue: 0,0:37:04.46,0:37:11.46,Default,,0000,0000,0000,,But is not perfectly spherical. And so here\Nwe Dialogue: 0,0:37:16.22,0:37:18.48,Default,,0000,0000,0000,,would expect this not to be spherical, given\Na Dialogue: 0,0:37:18.48,0:37:22.49,Default,,0000,0000,0000,,tolerance of zero. Yeah? So let's first run\Nthat Dialogue: 0,0:37:22.49,0:37:29.49,Default,,0000,0000,0000,,test. Cool. So that passes. It is not perfectly Dialogue: 0,0:37:30.11,0:37:34.90,Default,,0000,0000,0000,,spherical, and it is spherical-ish. We didn't\Nbreak that Dialogue: 0,0:37:34.90,0:37:37.62,Default,,0000,0000,0000,,test. OK, so now let's do the same thing Dialogue: 0,0:37:37.62,0:37:44.62,Default,,0000,0000,0000,,with our mutant command. Dialogue: 0,0:37:44.84,0:37:50.97,Default,,0000,0000,0000,,So the mutant still lives. Why? Dialogue: 0,0:37:50.97,0:37:53.41,Default,,0000,0000,0000,,So to make this fail, what we need to Dialogue: 0,0:37:53.41,0:37:56.08,Default,,0000,0000,0000,,do is we need to pass in a tolerance Dialogue: 0,0:37:56.08,0:37:58.79,Default,,0000,0000,0000,,that falls in the bottom half of the range. Dialogue: 0,0:37:58.79,0:38:03.38,Default,,0000,0000,0000,,So, in this case, Venus is slightly the area Dialogue: 0,0:38:03.38,0:38:09.41,Default,,0000,0000,0000,,of Venus is slightly above the perfect sphericism\Nor Dialogue: 0,0:38:09.41,0:38:14.02,Default,,0000,0000,0000,,whatever, right. It's not, it's on the high-end\Nof Dialogue: 0,0:38:14.02,0:38:15.54,Default,,0000,0000,0000,,the range. So what we need to do is Dialogue: 0,0:38:15.54,0:38:19.81,Default,,0000,0000,0000,,we need to find a planet that is actually Dialogue: 0,0:38:19.81,0:38:22.46,Default,,0000,0000,0000,,on the low-end of the range, right, where\Nit's Dialogue: 0,0:38:22.46,0:38:28.91,Default,,0000,0000,0000,,less. It's spherical, but within the tolerance,\Nbut it's, Dialogue: 0,0:38:28.91,0:38:33.86,Default,,0000,0000,0000,,yeah. On the low-end of the range. Make sense? Dialogue: 0,0:38:33.86,0:38:40.32,Default,,0000,0000,0000,,So yeah. I don't know. Like, what we could Dialogue: 0,0:38:40.32,0:38:42.55,Default,,0000,0000,0000,,do to test, like, we could, I, I don't Dialogue: 0,0:38:42.55,0:38:44.79,Default,,0000,0000,0000,,want to necessarily like look up more planets\Nand Dialogue: 0,0:38:44.79,0:38:49.20,Default,,0000,0000,0000,,their radiuses. But we could do something\Nlike this. Dialogue: 0,0:38:49.20,0:38:53.46,Default,,0000,0000,0000,,So this is, sorry, that's not earth. This\Nis, Dialogue: 0,0:38:53.46,0:38:54.23,Default,,0000,0000,0000,,like. Dialogue: 0,0:38:54.23,0:38:56.55,Default,,0000,0000,0000,,AUDIENCE: Rubinius 5. Dialogue: 0,0:38:56.55,0:38:59.53,Default,,0000,0000,0000,,E.M.: Rubinius 5. I like that. Thank you for Dialogue: 0,0:38:59.53,0:39:04.54,Default,,0000,0000,0000,,the suggestion from the audience. And Rubinius\N5. Let's Dialogue: 0,0:39:04.54,0:39:06.89,Default,,0000,0000,0000,,sort of make it easy for ourselves. So we'll Dialogue: 0,0:39:06.89,0:39:13.81,Default,,0000,0000,0000,,say the radius is zero point five, right.\NSo Dialogue: 0,0:39:13.81,0:39:17.08,Default,,0000,0000,0000,,if we put that in our formula, zero point Dialogue: 0,0:39:17.08,0:39:21.35,Default,,0000,0000,0000,,five squared is a quarter, and then a quarter, Dialogue: 0,0:39:21.35,0:39:26.04,Default,,0000,0000,0000,,when it sort of cancels out the multiple by Dialogue: 0,0:39:26.04,0:39:29.21,Default,,0000,0000,0000,,four. You div, you're dividing by four basically.\NSo Dialogue: 0,0:39:29.21,0:39:33.19,Default,,0000,0000,0000,,the, we know that the actual area should be Dialogue: 0,0:39:33.19,0:39:36.50,Default,,0000,0000,0000,,pi. So then we can just say something like, Dialogue: 0,0:39:36.50,0:39:43.50,Default,,0000,0000,0000,,let the area be Math::PI. And we want it Dialogue: 0,0:39:44.75,0:39:47.68,Default,,0000,0000,0000,,to fall, we want the area to be below Dialogue: 0,0:39:47.68,0:39:49.43,Default,,0000,0000,0000,,the range. Right, so we want it to be Dialogue: 0,0:39:49.43,0:39:52.35,Default,,0000,0000,0000,,like, Math::Pi minus, like, some amount that\Nfalls within Dialogue: 0,0:39:52.35,0:39:56.62,Default,,0000,0000,0000,,the tolerance or whatever. Right? Make sense? Dialogue: 0,0:39:56.62,0:40:01.66,Default,,0000,0000,0000,,And then we expect that this is gonna be Dialogue: 0,0:40:01.66,0:40:08.66,Default,,0000,0000,0000,,spherical. Ish. Within the default tolerance.\NCool. OK. So Dialogue: 0,0:40:19.57,0:40:25.76,Default,,0000,0000,0000,,let's run that. Specs pass. And have we killed Dialogue: 0,0:40:25.76,0:40:32.51,Default,,0000,0000,0000,,the last mutant? Nice. Yeah. Dialogue: 0,0:40:32.51,0:40:36.61,Default,,0000,0000,0000,,Yeah! So.