00:00:07.060
Thank you! There's popcorn downstairs, and Andres is downstairs now. Here we've got this to mark.
00:00:12.710
J-Mac is a big person with a big smile who loves big hugs. True? Bring it here!
00:00:20.750
Okay, bringing the big booming bear hug.
00:00:27.290
The hug is authored by a programming book in CoffeeScript. He's Paul McCartney's cousin.
00:00:32.630
Don't ask him to sing. Please welcome my fate—and so did that!
00:00:43.670
I want to just give you an introduction. I am NOT Paul McCarthy's cousin, but ask me later, and I do have a really, really good Paul McCartney story for you.
00:00:49.609
I am also not Ryan Bates, if that is what you were expecting to see. Hi Josh, thanks for coming!
00:00:55.789
I am the author of three books: "Programming in CoffeeScript," "Distributed Programming with Ruby," and my latest, "Conquering the Command Line." I have some to give away!
00:01:04.250
This is what it looks like when you win one! I'm very excited—this is not me trying to bash my head on this thing, by the way.
00:01:10.790
So, if I suddenly fall unconscious, don’t be alarmed. I do have a couple of giveaways.
00:01:20.630
Before I do that though, I'm also the voice behind a site called Metacast.TV. It features weekly screencasts about Ruby, Rails, JavaScript, Postgres, and Go.
00:01:27.420
It's a lot of fun! Enjoy a free month of Ruby AU 2014, and learn about all sorts of things. So before I give away books and before we dive into MiniTest, I know who really went to the GitHub drink-up last night!
00:01:40.549
Good number of people. Who here flew in from really far away very recently? And who here is just generally tired this morning?
00:01:52.880
That's what I thought, so let's all stand up! If you said you weren’t tired, we wouldn't do this. Let's all stand up!
00:02:05.780
There we go, let’s get the blood flowing. Everybody stand up, come on. Roko t-shirt, stand up! It's a small room!
00:02:12.560
Now, everybody reach up into the sky! Good! Now reach out for every t-shirt!
00:02:19.340
Alright, let’s all do some twists. Everybody do some twists! Stretch it out!
00:02:24.410
Waking up, that’s good! We like to get people moving.
00:02:32.060
Now everybody, let's stay standing for just a minute.
00:02:37.510
Today we're going to take a big look at MiniTest. Alright?
00:02:43.340
This is the Green Dot—it’s what Rubyists love! I’ll be honest, my wife is here with me in Sydney.
00:02:48.650
If she wasn't, I'd probably be making out with the Green Dot in my hotel room at night! That's how much I love the Green Dot.
00:02:55.070
Nothing makes us feel better than to see a bunch of green dots going across our screen.
00:03:01.940
Red dots make us sad, green dots make us happy! When we see a screen like this, we all know we can sleep well at night.
00:03:08.239
We know our code is perfect, wonderful, and very well tested. Okay, maybe not perfect, especially if you're writing Zach's code.
00:03:14.239
But, it's at least somewhat tested, right? Green dots make us happy.
00:03:19.610
Alright, let's get back to serious business.
00:03:24.880
The first thing we do when we set up a new project is set up a testing framework.
00:03:32.000
At this point, you usually think, 'Oh my god! I should write my own testing framework, because how hard could it be?' Who here has thought that before?
00:03:37.810
Raise your hand! At least one person has.
00:03:45.310
I'm here to say, please don’t! And I’ll tell you why.
00:03:51.350
There’s a site called the Ruby Toolbox; who here has heard of the Ruby Toolbox?
00:03:58.519
Fantastic! It's an amazing site written by a big hulking German guy named Christoph.
00:04:03.590
If you see Christophe, buy him a drink. He smokes a lot, drinks a lot, so he’ll be open to that!
00:04:10.790
But the Ruby Toolbox is a great place. You can go find a new plugin for your app.
00:04:15.980
I want to write that tags for my application, what's the latest and greatest?
00:04:22.040
It gives you a lot of information. Here is the MiniTest one, for example.
00:04:29.780
It tells you the last time it was updated, how many commits, and how many downloads.
00:04:37.909
It's a really helpful tool to get a good idea of what these plugins are and what they do.
00:04:44.810
I did a little search for testing unit testing plugins, and these are some of the ones I found.
00:04:52.340
I know RSpec, MiniTest, TestUnit, Bacon, and it starts getting a little wonky as we go along here.
00:04:59.140
Other people have had your idea, and I'm here to tell you, don't do it!
00:05:06.120
The reason is we already have MiniTest. MiniTest is already with us, and it's there every day. Most people don’t realize we have it.
00:05:14.300
Good things indeed come in small packages, as we can all agree. The Mini Cooper—everybody loves the Mini Cooper!
00:05:21.169
Mini me, who doesn’t love Mini Me?
00:05:26.270
You get mini bottles of booze on airplanes that make you feel like a giant!
00:05:31.460
And when you hold them, it’s a fun feeling!
00:05:36.589
Anyway, back to the topic of MiniTest: MiniTest comes in eight files.
00:05:41.180
Honestly, there are about three that actually do anything. For example, one is a gay pride formatter that will rainbow color your test results.
00:05:50.419
It’s awesome, although probably not incredibly useful.
00:05:56.120
It really comes down to about three different files that make up a solid testing framework.
00:06:02.659
This is a little bit of what MiniTests look like. This was the MiniTest spec; it looks very much like RSpec, as we will see going forward.
00:06:10.249
This is MiniTest unit, for those of you who have a preference for test unit.
00:06:16.279
Now, one interesting thing to note about these two files I just showed you is if you were to take the time and quickly type these into Vim or Sublime.
00:06:23.629
Then run them as Ruby; chances are they would run for you and the tests would actually pass.
00:06:30.919
And we did that without any gems! How the heck do we do that?
00:06:38.029
It ships with Ruby people! It's there, on your computer, already!
00:06:46.599
If you have Ruby greater than 1.9, and why don't you if you don’t? Seriously!
00:06:54.229
If you have Ruby 1.9 or above, you already have MiniTest.
00:07:00.120
You have what you need to run testing. It is also available as a gem.
00:07:10.810
The reason why it's available is that the gem is easier to develop outside of the Ruby pipeline.
00:07:17.440
So I highly recommend you use the gem. You can install it with 'gem install mini-test'.
00:07:23.630
But if you're on a long flight from LA to Sydney with no internet, you can still write tests without needing Bundler.
00:07:30.510
It has a very familiar syntax to RSpec.
00:07:37.550
Who here has used RSpec before? Who here has never used RSpec?
00:07:44.790
Now, I know you're timid... who here uses TestUnit?
00:07:52.640
Really? Oh, you poor thing! We'll buy you a drink later to help you out!
00:07:58.740
So, Ruby 1.9 refers to MiniTest to replace the TestUnit in the Ruby core library.
00:08:06.360
Thus it is readily available to you.
00:08:12.630
We'll take a quick look at the basics, and some of the differences between MiniTest, Spec, and Test Unit.
00:08:20.399
Who here is involved with Rails and are you excited?
00:08:27.680
It’s coming up. I think it has a bright future.
00:08:34.299
So, here's a basic MiniTest spec: describe something, do it, it does something.
00:08:41.640
These are all very RSpec-like. If you already know RSpec, you know what you need to be familiar with MiniTest.
00:08:45.270
I could probably end the talk right there and still cover before and after setups and teardowns.
00:08:51.360
We can do nesting, just like we'd expect!
00:08:56.630
For those who don't know what lets are, lets memorize or encapsulate what's inside that code block.
00:09:03.240
That allows us to access another place, just like RSpec.
00:09:07.890
We also have subjects, just like RSpec.
00:09:13.920
What’s fascinating about this is that I keep saying 'just like RSpec', but if you go into a project that uses RSpec and do 'bundle open RSpec'...
00:09:20.320
You can see how many files are there.
00:09:27.320
Then do 'bundle open' on all the files for all the gems that RSpec requires.
00:09:31.890
Then go and look at the MiniTest code to see how much they can do in three files.
00:09:38.310
Versus what RSpec does in about six gems.
00:09:41.720
It’s important to see, you can achieve similar results.
00:09:44.240
Context blocks, we can’t do context blocks in MiniTests.
00:09:50.050
If you run that, you get an undefined method context.
00:09:56.790
But we can fix that easily by aliasing it off.
00:10:02.870
It's quite simple to alias context to describe—it’s just pure Ruby!
00:10:08.650
We can do pendings with MiniTests.
00:10:14.870
There are three different ways to do that: it does something without a block.
00:10:21.180
We can skip it, or we can skip with a message.
00:10:27.920
Pretty straightforward! Run that, and you'll have a bunch of successful tests.
00:10:33.850
Expectations, this is one of the things I like most about MiniTests.
00:10:39.350
It's got really nice expectations that are very simple.
00:10:44.390
They don’t clutter up your object space like other testing frameworks such as RSpec.
00:10:51.830
These are the expectations that are included with MiniTests.
00:10:57.820
They all start with 'must_'.
00:11:02.350
So when you're looking at the methods that are available, you know which ones belong to MiniTests.
00:11:07.510
They all run with 'must_' which keeps things neat.
00:11:14.610
You won't pollute the kernel object space or your object’s space.
00:11:22.100
It’s very clean and simple, like 'must be empty', 'must respond to', 'must send', 'must have output', etc.
00:11:27.350
Also, the opposite is 'won't'.
00:11:31.640
If you know one, you'll remember the other. For instance, 'must be' means it won't be.
00:11:38.850
Or 'must match' meaning it won’t match. Very straightforward!
00:11:44.610
Here's a little code showing you what a bunch of them achieve.
00:11:51.490
You have 'must raise', 'must include', 'won't include', 'must be nil', 'must be empty', and many more.
00:11:56.500
I love the assertiveness of this framework. It’s not wishy-washy; it clearly states expectations.
00:12:01.720
It should be equal and not hopeful; it’s definitive!
00:12:09.100
Here’s an example of some of the expectations in action.
00:12:15.370
It’s very direct with things like 'must raise', 'must include', and 'won't include'.
00:12:22.480
These offer great clarity in your testing.
00:12:30.000
Much of what we accomplish with assertions can be done simply, without any convoluted syntax.
00:12:37.840
It’s quite refreshing!
00:12:43.670
That said, if we compare this to TestUnit, we can create assertions that don’t affect your namespace.
00:12:52.720
It allows us to assert truth or falseness without contaminating our object.
00:12:58.560
You won’t find these methods on the objects you're testing.
00:13:06.060
That approach garners extra respect for Ruby as a testing language.
00:13:11.570
Many tests support mocking and stubbing.
00:13:18.040
Who here does a lot of mocking and stubbing?
00:13:24.000
Cool! The rest of you should do a lot of mocking and stubbing!
00:13:29.160
Your tests will run significantly faster that way.
00:13:36.930
Testing support in MiniTest is very basic.
00:13:43.920
There are only about three real files involved.
00:13:49.950
Let’s break this down further.
00:13:56.510
You get a MiniTest mock: you can create a mock object.
00:14:02.670
You can set expectations on it.
00:14:06.020
The verify step ensures those expectations are met.
00:14:14.370
You can also stub on an object with a stub block.
00:14:21.060
We do the same thing; we have an instance of something and stub the method.
00:14:29.370
These techniques are effective, allowing your tests to run smoothly.
00:14:36.000
Ruby also excels in mocking and stubbing.
00:14:43.200
Let’s create a struct that behaves as if it had a complex object.
00:14:51.000
You can replace heavy network classes with a struct or an open struct.
00:14:57.080
This allows for cleaner, simpler tests.
00:15:04.410
This method fades away when the instance is disposed of.
00:15:09.640
Many tests demonstrate that we don’t need a complex mocking system.
00:15:16.230
It’s all built into Ruby!
00:15:21.120
However, there are great mocking libraries available, like Mocha and FlexMock.
00:15:28.150
These offer certain levels of convenience.
00:15:37.410
You might feel inclined to write your own, but please don’t!
00:15:44.980
Instead, go to Ruby Toolbox and check what's already been done.
00:15:51.000
You'll find alternatives to save you time.
00:15:58.920
Custom assertions are easily made in MiniTest.
00:16:06.180
Who here has created custom assertions in RSpec?
00:16:14.070
A few of you! MiniTest allows for this in a far simpler manner.
00:16:20.340
For example, you might want to create an assertion called 'must_round_to'.
00:16:30.500
You can simply open up the MiniTest assertions module.
00:16:36.919
Create a new method called 'assert_rounded' or name it whatever you wish.
00:16:43.960
Just ensure you assert that it's equal.
00:16:51.320
This method returns true/false, and you can supply a message.
00:16:58.050
Now, here's where it gets even more interesting.
00:17:03.850
You have to do something with these methods created.
00:17:10.320
MiniTest won’t put these assertions on your objects until you instruct it to.
00:17:16.790
You do that by using the 'infect_assertion' method.
00:17:22.408
It's more simple than you may think!
00:17:30.080
So you can etch into numeric values, so that they can round.
00:17:36.970
You're not concerned with how other data types manage that.
00:17:42.920
We have a MiniTest, a spec equivalent, which is really straightforward!
00:17:48.440
We can install a MiniTest spec Rails gem; there's one available.
00:17:55.919
They do need some updates; users may find it somewhat lacking. If you know the author, encourage them!
00:18:01.880
You can create a test helper with requirements as we insert more tests.
00:18:08.230
It's straightforward, incorporating pending task checks and so forth.
00:18:16.360
MiniTest expectations allow you to include effects in blocks.
00:18:25.070
You can, and we generally assert methods for redirecting.
00:18:30.450
You can implement type checks like 'must redirect'.
00:18:37.740
You don’t have to call a myriad of responses—keeping your code clean.
00:18:44.490
I'll reference the slides later; they'll have all these examples.
00:18:51.490
There's a little rake task to set this up, which is a touch of low-hanging fruit.
00:18:57.030
It's instant easy fixes that would benefit anyone learning about the gem.
00:19:07.520
One of the nice things about MiniTest is you run tests with pure Ruby.
00:19:15.550
This means you can avoid chains of commands.
00:19:23.110
Use it directly in your Rails folder!
00:19:29.140
You can seamlessly incorporate standard functionality into your tests.
00:19:34.270
If you like guard, who here uses guard?
00:19:42.500
You should be using it for everything!
00:19:48.500
I rely on it for everything, even silly things.
00:19:56.150
Okay, here's my guard file. It's integral for developing your test process.
00:20:01.670
MGM provides neat enhancements that allow you to optimize testing.
00:20:09.350
You simply don’t need to pass in special flags to obtain results.
00:20:17.330
It optimizes the search for files and knows where to look.
00:20:23.280
If you're active in Capybara, it has provisions too.
00:20:30.840
In conclusion, it's a familiar syntax for those seasoned with RSpec.
00:20:37.800
You likely picked it up quickly and went, 'I already know this!'
00:20:45.330
95% of functionality inherent in RSpec lies within MiniTest!
00:20:52.550
What’s happening in that extra 5% that requires hundreds of lines of code?
00:20:59.030
MiniTest is incredibly lightweight! Look at my gemfile.lock.
00:21:05.650
These show what RSpec requires—note how much is necessary in comparison.
00:21:11.780
Ultimately, you won't need any extras installed outside of what's already present.
00:21:19.660
Quickly benchmark RSpec against MiniTest.
00:21:24.820
Generally, Rails testing is slower, while MiniTest has a better speed rating!
00:21:32.420
And let’s be real: every second counts in development.
00:21:40.500
So I urge you to explore testing solutions while prioritizing both effectiveness and efficiency.
00:21:49.140
Please view the resources I recommend. Check my screencast site!
00:21:55.560
There are references like, 'Perform MiniTest in Rails' which cover all the basics.
00:22:03.930
You can obtain valuable information, and it’s all free at Ruby AU 2014!
00:22:10.750
Now, any questions?
00:22:17.700
Yes, sir! You asked about the 95% that MiniTest covers?
00:22:23.980
The biggest component you're missing is the ability to tag tests.
00:22:31.200
For example, with VCR, you want tags for tests to harness specific behavior.
00:22:39.400
But, there's also a MiniTest gem out there that provides tagging functionality!
00:22:45.940
It's not often I don't use it, but if you want it, the option is there.
00:22:50.740
This shared expectation is an element of that 5%.
00:22:59.760
For tasks that rely on these shared expectations, you can create a module that includes methods.
00:23:06.690
Or you can develop your own custom assertions for those needs.
00:23:12.160
That's important to know! Anyone else have questions?
00:23:19.130
Yes, one more question—kindly hurry as we are running behind!
00:23:25.720
Does MiniTest work well with CI tools like Travis?
00:23:32.730
Yes! It can run any Ruby-related tasks efficiently!
00:23:40.210
Josh could answer this better than I could.
00:23:46.120
Travis runs successfully with MiniTest!
00:23:52.850
So, thanks everybody for your time today. I appreciate it!