Twitter

Stubbing Partials with RSpec in Rails View Tests

Working with my pair yesterday we ran into an issue testing a view that pulled in several partials. In the interest of making progress we punted after about half an hour of trying to setup expectations on the partials and just tested the negative cases where we didn’t have to worry about the partials being called. Intellectual curiosity and not wanting to leave the views lightly tested I dived into seeing how we could effectively test that the partials were called as expected.

Say you have a view like the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<div id="content">
  <div id="page_title" style="padding-bottom: 20px">
    <h2>Books</h2>
  </div>
  < %= render :partial => 'tabs' %>

  < % if @books.empty? -%>
      <em>No Books</em><em>
  < % else %>
      < %= pagination_links = render :partial => 'shared/pagination', :object => @books %>
      < %= render :partial => "book_rows", :locals => {:books => @books} %>
      < %= pagination_links %>
  < % end %>
</em></div>

You want to test the conditional to see that the partials to display the list of books work correctly. You don’t want to worry about concerns like setting up the books collection, and you might even want to stub out the call to the partial that displays the tabs a the top of the page.

The Rspec example group for this looks like the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
require 'spec_helper'

describe "books.rhtml" do
  before(:each) do
    assigns[:books] = []
  end

  describe "with no books" do
    it "should display 'No Books' message" do
      render
      response.should have_text(/No Books/)
    end
  end

  describe "with books" do
    before(:each) do
      assigns[:books] = [Factory.build(:book)]
      template.stub(:render).with(hash_including(:partial => "tabs"))
      template.stub(:render).with(hash_including(:partial => "shared/pagination"))
    end

    it "should render book rows" do
      template.should_receive(:render).with(hash_including(:partial => "book_rows"))
      render
    end
  end
end

The key find was to use with(:hash_including()) which I found from a helpful link at Stack Overflow.

Breaking the Build at the New Job

I broke the build

My first break of the CI build on a new team came about two weeks into starting the new job. We had made a small change to a dynamically created URL on a single page of the application. Normally this would fall into the category of “too simple to test” for me. My pairing partner pointed out when we started the story that we should put a test in for the change. I argued that changing a URL was too simple a change to bother writing a test for. He disagreed, but let me go ahead after some further discussion. After checking in the feature, about an hour later a developer on the other side of the room piped up with “Someone broke the build.” My pairing partner smiled and said, “I guess we didn’t need to test that.”

It turned out there was another test I didn’t realize had a dependency on that same link and by changing it we had broken an assertion on the specific URL. A bit embarrassed I learned an important lesson. My assumptions about “too simple to break” needed some adjusting.

Over the course of several weeks I came to appreciate that many things were worth testing. A particularly revealing example was testing a new javascript dialog. Javascript is always a pain point when it comes to unit testing, and I’ve often let that coverage of javascript functionality be covered by functional tests usually with Selenium. My pairing partner walked me through a complete TDD approach asserting every part of the function we created and the various DOM elements we used to create it. I did ask a few questions about whether we really needed to test that we had created a DOM element in some exact order at points, but he was firm about testing in every piece. By the end of the feature I had a new appreciation for doing very low level unit testing.

I love that I’m being challenged on not writing enough tests. For so long in past shops I was the hardcore TDD advocate constantly questioned about the real need for testing some component. Now I’m learning to test in even very small changes.

Cardboard Boxes and Modern Web Frameworks

My daughter spent an hour the other day cutting holes, drawing red bricks, and pasting grass along the bottom of a simple cardboard box. It’s a common story among parents, especially of small children that despite spending a lot of money on a gift, the kid ends up enjoying the box and ignoring the toy.

I’ve noticed a common quality of many newer web frameworks is that they provide you with a nice box to build from. Typically:

  • A default structure so you know where to find the models, views, controllers, extra libraries, etc.
  • A command line for generating stubs, running tests, and deploying.
  • A plugin system for easily adding functionality from swapping out javascript libraries to adding a security system.

Though there are probably others I’m aware of this model being used by Spring Roo, the Play Framework, Gryphon, Grails, and Rails. I don’t claim to be a historian on this, but Rails was my first experience with this style and I assume to be the originator of the approach.

