 I want to start by asking who here has taught in a classroom setting or a group setting where you've taught a group of people? Wow, a lot of people. How many of you guys use tests? OK. Oh, great crap. And who here has taught in an informal setting? So we're going to talk about test-first teaching, which is a specific technique for teaching programming, which is not unique to Ruby, but we'll be mostly talking about the Ruby effort. So why should you care about this? Maybe you want to learn Ruby better than you already know, or you're a novice coming to this conference and you want to learn Ruby at all. You have a friend or colleague that you want to teach or a relative who's always wanted to learn to program. Or maybe you're a teacher and you want to help use our materials or improve our materials. We would welcome your participation. Or maybe you recognize that teaching, the active teaching, actually helps you learn. In fact, even if you're not an active teacher, everybody who participates in the active engineering and the kind of teaching and the kind of engineering that we do is required to teach. The best engineers are great teachers. We work very collaboratively. And we live in an environment, and it's been this way for some time, where it's not really sufficient to know anything well, any one thing, or any group of things. You always have to acquire that next new thing. And so you are producing great software if you're constantly teaching what you know. And then you work with people who let you learn. I actually was impressed with Jim's answer to one of the questions, or not questions, but something he said in the last talk, which is, I worked through the exercises, but I haven't taught them yet. So I don't understand them. That's kind of the same attitude that we have here. Sarah and I both and lots of other people feel that we don't really understand something until we've taught someone, or maybe even written a course about it. So what is test-worth teaching? This is the idea that the teacher provides these micro-tests and the student makes them pass. And in making them pass, learns a concept and takes it one test at a time. This can be used in a classroom setting or guided and used solo or in a pairing situation. And so this is different from test-worth development. We'll talk a little bit about that later. So pairing is teaching. When you work collaboratively, you teach each other. We're also going to be talking about pairing in the classroom. We are? I like to passionate about pairing in the classroom. I am? Yes, sorry. Well, hi. Is this one of my slides? Well. OK, yeah, well, apparently students can learn together and teach each other. Yeah, no, pairing in the classroom is something that I've used a lot in my gigs as a teacher. I thought you were going to do this one. OK, well, in any case, when I started teaching Ruby, I would encourage people to pair. Some people feel like they really need to work on their own to master the skills. And I think both work really well. But pairing can work really effectively. Students teach each other. And I want to point something out of this last bullet point, which is that pairing is good for the students, but it's also really good for the teacher. Because what you find is that the students, if they're paired up while working on exercises, even if they're not test-first exercises, but if they're paired up, they can help each other through the rough spots. And they don't ask for help until they really need it. And so the teacher is free to wander the room, talk from, move from station to station, and actually help the students out who are having set-up problems or challenging conceptual problems. And in fact, the students get a lot of, I don't know, what the right word would be, self-esteem from working through it on their own and actually learn the material better if they fail a little, which we're also going to talk a little more about later. So how do we know this is a good idea? Well, it turns out it has many independent inventors. When I first started teaching Ruby, I was signed up to teach Ruby on Rails class after we started doing these workshops. And I really felt strongly that it was important to teach testing. And I sent some email out to some groups. And the response I got was, that's a really bad idea. And I was horrified. And I, because I thought it was important. And people said, no, your students are going to get frustrated. Testing is hard. And if people don't know how to program, then they can't really learn how to test. And I was like chagrined and I tweeted about it. And Alex, who I met once ever, tweeted back. Oh. At Goga Ruko, right? Yes, I met at Goga Ruko last year. That's right. Wow. The wheel turns. Look what happened. He tweeted back and said, yes, you should teach testing. In fact, I have a whole curriculum. Unfortunately, that curriculum is written in Java. He says, why don't you stop by and turn it into Ruby? And thus, a partnership was born. So Alex created his curriculum in Java in 2002. And in doing research for this, we both discovered, and or I discovered, maybe Alex already knew that there's all of these different people who figured out that this is a good way to teach. I'm in a good way to learn. So in 2005, Mike Clark wrote about using Ruby test to learn. And in 2006, Art Howard's Ruby Quiz Metacolons was a predecessor to the Ruby colons, I understand. And in 2000, I talked to Yehuda Katz about this. And he was like, oh, hey, I did that before. You told me this. And did some teaching with Matt Aminetti using this technique for Ruby on Rails training. And there's probably other people who independently invented this as well. Hands up for anyone else who independently invented this. OK, we've got Ryan over there. Anyone else? Someone up here, Ross invented it too. OK. Excellent. Well done. Jim invented it, as well as having based off of the Metacolons. OK. OK, super. So when I came to this, it wasn't obvious that this would be a good teaching technique. But it turns out that it is a terribly. It's obvious enough that, and it's the right thing enough, that a lot of people came to it independently. The other reason we know it's a good idea is because it works. And we have the student evaluation forms to prove it. And students actually get emails saying, oh my gosh, doing the homework was fun. And people don't expect their homework to be fun. And people don't expect the programming exercises to be fun. And they want more. That's actually the worst part. It's like, OK, I did the exercises. What's the next one? It's like, well, we haven't really taught you about threads yet. So you can't do it. Sorry. OK. So yeah, this, oh, I guess we're swapping out. OK. So just to give more of the backgrounds, we're going to buzz through this because we don't have a lot of time and because you want to see actual code. But just to give you a brief overview of the materials that we talked about, test first teaching is what Sarah and I have done. It's Ruby. It's micro tests. And it's kind of at a relatively high conceptual level where we let the students bite off a little bit more, perhaps, than learning a single syntactic feature of the language. Ruby Coens is at the other extreme at this tier where it's very much about learning incremental, tiny things about the language. And I'm going to show you code examples and go into more detail about both of those styles a little later on. MetaCoens is actually kind of fun. How many people here have done Ruby Quiz number 67? Do you remember it? I see a few hands here. This is really fun. I actually tried to do it in preparation for this talk. And I needed to spend more time on it because I didn't get more than halfway through it. It's really a great way to sort of learn. Even if you are a Ruby expert, you can use this test-driven learning style to improve your language with Ruby Meta Programming. Basically, they test drive you through writing a, you know, it sounds simple kind of method that's basically defining a new type of attribute accessor. So I won't spoil the rest of it. But it's actually quite fun. Also, all the other Ruby quizzes are pretty good. There's other things. If this were sort of a diagram with boxes and eras, there would be this constellation of Ruby testing. And there would be this nearby constellation. I'm sorry, this constellation of test first teaching, test first learning. And a nearby constellation of other forms of guided learning. All of these are also in Ruby. There's a really fun one called Ruby Warrior, where instead of writing code to make a test pass, you're writing code to make a little like Dwarven Warrior fight works in a dungeon and get the highest score for each level of the dungeon. And it's a really neat game that you can play, you know, sort of with yourself, but then compare your score to your friend's scores. And it's all in GitHub and it's very cute. Ryan Bates is in here, is he? Okay. Try Ruby, of course, a lot of us have seen or played with. That's guided because you're playing with Ruby live in a browser and it's giving you hints about what to try next, right? So it's very much about the same style of experimentation that the testing driven stuff is promoting as well. There's also a relatively recent book that came out last year called Growing Object Oriented Software. And that is written in Java, I believe, but Brian Merrick has been converting the exercises into Ruby, so people who are more comfortable with Ruby can follow the book and use his exercises to follow along. And that's sort of using tests at an even higher abstract level, again for advanced people, right? If you guys already know the difference between a proc and a lambda, you might still get value out of following along with this book's exercises. It's teaching a style of object oriented design that's very heavily based on testing and mocking. So this is our site, and if you visited this site a week ago, it would look even uglier than it does today. But this is the screenshot as of today at noon, where as you can see, we need some help, some contributors to not just the code part, but the web design. So I do wanna say that Navbar on the right is using position fixed. Thank you. Okay, so you can scroll and it stays, okay. Anyway, do you have anything more to say about that? We've, about. Oh, I have, okay, so testfirst.org is this site that is, the intent is that you, as a student, could come to this site or as a teacher to point people to the materials. But then at ultra-saurus slash testfirst teaching is the source for the site and the solutions to all the problems. So you can dig in and look at the solutions and feel free to fork and send full requests and contribute. So this is all meant to be very open, open-sourcy. And also, kudos to Leah who joined us shortly after, I mean, probably the day that we got together and has been a strong contributor to all of these materials throughout. Leah. Okay, so as we all know, this is you in a traditional programming class, right? And even if you're a teacher now, it's really, this is heartening to look around the room and see a bunch of board people. Actually, I'm pretty impressed with how few of you are Twittering right now. That makes me feel pretty empowered. So normally, when you're doing these classes, they're written as courseware, which means a bunch of text in a book that gets photocopied and bindered up and fedexed out the day before you're there for a four-day course. And it's usually a big boring lecture about threads or whatever followed by exercises. And the exercises are what really doesn't work because a good teacher can save a boring lecture, but they can't really save boring exercises or more to the point frustrating exercises, right? A lot of these exercises are either too simple, they're multiple choice or fill in the blank, which is like not actually about programming, right? It's about memorizing terms. Or they are skeleton code where somebody else wrote a bunch of code and then deleted key sections and replaced it with a comment, right? Now, even if the final version would compile and do what it said, it's still very frustrating and confusing and not really very educational as a student to just try to fill in the blanks because you not only have to figure out what goes in there, you also have to figure out what's different between the way you would've solved it and the way they would've solved it. And that can get down to like even little things like variable names can be really grit in the gears for trying to come up to speed on a new concept. If you can't name your own variables, you're not really programming, right? Finally, there's a way that sort of throws that out all together. It's the easiest kind of exercise to write and probably the hardest to do, which is just okay, go and write a simulation of a bank deposit. Well, okay, I'll do that. And then, of course, the students don't know what they're doing and they have to be guided and corrected. So, after all of this, but no, not quite. So writing code is actually engaging. I think Sarah, you had an awesome question. I mean basically the alternative that is to get students writing code in a structured way that they know what they're supposed to achieve and that the sooner you can get people hands-on, the better and that leads into. Okay, so that leads into how we actually do it. So this is very familiar to all of you guys. In fact, I'm sure you've all done this. I don't know if you've all seen this. This is a poster I made at Pivotal. You can actually download Iowa's version off of Flickr if you want. Mr. Clean used completely without permission, sorry. But I believe parody is fair use. Don't quote me on that. I'm not a lawyer either. Okay, so you've already done this. Do we want to get into failure? Do we want to get right into the code? I think we should just. Okay. I think we've said all of this. We haven't said about the errors, but it's important that students aren't freaked out by errors every time they happen. And so. Actually, I have a really important point to make about this. One of the things that Task Force Teaching does, which I love, is that the students, the really good students who are like following your every instruction in a traditional class, they don't get to see the errors. They don't get to run into problems because they're listening very carefully and they're following your instructions. And then they go out to write their own code and inevitably it doesn't work. And then they, for the first time when they're completely on their own, they see the confusing error messages that don't always correlate to the code that you need to write to fix them. With Task Force Teaching, the first thing you see is a broken task, a failing task with a syntax, what's some kind of error that is the same kind of error that you're gonna see in the wild. It's got some weird jargon you don't understand and then a file name and a colon and a line number and then some more weird jargon. And from that, the student needs to figure out, oh, I just need to zoom in on that file line and go and play around. And they pick up the weird jargon by osmosis and that's a wonderful thing. So we call this embracing failure as the little turtle doves have embraced the fail well. So you and your students must embrace the stack trace. And I think, yeah. Yeah, so the key thing is that learning happens best when you're happy and playful and relaxed and engaged. And that can be hard when you're programming because things don't work and it's very frustrating. But if you start off the students with its failing and it's not your fault and that's just the point of the beginning, then they get into that and they don't get attached to their own confusion and failure and it's so rewarding when they make it work. So there are more things than test-driven exercises that go into a good class. So I think we have time to go into this, but I just wanted to have said that there's, I think, with so many teachers in the audience, you all know what I just wanted to underscore. There's a lot to teaching in addition to these exercises. Okay, so here's some examples. Are you ready? I'm gonna try to go through these, not quite as quickly as Yehuda did, so that maybe some of you could actually read the code. No offense to Yehuda. Okay, so here's an actual example. Can you guys read that, okay? I wanna read the font so small, nobody can read it. Yeah, I don't know, can you read it? We could go in and fiddle with the font. Okay, it's fine on the back. So this is a very basic example. It's one of the first ones that students in the Ruby curriculum encounter where we just make a new object and it's a calculator and we try to add zero plus zero equals zero. This is one of the keystones of test-driven development that we're kind of smuggling in. We're sneaking in this concept that the first thing you should do is the null case, right? And so when the students actually run this file, they see we have a, we use RSpec as you can see for the testing framework for the Ruby stuff and I've actually, yeah, here's what they see. So this is, oh my gosh, a whole bunch of failures, right? So they have to go back in and make that first one pass, right? And all they have to do is write a class calculator and then it'll fail for a different reason and then they have to say def add and then it'll fail for a different reason and then they have to say, oh, parentheses x comma y, right? And then it'll fail for a different reason and then oh, right, it should return zero. And each of these failures is a teaching moment because you can illustrate what the Ruby behavior is when you have those little lines of code. So sometimes we do exercises with students sort of in front of the room, like we'll pull up a victim and pair with them and have them walk through it and sometimes we let them do it on their own and the students walk themselves through these little moments of failure. It depends on the actual setting. I think we thought that a volunteer. No, no, victim, victim. So I was just gonna say, I've now hacked our spec to fail after the first failure which is kind of good, but I'm having trouble actually making that work when you're deeply nested in a subdirectory and I don't wanna teach the students how to alter the path variable and run a custom binary and that kind of thing. So maybe I could use some help from someone in the audience on that too. There might be a way to do it with Rake or something else I haven't thought of. Okay, so here's another example. Oh, just to go back to the calculator one more time. By the end, if we have been holding the hands of people through the first three, we definitely wanna let them do the fourth one on their own, the subtract, right? Which applies all the lessons that they've learned in the first three tests to make a whole new method that does a whole new thing. Okay, so here's an example of how we teach strings. Again, we're trying to make it playful and fun so we're teaching them how to make a translator from English into Pig Latin. Who here speaks Pig Latin? Surprising number of people don't speak Pig Latin. Okay, and I think they'll be able to do it. So at any rate, this is actually fairly... Come back up to us afterwards, we'll translate for you. Yeah. Okay, so it turns out this is actually pretty fun because by the time you get to the very last test, you've actually learned a fair amount about how to correct an algorithm that was too simple. You have to add some special cases. Like on the last one, we snuck in quick where, uh-oh, that's like a consonant that you have to add A-Y-2. Sorry, it's not just a single consonant, it's the Q-U that's the sound. And so we have to have a special case in the example. So for those who don't, maybe I should do the trans. For those who don't speak Pig Latin, you take off the consonant sounds at the beginning of the word. You add it to the end with an A-Y. And so it's Iqqui. Right, okay, sorry, I've been assuming you would all just read this and process it. Yeah, so the Pig Latin for stupid is up-it-stay. So you take off the first string of consonants and add A to it and stick it on the end. And then for words, you do the same thing. E-pi's, E-day, I-pay. And then for the quick round five, it's E-ve, Iqqui, Andrei, Oxfey. Right, that's Iq-pay, Attenway. It turns out this is a great exercise for learning strings because in Ruby, as most of you, all of you know, there's lots of different ways to do the same thing with a standard library with strings. So this is one of the answers we got from, I think this was from an instructor, but it might've been from a student. And then this one was definitely from a student, right? Which is exactly the same, the same results, but completely different. They're both using regular expressions, right? And then this is also using regular expressions, but it's also appending stuff to an intermediate string rather than just using plus, right, as this one did. So it's really fun looking at the solutions the students, you know, the different students or student pairs come up with, right? So we can also use this to teach not just strings and arithmetic, but Ruby stuff, like iterators. So here we're extending the calculator, which we built, you know, yesterday or whatever, to work on series of numbers rather than pairs of numbers. And so here instead of having an add method, well, the sum method that takes an array that forces you to iterate through all of them. I'm not gonna show you any more of the answers because that would be cheating. Okay, and then of course, if we wanna be really fancy, we could teach open classes, right? With that same code that we added to the calculator, why not just make a method on array? And so that'll be very confusing and weird and people are gonna be like, what do you mean you can just reopen array? Well, you know, whatever. And it's like, yeah, you can, but don't publish that in a jam. Because that would not be open classes, that would be a monkey patch. Very subtle difference. And then what we wanna point out is that this is, as we were saying, we wanna smuggle in test-driven development concepts. And so we give in some of these exercises a little extra credit at the end where students can go on and write their own tests and code, which isn't quite the same as teaching test-driven development, but it's getting there. I just wanna show you a few things that are impossible. Things you might think are impossible. No, no, they're actually, okay. As right now, you might be thinking, but wait, how do we write a test for blocks? Or how do we write a test for time, right? When we're using, or how to- And this picture that you probably can't see because it's too dark. This is the photo of him. Oh, yeah, you totally can't see. There was a stool. There's a stool under there. There's a stool under there. You can't anyway, like that. Okay, so, you know, we only have five minutes so I think I'm gonna buzz through this. I'm just gonna say there are ways if you as a teacher are clever enough or maybe lateral enough to think through it, you can build tests for weird things including testing blocks, like proving the functionality of blocks and lambdas in Ruby. You can even do method missing, teach method missing by calling a method that isn't declared until later. And sorry for the Java, but you can even test threads. This is lifted from the Java part where we test thread safety where basically we have the students test drive a depositor and a bank account and then we make 50 different depositors, bomb 50 threads and have each of them deposit 25,000 times and try to get a race condition, right? So that's an interesting way since we've written this code where we're trying to force a race condition to happen, the students have to have written thread safe code on the back end or else this test will fail, right? And this is kind of a lesson for some things you can apply in your own test suites, maybe not in your unit tests but this is more of a integration level thing that you want as a sanity test. Anything more to say about that? No, we just, so we go through that. Yeah, Ruby Cohen's are another great example and I would be remiss not just because Jim is in the audience but because Ruby Cohen's is actually kind of better than our stuff. It's certainly much more finely polished and more widely used. Ruby Cohen's are basically a self guided test driven way of learning the Ruby language and it's probably geared more towards people who know how to program already whereas a lot of our stuff is tutorial towards people who may never have programmed or it might have been awhile since they took a class in college and it's very elegant. So everybody should check out Ruby Cohen's if you haven't already. Who's used Ruby Cohen? Yeah, excellent. So, quickly, test first teaching is not TDD. That's a whole nother class but I think it prepares you well for it because you learn the mechanics of testing and then you can learn about test driven development. Lastly, we have some credits and thank you Flickr and Creative Commons for making it so that we could have illustrations. And I think I'm Sarah Allen. My Diverse is my startup company. I also lead a consulting company called Blazing Cloud which we have new branding now for checkoutblazingcloud.net and we have Ruby and Rails classes in San Francisco. If you wanna brush up on your TDD or you know people who wanna learn Ruby and Rails you can go to JavaScript HTML. And that's me, I think. Yeah, that's me. And I've created or contributed to a bunch of stuff that you may have heard of and probably never used except for Pivotal Tracker which I was the co-creator of. And recently, Steve Conover and I made a testing framework named Wrong and it feels to me very wrong that it wasn't in the list of testing frameworks this morning. So I just wanted to say it since I have the microphone. I ran out of screen. Sorry. It was alphabetical and I ran out of screen. Oh, it was alphabetical and you ran out of screen. That's a likely excuse. I bet you, I bet you. I will assert you wrong, sir. We wanted to leave that learning should be fun and I don't know if we have time for questions. I think we have two minutes, right? Look, I see, we started five minutes late. So we think we should get at least two minutes. What do you mean? Okay, if you have questions. This is a party. If you have questions, come up. It would be like talking very quickly. Yeah.