Cookin' with Ruby on Rails - Designing for Testability
Pages: 1, 2, 3, 4, 5, 6, 7

CB: So now we've got a test database, but it's empty. We need tables to put our data in. Rails wants to make testing easy; something we really have no excuse to not do. So it provides us with a set of rake tasks that do the "heavy lifting." All we have to do to recreate the tables that exist in our development database is...

rake db:test:clone_structure

creating tables in our test database
Figure 5

Paul: It doesn't look like it did anything.

CB: Yeah. Depending on how the rake task is coded, sometimes it only tells you if it has a problem. Easy way to check is just to open up your database front end of choice and take a look.

So here's our development database...

development database schema
Figure 6

and here's our test database.

test database schema
Figure 7

Paul: Wow. That was easy. What about data? Did Rails copy that over too?

CB: No. The manual testing we're doing in our "normal" development pretty much needs a close approximation of our production data. Customers seem to find it easiest to test when they can exercise the system using the data they're used to seeing. But successfully using automated testing requires a different approach to test data; one some folks refer to as "engineered test data." The data we'll put into our test system is exactly what we need to test the system; not more and not less. If we do it well, that is ;-).

Paul: Oh boy ;-(. I knew there'd be a catch. The contract tester that's been talking up the GUI test tools started talking about the need for "engineered data" the other day. Boss was standing there and said he'd never heard the phrase before, so I asked her about it. She started talking about a whole new project to go back into all the test plans and figure out what data was being used. Of course, that was after they'd gone back and re-executed everything to make sure the plans were still valid, added detail to the existing test cases, added new test cases, and on, and on... She was all "wouldn't this be great?" I could tell from the veins in his neck that it was all Boss could do not to say something less than complimentary. In the end, he just said, "Hmm. That's interesting. We should think about that." And then he excused himself. I don't think I want to revisit that topic with Boss, if you know what I mean.

CB: I do know what you mean. The difference between that and this comes down to one word: Legacy. Working with Legacy systems is expensive; no question about it. And if there's one generally accepted characteristic that defines a Legacy system it's the absence of automated tests. Remember the first day you and Boss came by on this? Remember me saying to him, "One of the things that Rails really enables, Boss, is an iterative and incremental approach to development." And remember me saying just a few minutes ago that testing is an integral part of Rails? There's one guaranteed way to avoid the situation you just described: stop building Legacy systems. I realize your "day job" makes it a little difficult to see how this could possibly work, but... well, maybe it'll be easier to just show you.

We're going to create our test data in what're called "fixtures." Remember that there are three types of tests in Rails. Working from the top down we've got Integration, Functional, and Unit tests. The basic top-down relationships for each type of test looks like this. Test results get produced by executing test cases which consist of test methods which use test data, much of which is specified in test fixtures. So, we'll start at the bottom-bottom and work our way up.

You probably don't remember seeing it, because I didn't draw your attention to it at the time, but when we generated our scaffolding for the recipe and category models and controllers, Rails actually produced the stubs we need to do our Unit and Functional testing of them. Let's take a look. The test fixture files are in the test\fixtures directory...

categories fixture
Figure 8

 recipes fixture
Figure 9

And the test case files are in the test\unit directory. Here are the Unit-level test cases...

category fixture
Figure 10

recipe fixture
Figure 11

Paul: OK. They definitely look like "stubs." What do we need to do to them to make them useful?

CB: Well, like many things in Rails, they may not do a lot right now, but they'll already do something useful. Let's take a look at what happens when we run the test cases. Let's start with the category test. From the application root directory, run it with

ruby test\unit\category_test.rb

category_test stub run results
Figure 12

CB: And now let's run the recipe unit test.

ruby test\unit\recipe_test.rb

recipe_test.rb first run
Figure 13

Pages: 1, 2, 3, 4, 5, 6, 7

Next Pagearrow