The benefits of this approach are obvious from the first time you start off with a Hello World tutorial. For one you generally have a single download for the framework. After unpacking you’re able to use the command line to generate your Hello World controller, find the view in a predefined location, add the Hello World line, and fire up the application from the command line. Passing the 5 minute test is pretty important if you expect developers to give your framework a chance.

As a consultant working on numerous legacy code projects, there’s always the groan moment when you start looking into the code and you realize its non-obvious where to find things. I’ve seen libraries sprinkled about at random, key configuration files that were supposed to be moved into the users home directory, model classes mixed in with controllers, and a host of other inconsistencies. With a framework that reinforces the default structures it becomes easy to find things and much easier for plugin-authors to write plug-ins that make the framework much more valuable.

Finally, the plugin system is a critical part of new frameworks. Being able to add security framework on the fly, swap out your testing framework, or simply add in a nicer date library really starts to make things feel like magic. Indeed among these frameworks they are starting to push more and more modularity into the plugin systems to allow for the framework to evolve better over time.

I hope this trend continues in the world of web frameworks, as I really like a nice box to start a project from.

Mock With Spock

My default rule with mocking is to try to stick to stubs where possible. I don’t enjoy having to setup and verify interactions with mocks, but sometimes you have some code where that’s exactly what you need to do. I’ve used many frameworks in Java over the years from EasyMock to Mockito, but I was quite happy with how easy it was to do in Spock. I recently found myself having to build a test harness around some legacy code. The real world code was more involved, but it looked something like this:

1
2
3
4
5
6
7
8
9
10
11
    public void addDefaultQuestions(Category category) {
        if (categoryDao.getCategory(category.getId()).getQuestions().isEmpty()) {
            for (Question question : category.getQuestions()) {
                if (question.isDefaultQuestion()) {
                    categoryDao.addQuestion(question, true);
                } else {
                    categoryDao.addQuestion(question, false);
                }
            }
        }
    }

The method is taking a category, checking if any questions related to the category exist in the database and then saving all the questions with a valid flag set to true or false. Not unusual in a typical corporate application, but I want to test two things:

  • I can add new questions to the database with the proper valid flag.
  • If the database category already has some questions then do nothing.

After walking through the Spock mocking documentation I had a pretty good sense of the approach. In Spock it’s referred to as interactions, but it doesn’t follow the typical expect-run-verify pattern. You just verify what you need to if you need to. And given a choice I prefer not to have to verify the mock at all.

With this code I needed to mock the categoryDao which used straight JDBC and made calls to the real database. That meant I needed a way to verify that the questions were added correctly with calls to the categoryDao. Hence I needed the power of an actual mock and not just a stub class.

The first test would show that I could save new questions in a category to the database:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 def "should only insert new default questions"() {
    given:
    def question1 = new Question(defaultQuestion: true)
    def question2 = new Question(defaultQuestion: false)
    def category = new Category(questions: [question1, question2])

    CategoryDao dao = Mock()
    dao.getCategory(_) >> new Category()

    CategoryService service = new CategoryService()
    service.setCategoryDao(dao)

    when:
    service.addDefaultQuestions(category)

    then:
    1 * dao.addQuestion(_, true)
    1 * dao.addQuestion(_, false)

  }

So the steps are:

  1. Setup a Category object with two questions.
  2. Create a mock dao.
  3. Define a method and its default return value on the mock DAO.
    1. We define arguments to getCategory() with a wildcard operator the underscore standing in for an id.
    2. Then with the right shift operator (>>) we define that we will return a newly created Category object.
  4. Inject the mock into the service class we’re testing.
  5. Finally, we make verifications on the addQuestion() method by just stating the number of times we expect the method to be called with a given set of arguments, again reusing the wildcard underscore character.

You can even specify the particular order you expect by breaking the verifications into separate then: blocks. For this example it wouldn’t matter on the order, but in case it did the last when then block would change to:

1
2
3
4
5
6
7
8
    when:
    service.addDefaultQuestions(category)

    then:
    1 * dao.addQuestion(_, true)

    then:
    1 * dao.addQuestion(_, false)

