Afrikaans
Akan
Albanian
Amharic
Arabic
Armenian
Azerbaijani
Basque
Belarusian
Bemba
Bengali
Bihari
Bosnian
Breton
Bulgarian
Cambodian
Catalan
Cebuano
Cherokee
Chichewa
Chinese (Traditional)
Corsican
Croatian
Czech
Danish
Dutch
English
Esperanto
Estonian
Ewe
Faroese
Filipino
Finnish
French
Frisian
Ga
Galician
Georgian
German
Greek
Guarani
Gujarati
Haitian Creole
Hausa
Hawaiian
Hebrew
Hindi
Hmong
Hungarian
Icelandic
Igbo
Indonesian
Interlingua
Irish
Italian
Japanese
Javanese
Kannada
Kazakh
Kinyarwanda
Kirundi
Kongo
Korean
Krio (Sierra Leone)
Kurdish
Kurdish (Soranî)
Kyrgyz
Laothian
Latin
Latvian
Lingala
Lithuanian
Lozi
Luganda
Luo
Luxembourgish
Macedonian
Malagasy
Malay
Malayalam
Maltese
Maori
Marathi
Mauritian Creole
Moldavian
Mongolian
Myanmar (Burmese)
Montenegrin
Nepali
Nigerian Pidgin
Northern Sotho
Norwegian
Norwegian (Nynorsk)
Occitan
Oriya
Oromo
Pashto
Persian
Polish
Portuguese (Brazil)
Portuguese (Portugal)
Punjabi
Quechua
Romanian
Romansh
Runyakitara
Russian
Samoan
Scots Gaelic
Serbian
Serbo-Croatian
Sesotho
Setswana
Seychellois Creole
Shona
Sindhi
Sinhalese
Slovak
Slovenian
Somali
Spanish
Spanish (Latin American)
Sundanese
Swahili
Swedish
Tajik
Tamil
Tatar
Telugu
Thai
Tigrinya
Tonga
Tshiluba
Tumbuka
Turkish
Turkmen
Twi
Uighur
Ukrainian
Urdu
Uzbek
Vietnamese
Welsh
Wolof
Xhosa
Yiddish
Yoruba
Zulu
Now, before we go any further, take a moment to pat yourself on the back.
You are halfway through the Ruby course.
Woot!
And in the second part of this course, the game that you've been writing will get a
lot more interesting and fun.
But herein lies a potential problem.
In order to figure out if we're getting the results we expect in the game, we actually
have to run it.
We set Larry's health to 60, we play the game, which right now is one blam and two
roots, and then we check that Larry's health is 80.
We have to do that math in our head.
And as we make the game more interesting, we're also going to make it a bit more sophisticated.
This means there'll be more to check, more math to do, more to remember to check, more
to keep in our heads.
So what we need is an easier way to ensure that the functionality we already have, we
don't go and break it.
And the best way to do that is by starting to write some unit tests now.
Thankfully, Ruby has a strong culture of testing.
In fact, Ruby ships with a unit testing library called Test Unit.
Now here's the thing, all these testing libraries basically give you a way to do the same thing.
Run parts of your program, get back some results, and then check that the results are what you
expect.
In this course, we'll use the RSpec library.
It's used pervasively by both the Ruby and Rails communities, and also gives us an opportunity
to learn how to use an external Ruby library.
All right, now testing is a huge topic.
In fact, it's a course all to itself.
Our goal here is to simply get you started.
We're not aiming for 100% test coverage.
Yeah, specifically, we're going to look at writing tests for individual classes and methods,
often called unit tests.
So let's head over and get started.
Now the first thing we need to do is install RSpec.
Yeah, RSpec doesn't ship with Ruby.
It's actually an external library that's distributed as a Ruby gem.
Right.
We just call them gems.
Yeah, just gems.
And gems make it easy to download, install, and use external libraries like RSpec.
So let's get RSpec installed.
Perfect.
We do that by typing gem install RSpec.
And the RSpec gem actually has dependencies on a few other gems, so we end up with four
total gems installed.
So now we're ready to write tests for our movie class.
Sure.
We'll just go back over to our TextMate file, and we're going to create a new file inside
of here, inside of our directory here.
I'm just going to call it movie, and the convention is to call it underscore spec dot rb.
And at the top of this file, we want to require our movie file because we're going to be testing
our movie class.
And then we're going to start specing out what the movie class does.
So the first part of that is we're going to say describe.
Now this is part of RSpec's domain-specific language.
So this is all Ruby code.
It just has its own little vocabulary in here.
We're going to say describe a movie, do, and it takes a block, so it's a do-in structure
there.
Then inside of the describe block, we add what are called code examples.
We do that using it, and then we type in what we want a movie to do.
So it has a capitalized name, for example.
Actually, it's a capitalized title.
And then it's got a little block structure.
So now we can actually spec out the movie.
So we're going to say I'm going to set up a movie, and the movie is going to be, yeah,
Goonies with a rank of 10 is good.
So that's the sort of setup.
When we have a movie in that state, now we can write some expectations about it.
So we expect that when we call movie.title, we're going to get the capitalized form of
Goonies.
So the way we write the expectation in RSpec is RSpec adds this method called should to
every object as a way of making this a little bit more readable.
So it says movie.title should, and then we use equal equal.
That's the comparison operator, and it should equal the string capital Goonies, just like
that.
Now just bear in mind, this is equal equal.
It's not a single assignment operator.
We're actually doing a comparison there.
Okay, then we save that file.
We can hop back out on the command line.
And then to run this RSpec file, we type RSpec.
That's a command utility that was installed with RSpec.
We give it the name of our movie spec file, moviespec.rb.
And we see we got this one little dot at the top, and it says one example and zero failures.
Now I like to run this with some color.
You can pass in a dash dash color option like that, and we get a nice little happy green
dot with our output.
No gold stars, just green dots.
Just green dots, yeah.
Now I'm never confident about the first test I write.
Is it actually testing something?
So let's come back over here and let's make it fail.
If I go into the movie file, and let's just change this.
Let's say we forgot to capitalize the title, so I'm just gonna comment that out, bad programmer.
And we come back out to the command line, we run it again.
Oh, now we get some red failing messages here.
And we see movie title should equal Goonies.
It says expected uppercase Goonies got Goonies using that equal operator.
So we are actually testing something.
We can go back into our movie and put the capitalize back on there, come back out to
the command line again, and now we've got it all back to green.
Let's also show them how to run it in Textmate.
Sure, over in Textmate, if we open the movie spec.rb file, we can just run it inside of
Textmate because of the RSpec bundle here.
And if I run it, I get the same green color coding.
And it actually says movie has a capitalized name.
So it printed out that string that we had in the it block.
We get a green bar instead of a green dot.
There you go.
Yeah.
Now let's write another test.
Let's test the initial rank.
Sure, we'll just have another code example for that.
So it starts with it, we'll just say has an initial rank.
And then inside of that, well, we're going to need another movie object, and I'm going
to do some copy paste coding for a while.
We'll clean this up a little bit later.
So there's our movie.
Each of these it blocks runs on their own.
So we can't access inside of this it block, we can't access this movie.
So we've got to set up a new movie object here.
And I'm going to say movie.rank.
It should equal 10 because that's the value that we actually passed in.
So I'm going to go ahead and run this inside of TextMe.
And sure enough, we've got two green bars here.
You know, as you were writing those, I found myself thinking about the other code examples
I want.
Like I want to test the 2S and the thumbs up and the thumbs down.
And I kind of don't want to forget about the tests that I want.
So maybe we could create a list of examples.
Sure.
Then we can just cross them off one by one.
Right.
So what's the next code example we want to write here?
Well, let's see.
Movie has a 2S.
So let's test that.
That's a string representation.
So let's just add that to the list here.
We can just use an it block and then we'll say has a string representation.
And if we don't give it a do block, what happens and we run this now, we get a pending test.
So you see it turned it yellow and the yellow one is has a string representation.
It says pending, not yet implemented.
Back out on the command line, if we run it with coloration, we get some yellow colors
there and we also get this pending marker.
Movie has a string representation.
So we've got a little to do list started here.
So we also want to test that we increase the rank because we have this thumbs up method.
So let's write a test that says it increases rank by one when given a thumbs up.
From your mouth to the specs itself.
And then we have our thumbs down method.
So we should test that too.
It decreases rank by one.
Decreases rank by one when given a thumbs down.
All right.
So we've got our list of three specs that we want to write.
So let's start knocking these off the list.
We have the first one, string representation.
We need a do block there.
All right.
We're going to need a movie for that.
Just like everything else.
We need a movie.
Goonies or rank a 10.
That's fine.
But our expectation is when we call movie 2S, it should return a string that says Goonies
has a rank of 10.
I think there's a period at the end, but the tests are going to tell us.
So if I run that.
No.
Goonies has a rank of 10 was expected with a period, but we don't have a period in our
2S method.
So let's take that off.
Run it again.
Okay.
Now we've got that one all fixed up.
So let's tackle the other one down here.
Increases rank by one when given a thumbs up.
It should actually be increases.
We'll fix the documentation there.
All right.
So I'm going to do this one a little bit different.
What we want to have happen is we want an initial rank set.
We want to create a movie.
We want to thumbs up it.
And then we want to compare that initial rank.
We want to compare the new rank to its initial rank.
So to do that, I'm going to create an initial rank variable.
I'm going to set it to 10.
And then we'll create our movie object.
We'll shortcut there.
We'll leave it at Goonies.
And then we'll just pass in the initial rank like that.
Then our expectation is, or actually then we have to do something to the object.
So we call movie.thumbsup.
Then our expectation is when we look at the rank of that movie, it should equal the initial
rank plus one.
So it should have increased the rank by one.
Yeah?
Yep.
Run that.
We've got one more crossed off the list.
We're on a roll.
So this last one is very similar to the one before.
I just need a little space there.
Let me just take this.
We're going to clean this up in a few minutes.
In this case, we're going to decrease the rank by one.
So we're going to call thumbs down here.
And the initial rank should decrease by one, just like that.
How do we do?
Green across the board.
So now we have specs for our movie behavior.
And if we break something going forward, we'll know about it.
Yeah, I love the confidence that that gives us as we continue to code.
But we do need to do one thing before we go too much further, and that's clean up all
this duplication in the tests.
So let's do that.
So let's have a look at this duplication.
We've got a couple lines here.
Those are also repeated in this little spec here.
And then in each of these above, we're creating a new movie.
Clearly, we don't want to be doing that.
So let's just take one of them from down below.
I'm going to take these two lines and just copy them.
And we want to do this in one spot in our code.
And in our spec, we can do that in what's called a before block.
It takes a block structure like that.
I can just paste that code in there.
And this code is going to run before every it block, before every code example here.
Now we need to use instance variables for these so that they're accessible down in those
code examples.
So we've got instance variables for initial rank and for movie.
Now down inside of the code examples, we can remove this line because it's going to be
set up in the before block.
We just have to change this to an instance variable.
The same way, we can remove this line here, change it to an instance variable, change
this one.
So we're just refactoring some code here.
That one's OK.
This one, we've got initial rank and movie already set up.
So we'll change that to an instance variable, that one as well, and initial rank.
Same thing here.
Just cleaning these up nicely a little bit.
All right?
So we've got all that extracted up in the before block.
Now if we run our tests, hopefully they all pass, and they do, so our refactoring there
was successful.
And we've removed all the duplication, which is kind of nice.
You know, we forgot to add one test.
Uh-oh.
A movie can have a default value for its rank.
Well, that gives us a good opportunity to look at another feature of our spec, context.
A context gives us a way to organize examples with similar setup within a spec file.
And you're talking about something having a default rank.
So we kind of have a movie that's set up a little bit differently than the one we have
up in our before block now.
So let's create a context for that.
I'm going to give myself a lot of space here.
Context, we can give it a name, created with a default rank.
So this is a movie created with a default rank.
It's a block structure.
Inside of here, we can have another before block.
And inside of that before block, we'll create a movie fitting this context.
So it's going to be a movie.
It's going to be a new movie.
And it's just going to be Goonies.
We're not going to pass in an explicit rank here.
Right?
So for that context, then we can start to write an example.
In this case, it's going to be has a rank of zero.
And then inside of that, we can put the expectation.
So the movie, movie.rank should equal zero because we know the default rank is zero.
So we've got a context here that does a couple things.
It sets up some common code to demonstrate that context.
And then we make assertions or expectations against that code to make sure it's doing
what we expect it to do.
So let's go ahead and run that.
And you notice when I run in TextMate, I've got all the regular code examples, but then
nested down in that is a movie created with a default rank has a rank of zero.
It kind of reads like you would write something like a software spec.
If we look at that on the command line, you notice we don't get it with the default color
option, but if we pass in the dash dash format and dock option, it'll neatly nest these.
We see movie created with a default rank has a rank of zero.
Remember, this is just a start.
The test may seem trivial at this point, but it's critical that we get a good foundation
of tests in place before we start to add more functionality.
That's a really good point.
So in the exercise, you're going to have a chance to add some tests to your game.
And then when in the next section, we're going to look at conditionals.
This means we'll be able to randomly woot or blam our players, which means the outcome
in the game won't be the same every time.
Happy spec-ing!
We're going to look at conditionals so that we can randomly woot or blam your players.
Randomly woot and blam!
Okay.
All right.
So take a few minutes to put some tests in your game.
The next section, we'll look at how to use conditionals.
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.