Fast Rails Tests

Ruby on Rails gives us incredible power. MVC architecture, automatic reloading, easy model relations, cacheing, asset management. It also gives us incredible overhead, especially when it comes to testing.

I recently ran across this in Event Faster Websites, quoting Jakob Nielsen’s research:

  • 0.1 second is about the limit for having the user feel that the system is reacting instantaneously, meaning that no special feedback is necessary except to display the result.
  • 1.0 second is about the limit for the user’s flow of thought to stay uninterrupted, even though the user will notice the delay. Normally, no special feedback is necessary during delays of more than 0.1 but less than 1.0 second, but the user does lose the feeling of operating directly on the data.
  • 10 seconds is about the limit for keeping the user’s attention focused on the dialogue. For longer delays, users will want to perform other tasks while waiting for the computer to finish, so they should be given feedback indicating when the computer expects to be done. Feedback during the delay is especially important if the response time is likely to be highly variable, since users will then not know what to expect.

Where do your tests lie on that scale?

Rail Overhead

Rails tests tend to be slow for two reasons:

  • Loading the entire framework with all it’s nifty features on every test run.
  • Using the entire framework with all it’s nifty features on every test.

Not using the full stack (especially hitting the database) basically comes down to mocking and stubbing, which is a topic unto itself. What I’m going t focus on here is not loading the entire framework. This doesn’t mean addressing loading won’t cause some mocking and stubbing – anywhere you butt up against the Rails API or ActiveSomething, you’re going to have to stub that bit out to avoid loading it, an exercises that should make a nice object lesson in modularity and coupling.

Fast Rails Tests

Getting separately testable pieces won’t be easy. You actually need something that doesn’t depend on Rails, such as accessing an API, or that can be easily stubbed out, such pulling a couple methods into a module. You can do some refactoring in the standard test environment, but then you’ve got to figure out how to actually test them without rails.

Corey Haines demonstrated /spec_no_rails. That was a little long for me. as well as a little negative, so I went with /spec_clean. I wanted, of course, to have /spec be the plain tests and /spec_rails the slow ones, but that runs afoul of the many and various tools, such as autotest, which make assumptions about your directory structure.