And to round out testing the legacy Java code we need to test the negative example where it should do nothing if there are already questions in the database for the given category.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
  def "should add no questions if questions are already in database"() {
    given:
    def question1 = new Question(defaultQuestion: true)
    def question2 = new Question(defaultQuestion: false)

    CategoryDao dao = Mock()
    dao.getCategory(_) >> new Category(questions: [question1])

    CategoryService service = new CategoryService()
    service.setCategoryDao(dao)

    when:
    service.addDefaultQuestions(new Category(questions: [question2]))

    then:
    0 * dao.addQuestion(_,_)

  }

So we can test for the negative case by just verifying that addQuestion was called zero times.

Grails Unit Testing: Mocking With MetaClass Stubs

On a recent project I ran into issues with testing controllers in Grails. Starting test first, I spent some early time figuring out how much support there was out of the box for unit testing Grails domain classes and controllers. I setup Spock as a plugin and plunged in. I was dealing with a legacy database which had 100% compound primary keys so many of the findBy type operations that are well supported for controller testing are of no help. Often I found I needed to mock a call to a find or findAll with HQL syntax or a criteria call. I knew metaClass mocking could work here, but I wanted to understand better how that would impact the rest of the code after I started replacing methods on the fly. Turns out Grails unit testing has built in support for cleaning up metaClass hacking after every test with the registerMetaClass() method in GrailsUnitTestCase. Mrhaki has a good post on this. Here’s an Spock example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import grails.plugin.spock.ControllerSpec


class ContractControllerSpec extends ControllerSpec {

  def setup() {
    registerMetaClass Contract
  }

 def "validateContract() returns true for an existing contract"() {
    given:
    mockDomain(Contract)
    def contract = new Contract(division: '33', unit: '99', contractNumber: 'C7777777').save(flush: true)
    controller.params.division = '33'
    controller.params.unit = '99'
    controller.params.contractNumber = 'C7777777'
    Contract.metaClass.static.find = { String query, Map namedArgs -> contract }

    when:
    controller.validateContract()

    then:
    "TRUE" == controller.response.contentAsString
  }

}

Grails has support for the same idea using mockFor(), but the syntax is much like EasyMock. The same test would look like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import grails.plugin.spock.ControllerSpec


class ContractControllerSpec extends ControllerSpec {

 def "validateContract() returns true for an existing contract"() {
    given:
    mockDomain(Contract)
    def contract = new Contract(division: '33', unit: '99', contractNumber: 'C7777777').save(flush: true)
    controller.params.division = '33'
    controller.params.unit = '99'
    controller.params.contractNumber = 'C7777777'

  // EasyMock like syntax
  def mockContract = mockFor(Contract)
    mockContract.demand.static.find(0..5) { String query, Map namedArgs -> null }

    when:
    controller.validateContract()

    then:
    "TRUE" == controller.response.contentAsString
  }

}

For pure stubs I prefer the syntax of just using MetaClass. I often don’t care about validating the exact calls to the dependent class so I don’t really want a full mock. You don’t need a call to registerMetaClass() because mockFor() does this for you.

Developers and Desktop Databases

Typically development groups fall into one of two patterns:

  • Shared development database – every developer shares a single centralized development database often managed by a DBA group.
  • Desktop databases – every developer has an individual instance of the database.

The practice has evolved over time and developers tend to follow precedence on it. Historically, developers didn’t think of running a local database, primarily because of the resources involved. Installing and running something like Oracle locally used to be a significant drag on a development machine. You were already trying to run some sort of IDE that sucked up most of your machines resources so running the database locally wasn’t a great option. If you were lucky enough to be running a pretty light weight database you might think about running a local copy, but otherwise you just setup a connection and shared the dev instance.

As machines have gotten quite capable of running databases, IDEs, and even virtual machines all at the same time the option to run a local copy of the database became very real. In this case a number of developers began to install and run local copies of the database. Running your own local copy quickly makes some development issues stand out:

  • You have to learn a bit more about how your target database software is setup. Suddenly it’s just not just a set of connection parameters.
  • You have to think about the best way to coordinate changes to the database model. Making a lot of changes locally to apply later to the central dev integration instance is going to end in a lot of angry emails with how you broke the build.
  • You can quickly experiment with local changes to the database model without impacting the rest of the team.
  • You have a truly complete development environment, so if you take your laptop home at night, work remotely for the day, or get called for troubleshooting in the evening you can be effective without having to VPN into the dev database or drive into the office.

