Rake in Rails Switching InnoDB to MyISAM

About 11:00pm on April 7th I ran

1
rake

to run all my tests. I had a nasty problem where I went from all of my tests running on the depot sample application in the Agile Web Development Rails book to spitting out tons of errors. It didn’t make any logical sense. The error I saw over and over again was that the first record didn’t exist so the errors looked like:

ActiveRecord::RecordNotFound: Couldn't find Product with ID=1
...
in `products`
  test/unit/product_test.rb:7:in `setup_without_fixtures`

OK, next step was to just try to run a single unit test, so I jumped back to the

1
product_test.rb

unit tests. Run the 6 tests, ugghh, 3 of them error out. I know they were working last time I worked on the sample project.

I commented out all but the first test and started adding them back in one by one. After I added more than ones that just checked the initial values they just started failing again. Gheesh!

So, next solution is look at the logs. Not a lot of information there, but the SQL, so I wanted to add logger statements at the start and end of my tests. Took a bit of hunting to find out how to do it, but Robby Russell had a nice explanatory post on Rails, Logger, and Those Pesky Tests.

OK, I have logging, so I can see what’s going on. At this point I feared I was going to find out the order of the tests perhaps mattered and after deleting one entry the next test failed because it didn’t reset the records in setup(). This isn’t really how xUnit frameworks are supposed to work, but I was having trouble seeing the logic of why the tests are failing.

Run the tests, and the same failures. Look at the log, and yes, they are run in random order and each one ends with a ROLLBACK statement. Of course this makes sense, because under Rails 1.0 and up the default is to use transactional fixtures. At this point I decide to look at MySQL and the databases. Aha! The database tables are defined as MyISAM which doesn’t support transactions. I could have sworn they were already defined as InnoDB, but maybe I was confused.

OK, I switch them on the test database and then run rake again. No!!! The same huge number of errors. This doesn’t make a lick of sense. OK, look at the database again. OK, the tables are back to MyISAM. So it turns out rake is automatically using the development database to recreate the test database. So a simple change of the development database to InnoDB tables was in order. Run,

1
rake

again and all the tests pass.

Time for some sleep.

30 Day Software Trials

I remembered again today as one of our developers deployed Confluence why 30 day trials are so nice. Like many corporate shops we deal in purchase orders. If we had to wait to get our official license it could easily be 2 weeks before the PO clears with the vendor. In the meantime we can start out using the 30 day license and then just swap in the official license key in about two weeks with no delay.

James Shore On Private Variables and Getter/Setters

It was nice to run across this post by James Shore on the silliness of default getter/setter methods. I’ve posted on this before and Alan Holub has a fairly famous/infamous rant on why Getter and Setters Are Evil.

As just one example of this, let’s look at the simple and popular “instance variables must be private” design rule.

Now for the problem with the rule. People know about the “private variables” rule but don’t think about why. So you end up with code like this. I swear to God, I see this stuff everywhere.

public class MySillyClass { 
  private string _myFakeEncapsulatedVariable; 
  public string getMyFakeEncapsulatedVariable() { 
    return _myFakeEncapsulatedVariable; 
  } 
  public void setMyFakeEncapsulatedVariable(string var) { 
    _myFakeEncapsulatedVariable = var; 
  } 
}

From a coupling standpoint, there’s very little difference between this code and a public variable. The code follows the letter of the rule, sure. But the programmer of this class clearly hasn’t thought things through. The “private variables” rule was a mere speedbump on the way to thoughtless design.

This part of the argument is down towards the bottom of a very large post. If you haven’t run across James Shore before his blog posts are often experiential and quite enlightening on Agile and XP techniques.

SQL On Rails

My brother pointed me at an entertaining April Fool’s satire site, SQL on Rails. Favorite line of code in the screencast was:

SELECT * FROM the_internet

One Hour Pairing

Today, I blocked out an hour to sit with one of my developers and pair up to write some unit tests and get the Clover IDE plugin working with RAD 6.0. It was actually fairly productive for a single hour, and though only one test actually got written in that hour, I learned some things:

  • The Clover IDE is pretty easy to setup even in RAD, but you have to remember to recompile the code without instrumentation if you want to look at a JSP page in the embedded Websphere instance. Otherwise you get a nasty error warning you about not finding Clover.
  • Writing tests after the fact is always a bit more painful, sort of the Michael Feathers legacy code bit.
  • On this project we were writing some test classes that tested multiple classes which may be a mistake, but in one hour I couldn’t really evaluate it. We went ahead and wrote a new test class.
  • We extend a <div class="codecolorer-container text vibrant overflow-off" style="overflow:auto;white-space:nowrap;">
    1
    BaseTest

    </div>

    class that has most of the JSF setup code in it. It had a

    1
    testSimple()

    test in it that was getting run by all the inheriting classes so it was artificially inflating the number of tests. I took the obvious stand that we should just delete the test since it wasn’t doing anything real. Then we started getting a failure running the tests for the

    1
    BaseTest

    running in RAD. (Probably because it didn’t have any tests). Rather than spend a lot of time investigating we stuck it back in and moved on.</li>

    • Unit testing JSF is a royal pain. This was a good reminder. Knowing intellectually what is driving your developers crazy isn’t quite the same as sitting down and coding with it.
    • I learned I need to do more of this.</ul>