I also tried have a /spec/clean directory, but I ran into trouble with the default load paths and assumptions made about spec_helper.rb. In the end I had a separate directory for spec_clean. To avoid the ambiguity of spec_helper, I had spec_rails_helper and spec_clean_helper. Getting this to work with the default load path required creating/spec/spec_clean_helper.rb` and having it load the correct file, which could then adjust the load paths appropriately.

You have to be careful adjusting the load paths. Oh, and in your tests, don’t forget that won’t have Rails magic constant loading, so you’ll have to require everything explicitly. My first draft of spec_clean_helper looked like this:

$LOAD_PATH << File.join(dir)
$LOAD_PATH << File.join(File.join(dir), "../app")
Dir[File.join(dir, "support/**/*.rb")].each {|f| require f}
require File.join(dir, '../config/initializers/my_init')

RSpec.configure do |config| ...

If you want to go a step further and avoid Bundler’s startup overhead, you’ll also have to make provisions for anything outside of Rubgems – directly loading anything that falls under Bundler’s path or git options.

One comment so far, add another

Code Academy Startup Weekend

Half-way through their course, Code Academy‘s students are already rocking out complete apps in a weekend.

Code Academy is a Chicago based school teaching web development by way of Ruby on Rails. It says something about the kind of students the school is attracting that the students organized their own unofficial Code Academy Startup Weekend a few days ago. I only found out about the event when they started tweeting and posting pictures. It was only Sunday afternoon that I saw the opening for spectators and headed down to Chicago.

I arrived about a half hour before judgment time. Neal threw me into one of the team rooms to see if I could help a last bug. In reality, that close to ending it’s at least as easy to get in the way as it is to understand all the background and become helpful. Since it was primarily an internal event, there weren’t very many non-participants, and I got pulled into the judging panel.

Tell Me When

The idea for Tell Me When started with running races: get notified when registration opens without having to check back at all the pages. Further possibilities include movies, performances, and anything else that you might know about before you know the relevant dates.

Winner: Most likely to be acquired by Apple for Siri

Hangar 18

“Hacker News” for Code Academy. Pretty much what you expect – articles pulled from @CodeAcademy, #CA, and direct submissions with voting and comments. Future plans include profiles, job postings, and easter eggs.

Winner: “Ship It” – the app was live and usable by Sunday evening

Handmade.local

Sort of a localized Etsy. The app managed users, postings, photos, geocoding, and displaying maps. There wasn’t anything technically spectacular – except that the entire team was on the beginner track, and put it all together after only six weeks in the class.

Winner: Code Academy Poster Children

Wahdle

Group travel planning with a great looking front page and streamlined getting started process. The design was really slick, but much of the wireframing had been done beforehand, and I gathered that they brought in some outside help.

Winner: Pretty Girl at the Dance

Send Five Now

Send $5 SMS gift cards. Not only did this team have an almost fully-functional product (they just needed to take payment), but they actually got out of the building (or at least around the building) and talked to some local businesses. They also had a plan to bootstrap by buying gift cards and typing in numbers.

Winner: Hustle

Send Five Now brings us to an interesting point All the teams had something mostly functional to show off. This isn’t too surprising – it’s Code Academy, so everyone involved had some development knowledge, and it was in the same framework – I’ve been to several Startup Weekends were we had an even split between PHP and Ruby, and at most half the team development. There was some ambiguity, at the beginning and as we prepared for judging, whether it was a unofficial “Startup Weekend” (customer development) or a “hackathon” (product development) Most people focused on product development, and we mostly left monitization out of the judging criteria.

Despite differences in the experience levels of the people involved, all the teams delivered something within a few steps of a usable web service. It will be interesting to see what they can deliver once they’ve got the other half of their Code Academy education.

Comments Off

BIG, DUMB, and LOUD at Fox Valley Computing Professionals

There are myriad little tricks one can use to improve your slides, but these three simple rules will save you from some of the worst presentation faux-paus.

Comments Off

Ruby is the Force. Rails is the Dark Side.

A while back I wrote about “Uncle Bob” Martin’s The Lost Years of Architecture. As always it’s one thing to hear it and another to try and put it into practice, and I didn’t immediately have any architecture to think about. I’ve also been thinking about Corey Haines Fast Rails Test (“spec no rails”), which also has design implications.

Corey makes tests fast by not loading Rails. Uncle Bob says “A Ruby team fails if Rails is the first thing they do.” So, I’ve been trying to take pieces out of a Rails app and isolate them. I started by getting them to run in spec_no_rails, which I called spec_clean. For the first two pieces, I was making pure data queries to external services, so they didn’t depend on Rails in any meaningful way. I further extracted them to independent gems with their own tests. The result is that, so far, my spec_clean is empty – it makes me wonder if anything that can work in spec_no_rails should really be a gem.

The third piece does depend on Rails however – it has an ActiveRecord model, controller, and views. There are a couple of ways to separate parts of an app – the main ones being engines, and assembling multiple Rails apps as Rack apps. Engine don’t seem like quite the right answer – it’s designed for common functionality, while my goal is to isolate something that might eventually be it’s own service. Multiple Rails apps seems really heavy-weight, and maximally disruptive. In short, it’s proving difficult to disentangle the pieces.

“Once you start down the dark path, forever will it dominate your destiny, consume you it will…” – Yoda

Rich Hickey would say it’s Complected. Rich certainly picked on ORM and OOP. Uncle Bob (who responded to Rich) had the “The Lost Years of Architecture”: the internet craze, which includes web frameworks such as Rails. Part of my struggle is that I don’t know Rails well enough to know how to modify it, or even when not to use it. This is where Rails is like the dark side: it offers easy power, without requiring any of the upfront effort needed to understand what is actually going on.

“Grave danger you are in. Impatient you are.” – Yoda

To a certain extent, this is the same problem as with every framework – you are trading a great pile of already written and hopefully battle-tested code for no understanding of what you are actually doing. At some level every framework is the set of tools built up by someone to solve their own problems. It works great for that person because he built everything; he put in the work to understand all the pieces so he knows how they all fit together.

The 15-minute blog is a lie. (And Rails doesn’t even work that way anymore.) It won’t let you build anything besides 15-minute blogs. You have to do real work to understand the tools. And if you do understand the tools? Be careful playing with the dark side. If you shouldn’t call yourself a programmer, calling yourself a Rails programmer means your destiny has been dominated.

2 comments so far, add yours

Startup Weekend and the Magic Circle

Permit me a little criticism.

1) Don’t be too attached to the idea you arrive with.

Your idea sucks. Google it. It does. Your idea is not what is important. It’s where it ends up that matters. The number of pitches will probably change during the course of the weekend, so it’s best to keep an open mind.

How To: Survive Startup Weekend Ideas Week

RedRadius already had T-Shirts, but as far as I know, not much else. EditHuddle had prior technology, marketing, and business planning.

There is a concept in game design called the magic circle. It’s the idea that game rules define a kind of mental space. The experience of the game is created because every player is willing to play by the rules, in turn because the player wants to be part of that experience.

The magic circle of Startup Weekend is that everybody starts with nothing. We come with only ideas, and leave with companies.

I saw EditHuddle at the SocialDevCamp Hackathon. More concerning was the tweet on their own twitter feed about a post for the Chicago Lean Startup Challenge. Entry to the the LSC closed 2011-10-01. Their blog announced an MVP on 2011-10-04. Startup Weekend begin 2011-10-14. I don’t remember any of this being mentioned in the pitch either Friday or Sunday.

I did say a little criticism. EditHuddle is one of the projects I might actually use, as an occasional blogger prone to omit words. (Of course, without readers it wouldn’t do me much good.) Pacha reused a little geolocation code, but probably no more than we could have found on any tutorial site. I was on the Code Mountain team with the people from Code Academy, who were able to reuse a lot of marketing research. Unfortunately, at this remote pacha I don’t recall how upfront the presentations were about it.

I guess my real criticism is this: EditHuddle already existed, and it was well under way. It took an opportunity away from an idea that might have needed such an event to get going, and it did so in a way contrary to the spirit of the game.

One comment so far, add another

Startup Weekend Ideas Week: Judging

Sunday 2011-10-16

Thirteen teams pitched Sunday night, at least one of which didn’t expect to. The up front rules were that only ideas chosen Friday could pitch Sunday, but there were some last minute changes anyway.

  1. HashBang, which might have been @Vollees in a previous life, wanted to organize user video submissions around hash tags. Business would sponsor prizes for the best video submitted to a tag.
  2. FixMyPad wanted to match homeowners with contractors, using escrow to guarantee payment.
  3. HelloNGO took Best Pitch and planned to play matchmaker between organizations need volunteers and students. They took a 50%, but one of the criticisms from the judges was size of market, so it might have needed high margins to work.
  4. Rescue Round (@RescueRound)) offers second-chance dates for disappointed people already dressed up and ready for a night out.
  5. BikeRecov (http://onepagerapp.com/mj46 took First Place with a plan track bikes and report accidents. They didn’t have an app, but they did have some customer validation and several possible directions they could go.
  6. JamOut.fm wanted to provide online jam session for musicians who couldn’t get together inperson. They took Third Place by doing a Skype proof-of-concept.
  7. EditHuddle (http://www.edithuddle.com/) placed Second with a typo reporting and management platform for bloggers. They put on an impressive tech demo – which I suspect involved a bit of pre-weekend work.
  8. Outloudio (http://outloudio.com/) got Best Tech Demo for their “podcast pandora”, with a possible “listen later” to come.
  9. Dressora (http://dressora.com) offered a dynamic social online closet, so your friends could help you pick outfits.
  10. Pacha (http://pachaapp.heroku.com) promises to deliver exactly the information you need at the current location and time.
  11. RedRadius (http://www.redradius.co/) plans to gamify social interaction, awarding points for interacting, especially with people who aren’t doing so well at the game. They got far enough to submit to the iPhone store.
  12. Movitv8tion (@motiv8tionme) offered social accountability for goals that you set out to accomplish.
  13. MergeNote (http://www.mergenote.com/) wants to create a collaborative tool that’s as good as pen & paper. I couldn’t help but think of it as a marketing (and tech) reboot of Wave.

Advice from the Judges

  • “Why would I use your service?”
  • “Focus on Mission”
  • “Stories are great, but state what you’re about up front”
One comment so far, add another

Startup Weekend Ideas Week: Sunday

Sunday 2011-10-16

Sunday morning I woke up first, a fair bit before we were expected to return. I separated the tests into an online and offline component and set up autotest. That put me in a good position to unify the API based models with the independently developed custom content models.

All my development thus far had been completely backend. Later in the morning we integrated the first draft of the actual app layout and set it up to return the results fragment.

The afternoon had a small interruption – Brad Keywell was supposed to give a speech before the presentations, but his scheduled got messed up and he came early. On the upside, it pushed back the stop-work deadline. On the downside, I was too busy working to pay very much attention. Of the few things I noticed: Brad says Ideas Week was his idea; ideas create business which improve the world. Be different – even though society wants you to be the same. His big trend is social networking plus collective action. They work by trying to convince themselves that their ideas suck – fail fast and only the strong survive.

In the afternoon Mingwei returned from a forgotten study session. Unfortunately, we were all heads down working on things, and had enough that we didn’t expect to be able to use any more API research. Missing time on Startup Weekend is dangerous because you can be left behind. Though I’ve never missed time, I’ve been in his shoes several times. I believe he was able to help out the business team a bit. He was also asking me about Ruby, so I think the brief exposure on Saturday may have proved infectious.

I also kind of wondered if some kind of SCRUM would be useful to keep people in sync and identify problems early. Another interesting aside is that Saturday the organizers came around to ask for our one-line pitch, and nobody was comfortable giving one, since we’d been bouncing lots of ideas around and working in separate teams. And organizing people was still hard – there was a little disconnect about what people wanted and what we were actually doing – it’s all very well to say “yeah, that sounds goods”, but that doesn’t mean I’ve finished the last task, or the next, and actually done it. At one point I had to say “If it’s less important than the last thing you asked me, put it on the todo wall.”

Team Pacha didn’t focus on a great presentation, or on much customer validation beyond a survey. The judges were looking for customer validation and spit-and-bailing-wire product tests. (I’ll write more on the pitches later.)

We did make Pacha something that looked pretty good, and returned some results – most of them canned for a few sample locations, plus some data from the easy to use WikiLocation API. I dropped Yelp due to the tiny API limit – we didn’t have time to test how the program would react to it running out.

We are going to talk about continuing. On Startup Weekend, everyone had made time to be there; now we have to deal with sets of very different schedules in order to get together again. Organizing people is still hard.

Comments Off

Startup Weekend Ideas Week: Saturday

Saturday 2011-10-15

The alarm was set for 06:30; I guess I was wired up enough to not notice the short night too much.

Organizing People is Hard

People trickled in Saturday morning. I started setting up a cardwall of post-it notes to try and set some order to things, although I think I ended up being the only person really using it.

The reason it was hard to get the tech started is that we had four programmers. As if finding a suitable way to break up the work wasn’t hard enough, there were two people with some Ruby experience, and two people with some PHP experience. Ray (Ruby) spent a lot of time on the business side, and one Luis (PHP) had the most design experience, and some browser geolocation code to borrow. In the end we decided on Ruby, with Mingwei (PHP) focusing on API research to inform the Rails application.

I several times wondered if we should switch (I’m always up to learn something new) I spent a lot of time doing install support. Our designer never did use live rails, even after I got running properly. Mingwei even decided to try doing the API testing in Rails, in case it involved a library – in the end Yelp’s OAuth proved daunting and we used the much simpler V1 HTTP API. Even with that, we were still limited to 100 requests per day until the app went live and got approved, which easily got burned through in testing. I ended up registering a new key under my new account to finish up the integration.

Saturday after lunch had two talks. Erin had stopped by our room earlier in the day. She gave a talk on working with designers. She kept it short, saying that people are lazy by nature, so focus designs on minimum effort. Perhaps by demonstration, she offered up some prototyping resources by short url.

The other talk was Brian Wong, of the Kiip mobile rewards network. He had a lot of advice, such as go live in a foreign country for more than six months. He also had great success cold-emailing silicon valley companies and asking to meet with them, often by guessing email addresses. However he tried to sum with with five specific points:

  1. You are the most powerful force in your life, don’t wait for other people.
  2. If the fight is hard, it’s even more worth fighting for – it builds competitive advantage.
  3. Generate serendipity – find the right environment (don’t judge a fish by how it climbs a tree)
  4. Get as much feedback as you can (which means don’t bother with stealth mode)
  5. Hire amazing people. Frame your pitch so they come up with the idea themselves.

Saturday night I stayed at Ray’s house, saving myself a few hours of travel; or rather getting a few extra hours of sleep. Though, in an odd kind of way I missed the opportunity to get some work done on the train, away from the all the noise.

Comments Off

Startup Weekend Ideas Week: Friday

I was actually going to pass on October’s Chicago Startup Weekend and just try to get some work done, but my partner Ray Lian had an idea bugging him.

Friday 2011-10-14

Friday afternoon I misplaced a digit in the train time and missed my scheduled meet up with Ray. We didn’t come together until we were en route to Excellerate Labs, arriving late, but just in time to eat while the talks were going on. I believe there were 110 participants, and about half of them pitched ideas – the organizers had to cut the pitching off for the sake of time.

Ray came in just wanting to build a proof of concept, and he said as much in his pitch. The idea was to build an app gave you exactly what you need at your current location – the example being to bring up the airport schedule when you are in the airport

Every Startup Weekend seems to bring a new voting method. This time they handed out tickets and had people mingle and hand over tickets. While this was somewhat streamlined, it meant that you had remember who pitched your favorite idea – after watching a parade of fifty total strangers. Maybe next time I should be writing down shirt colors instead of names.

Though Ray tried not to oversell the pitch, he did network well, and came out of ticket trading with 14, merging in two other location based ideas. I didn’t notice the final cutoff for the 13 teams, but I think it was around 10 tickets. Most successful teams had around 10-14, I think there was one 24 or so.

14 tickets did in fact translate to seven people, although one didn’t return on Saturday. Our team, left to right (I though I might have the biz devs backwards since I didn’t work with them much.)

  • Chris Gryzywacz – business
  • Mingwei Shen – PHP, fears no challenge
  • Luis Armando Gomez – PHP/Javascript, front end design
  • Morgan Brewster – business
  • Ray Lian – Idea man, former Java dev learning Ruby, studying business.
  • Justin Love (not pictured)

We spent Friday night throwing around ideas and getting an idea of what we were going to build. A key feature was that we had to return relevant information, and one determinate was time – you might want some place to eat round noon, for instance. And thus I named the app.

Pacha is an old Quechua from the Andean region; I ran across it in a book called Secret of the Incas, and somehow it resonated with me. It’s concept with not perfect translation; various translations are “world”, “the earth”, “time ground place”. It means place and time simultaneously. You can go to the ‘place’ where the Incas reigned, and will be a very different experience than it was when the Incas lived there – it is a different at either of those ‘times’, or at any time, you can go to two different places, and those will be different experiences – different pacha. It’s pretty obscure word, and even Wikipedia only has a passing mention under Spacetime

The idea of the app is that shows you what is relevant right here, right now – at this pacha. At a different place or a different time, it’s a new pacha with new information.

We didn’t have a solid coding plan in place by the end of the night (more on that later) so worked on another project waiting at the station (there is no 23:40 on MD-W) and on the train home. When I got back I checked in, schedule a cab, and took care of a number of other little things, not getting to bed until almost 03:00.

Comments Off

The Lost Years of Architecture

Tuesday 2011-10-04

A year ago, the McHenry Cloud Developers ran out of services to look at, and transformed into Software Craftsmanship McHenry County. A surprise guest was “Uncle” Bob Martin, a legend of the field, who was quoted on the Software Craftsmanship Calendars that got handed out. For the one year anniversary, they asked Uncle Bob out to give a talk. It was one of those “We’re doing everything wrong” kind of moments.

I’ll be paraphrasing the talk from notes and memory – all errors are my own. You could also just watch the recording of Uncle Bob talking about Architecture

It started a long time ago – circa 1993 the world was ruled by C++ and COBOL, and object-oriented programming was born. The talk was built around a the book Object Oriented Software Engineering: A use case driven approach, which can be had (used) today for little more than the cost of shipping. There followed a period where people struggled to create proper object oriented architectures, using use cases (which today we know as user stories).

Then “all hell broke loose” – the web hit the scene, and time to market dominated everything else. It was circa 1995, Java and interpreted languages were on the rise and money was being throw at anyone doing software on the internet (today, it’s social media).

Then the tech bubble burst, and there were lots of young, jobless programmers asking what it meant to be a programmer – the birth of the agile movement.

Yet fast forward a few years and we see mostly frameworks. Ask somebody about their architecture and you’ll probably get something like “Struts and Hibernate on Tomcat” These are tools, not architecture. Web frameworks are often built on MVC, a GUI design pattern from circa 1978. In GUI MVC, a screen had dozens of views – each little widget.

When you talk about real architecture, you talk about things like floorplans, elevations, and utilities. The shape (especially the floorplan) should tell you what it’s for – it might scream office building for instance. This means it should scream at you about use cases. Most apps today scream at you about the web.

Use cases should be the central architectural guidance. They describe in a formal way how the user will interact with the system. They are described in terms of inputs and outputs. They are without trappings and delivery agnostic (e.g, don’t talk about forms, buttons, or pages) The use case might include a question and answer process. In the OOSE methodology, use case are represented by interactors (originally it was control objects, but Uncle Bob wanted to avoid any confusion with controllers).

Business objects become entities. They have the rules which are application agnostic and always true. All of these objects are “plain old xx objects”, which means they are easily and quickly unit testable.

Boundary objects connect the user interface to the interactors. They perform a kind of message passing using base data structures. It might involve presenters; basically a view gets data and renders it.

The database interface is in the interactors, because they manage transactions. (Aside: division into “DBAs” was invented by database companies for commercial reasons.) In any case, someone has to defend the schema, because it’s being pulled in different directions by every application. The schema is the lowest common denominator, it makes no sense to anyone because it has to serve everyone. The solution is database boundary layers which hide the schema and speak entities.

The point of this architecture is to defer critical decisions – such as desktop or GUI, which database, or even no database. A Ruby team fails if Rails is the first thing they do. (It’s kind of hard to defer the language decision.) The app should be thought of a kind of library (gem in Ruby) that is assembled with some IO system, such as the web.

During Q&A, Uncle Bob pointed to the Fitness testing framework as an example, although my brief investigation so far hasn’t been able to tease out the interactor/entity/boundary system he describes.

What now? We are doing everything wrong. (Or at least, I am.) I’ve had some leanings in this direction – the board game simulator was mostly an engine, with a little progress made on abstracting IO. Yet adopting this system is very daunting. Especially for existing projects where a major refactoring would be required. Even for new projects, you are weighing up front costs against the promise of future malleability. I might have to give Software Craftsmanship North America a try, even though it’s a tad pricey.

Update: Confreaks has released the Ruby-Midwest recording of Architechture: The Lost Years, complete with slides.

Comments Off