I think the long term trend is most developers will run local instances of their target database. This is almost standard in startups and newer organizations. As a consultant I love having a complete development environment since I can run and demo the project at a moment’s notice. The issues with integration are being addressed with approaches like database migrations in Rails and maintenance of DDL in source control, treating it like an equal member of the code. I’ve also seen partial steps towards this model with the idea of in-memory local databases used for unit/integration testing where you use an ORM like Hibernate to build the database model on the fly whenever you need to run tests.

Spock Intro Tutorial

I gave a presentation on Spock a very nice BDD framework in Groovy a few months back to our Groovy Users Group in Sacramento. After using it on a real world Grails project the last few months it has grown on me to become my go to testing framework for Groovy/Grails or Java projects. A typical specification looks something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  def "a pager should calculate total pages, current page, and offset"() {
    when: "count, rows and page number"
    def pager = new Pager(count, rows, page)

    then: "should return correct total pages, the current page, and the offset"
    pager.totalPages == totalPages
    pager.currentPage == currentPage
    pager.offset == offset

    where: "you have a number of different scenarios"
    count | rows | page | totalPages | currentPage | offset
    100   | 10   |   1  |    10      |     1       |   0
    950   | 100  |   5  |    10      |     5       |   400
    72    | 20   |   3  |    4       |     3       |   40
  }

If that passed your 5 second test take a look at a fuller introductory tutorial I put together.

A Gentle Introduction to Spock

And if you want to try out executing real code the project has a nice browser based environment at Meet Spock.

AgileZen for Solo Remote Development

Over the past few months I’ve been working on some remote projects as a solo developer. Knowing I wanted a light weight tracking tool I took some time to experiment with a few tools and I’ve recently come to appreciate the lightweight character of AgileZen.

Despite many warnings to use the simplest thing that could possibly work, often stickies on the wall or simple index cards, there have always been a number of options to translate these planning/tracking tools to software applications. Despite settling on the power of physical wallboards for collocated teams throughout my career I have looked into using a number of tools for feasibility ultimately deciding none of them worked as well as a cork board and some stickies or index cards. Tactile and visual cards rock.

Some of the tools I’ve looked at in the past include:

I never felt any of them where worth the effort to maintain in the end despite many high hopes. I’m not immune to tool fascination, but I tried to honestly evaluate the worthiness of the given tool. As a manager much of my focus on this was to please stakeholders and other managers with a nice visual report that could be shared via email and web browsers. In my Agile rollouts it turned out that I was ultimately more successful showing off my cork boards and cards. We did maintain an Excel spreadsheet with backlogs as well to meet some documentation standards for PM groups. It was a small compromise I was willing to live with.

My most recent projects presented me with a different challenge. As a solo developer I’m largely on my own and not sharing the project tasks with anyone else, but I like to have an organized workflow at all times. My home office doesn’t have much in the way of space for a nice corkboard, and again I wanted to fiddle with tools so I tried a few to see how they might work for me.

A first attempt was with Pivotal Tracker. I love the things Pivotal is doing out there with a focus on TDD/BDD, pair programming and producing high quality code. Pivotal Tracker is a nicely polished tracking tool that largely simulates the idea of a wall board with an emphasis on iterations that contain a set number of story points. It’s an opinionated piece of software with this and assumes that you are very concerned with ordering of stories based on points and how you pull them into the backlog. After a lot of work trying to understand how it wants me to work I found it not a great fit as a solo developer. It assumes you want to have tracker plan your iterations automatically based on your velocity. In fact they admit that you can change some settings for the current iteration to allow you to drag stories in or out, but it will still automatically plan all the other iterations in the backlog. In the end I might be up for trying it with a non-collocated team, but for a solo developer the overhead was a bit higher than I prefer.

AgileZen was my second attempt. I remember from some old twitter and blog posts that several people had said it was a really nice lightweight tool. I realized arriving at the site they had been acquired by Rally. I’ve used Rally’s tools, but for collocated teams I didn’t really think the overhead of using Rally was worth it. It appears that AgileZen is their attempt to provide a lighter more Kanban style tool. I liked the little bonsai tree on the login and found more to like when I went in and attempted to setup my current project. I watched the short series of screen casts showing how it worked, maybe 5-10 minutes in all. After that I’ve been very productive without having to dig into any help. The central metaphor is just a digital task board:

Agile Zen focuses on the concept of cards and a board with very lightweight workflow. You create a feature or user story and ‘hang the card on the wall’. You then just move the card to progress it from the backlog to started. You can do some customization, but the default workflow was perfect for me as a single developer. It also looks like it works quite well for remote teams and appears to support more options like marking cards as ready or blocked. I’ve even used the blocked status for a card once where I wanted to run a design idea by a colleague before I continued further on that particular story. And I’m a sucker for some auto-generated stats, but it has a nice page where it calculates your throughput with a pretty graph. It will take more time to see if the stats actually give me useful feedback, but did I mention they look nice:

Overall the tool feels closer to a digital taskboard than anything else I’ve experimented with. I’d still use a physical task board for a collocated team, but for a team working in remote locations or a single developer I think it makes a very good electronic substitute. Now if only it had an iPad version. If you’re a solo developer feel free to try it yourself as it’s 1 project is free for a single developer.

Fallback Plan in Action: From Software Manager to Developer

Everyone relishes the confidence of a having a backup plan if everything falls apart. For myself as a manager it was knowing I could always go back to development if something unexpected came up. After 10 years as a development manager, I got the unfortunate call to follow my director to an unannounced meeting first thing in the morning. Turns out the CIO had decided the organization didn’t need developers and could get by with contractors so there was no need for a development manager. My director would depart the company as well a few months later.

I was in a state of shock for a few days. Sacramento is a small IT market normally and finding open development management positions is fairly rare. I explored a number of options for the first month afterwards including biting the bullet and taking a great job in the Bay area but living with a horrible commute and lousy family life. For many reasons I choose family over a nasty commute.

I came back to the plan of returning to a developer/architect/tech lead role. I hadn’t done day to day development in at least 5 years, but I’ve always kept up my skills with home projects and taking on the tasks of running infrastructure tools like source control, CI servers , wikis, and functional testing tools. I really enjoyed managing development teams and moving obstacles and really growing the skills of my team, but now it was time to focus on myself.

Fear was right up front. I felt like an impostor in the first few development interviews all of which went well despite this. I’ve never felt a high degree of confidence in my abilities and always felt the need to prove myself. With my background as in professional services I eventually got acclimated to the feeling that I was an impostor working on the client’s project. It motivated me to spin up incredibly quickly so I wouldn’t be exposed as a fraud. I’m still not sure this has been the healthiest approach, but I’m still working through my affliction with the Impostor’s Syndrome.

Another factor was figuring out how comfortable I was with making less. Development managers simply make more than senior developers. I’m certain this is the wrong approach in many cases as I always felt at least my top few people were more important to the company than myself, but HR departments really like hierarchal salary structures. So diving into development was likely to mean a salary hit. I have a wonderful wife, two kids, and a hefty mortgage. The prospect of taking a startup job with a firm that was a using new technologies was enticing, but taking a big salary cut was going to be very hard. Lesson learned with the mortgage, sometimes the nice new house isn’t worth the career choices it forces you into to, but you end up making some compromises in life.

I ended up deciding I had to hold out for a well paying position even if that meant working for less exciting companies and technologies. It probably meant a lot of Java/J2EE given my background instead of Groovy/Ruby or mobile development.

Anyway after a month or so of doing some big career thinking, visiting family and friends, and polishing up some slightly rusty Java chops I dipped my toes back in the water with a couple one off gigs for a former employer. I took on a mentoring an organization through development tool choices and how to guide their staff on working with these new tools. From there I took an assignment to do a custom WebLogic course for a client. It was a week long course which I felt I could ramp and cover, but brought back a lot of lingering doubts.

I’ve done many presentations over the years ranging from an hour or two to a half day seminar. I feel very confident in the ability to deliver them with a high degree of quality. Before this I had done two week-long courses in the past and survived them both, but walked away from each feeling as though I had done a horrible job. Keeping a class engaged and interested in a topic for an entire week and knowing it deeply enough to answer almost any question is quite a tall order. So the WebLogic course was a big challenge.

I spent a week immersed in the course material and working through the labs several times after building a VMWare image. I prepped in front of the director of the company, feeling like I was going to fail. I delivered the course, and spent 6 hours every night reviewing everything for the next days class. I was actually shaking stood up to deliver a lecture on a new section. The good news was even though I felt like it hadn’t gone that well, I got glowing reviews from the students.

Soon after I dived full time back into consulting with a company. I had many assignments helping mentor development organizations and a ton of classes and custom class deliveries. In 6 months I actually taught 21 different week long courses. The work was brutal, but eventually I got the confidence in my abilities back, and I can almost effortlessly present on technical topics with just a small amount of prep time. Over the last 6 months I’ve come back to almost full time coding and even gotten to do a nice Groovy/Grails/jQuery project utilizing 1 week iterations.

I’ve read many times about how many technical managers make the mistake of letting themselves get promoted and then they can’t let go of the coding. And many technical managers point out the need to focus on the management tasks of the job. My approach to this was to focus on the management of my team, but to keep my skills fresh by doing side projects at home, presenting at user groups, and doing code reviews and maintaining build servers at the office. I don’t think this is the common approach of development managers, but it’s the only approach I’ve felt comfortable with. I do remember feeling some camaraderie with Rands (of Rands in Repose) as he proposes:

“I’m still cringing. Someone is already yelling at me, “MANAGERS OWNING FEATURES??!?!” (And I agree.) You are still a manager, so make it a small feature, ok? You’ve still got a lot to do. If you can’t imagine owning a feature, my back-up advice is to fix some bugs. You won’t get the joy of ownership, but you’ll gain an understanding of the construction of the product that you’ll never get walking the hallway.”

Rands

So the fallback plan is just as important as the financial advice you always get to make sure you have at least 6 months of salary socked away so you can ride out a layoff. Rather than fighting for nearly nonexistent management positions in a bad economy I was able to step into development and do important work. While I love management there are aspects of development that I’m very passionate about and I may continue on this course for the next few years. I’m sure I’ll return to managing a development team as it’s in my DNA, but for now I’m enjoying firing off a ‘git commit’, seeing lots of green tests passing and building a quality app in short iterations.

Recruiting for Passion: Creative Job Descriptions

As a new manager recruiting for the first time you’ll find HR will usually provide you with a job description template. You’ll read it, laugh at how generic it is, and then try to do a bit of modification. That’s a futile effort. (Though depending on the organization you may have to leave pretty close to the strict confines of a template, in that case you’ll be working with a few custom bullet points you can work in.)

You’re actually looking for the most talented, passionate developers you can find given the opportunity, your location, and the relative pay rates provided. So how do you attract those people with a generic job posting? Instead you rewrite the position from scratch and ask for things like writing plugins to open source frameworks, giving presentations at conferences, or writing a technical blog. You want to attract developers who care about their craft and are going to bring up the overall level of your team.

So in short:

  • Keep it short a paragraph or two and bullet points. The meat of the content is in the bullet points.
  • Explain the challenges of your environment, if you’re a hardcore waterfall shop trying to shift to Agile be upfront.
  • Explain that mentoring is part of the job.
  • If you have the control you can even write the job description in a programming language.
  • Be very clear that bringing your passion to work is encouraged.
  • If you’ve won some of the wars with the furniture police, explain the nice hardware and multiple large monitors that are available, or even semi-private offices.
  • If other members of the team have some public blogs, or open source projects point to those as well to give them a feel for the team.
  • If you’re not in Silicon Valley or New York, sell the upside of your region (probably cheaper living).
  • If HR will let you point to some of the targeted job posting sites like 37 Signals or Stack Overflow.