Hard to Capture Fluid Agile Practices in a Static Graph

Well, this is sort of what I like to do on software development projects…

I feel like there are some necessary startup processes to get you up and running quickly with a glimpse or vision of the product/end goal. And then some set of similar, or refined,  or slightly modified practices that carry on during the life of the main product development period. I liken it to getting the skeleton up and running, or the “tree trunk and main branches” upon which we can rapidly build out the app.

This was part of a “Day of Agile” immersion course where the attendees step through a mock development project…

PDF: Iterative Development Path Agenda.

PNG: Iterative Development Path

 

So You Wanna Try Agile?

Well, in a nutshelll, agile is a state of mind.
Agile is relative.
Agile is not dogmatic.
Agile is pragmatic.

Agile is designed to reduce the gap in time between doing something, and seeing a result that you can “measure.”

Blend in Lean concepts.
Read The Goal.
Don’t do giant monolithic things.
Learn how to decompose your “features/expected outcomes” into bite-size chunks.
Don’t plan across a far horizon to the same degree.
What folks are tasked with doing today better be clear and have unambiguous meaning of “DONE”
What folks are tasked with doing in 2 months better be rather nebulous and broad.

Don’t be complacent and relax.
Question the value of deliverables that are needed to fulfill some process step for some other team.
Ask any downstream recipient what they truly need — and why.
Try new processes.
Reflect.
Agile takes constant effort and constant partial attention if you are doing it right.
Be holistic.

Prefer Explicit Cucumber Tests

An Inexact Test

Innocently enough, one of our developers added this feature, which passes:

  Scenario: Create Field
    When I manage the "acme" org
    And I go to the user field management list for "acme"
    And I click "New"
    And I set the following values
      | Name     | Test Field |
      | Required | true       |
    And I click the "Create" button
    Then I should see "Test Field"
    And I should see "test_field"
    And I should see "Yes"

Note: for now I am not going to discuss the other improvements that could be done with this feature (e.g., to remove the “click” steps).

Unfortunately, the actual page looked as follows (using save and open page):

Name        Required?  Key 	
First name  Yes        first_name
Last name   Yes        last_name
Test Field  No         test_field

Sure enough, the text “Yes” was indeed on the page, given the step was defined simply as shown below. However, the intent of the test was actually not correctly followed in the code.

Then(/^I should see "(.*?)"$/) do |text|
  expect(page).to have_text(text)
end

An Explicit Test

So one way to ensure the proper data appears in the proper place on the page, especially when it is in a table, is to do the following.

Add an ID to the page location:

    %table
      %thead
        %tr
          %th.text-center Name
          %th.text-center Required?
          %th.text-center Key
          %th.text-center
      %tbody
        - user_fields.each do |field|
          %tr{id: dom_id(field)}
            %td.text-center= field.name
            %td.text-center
              -if field.required
                Yes
              -else
                No
            %td.text-center= field.key

Change the feature to expect the text exists in the context of the record:

  Scenario: Create New Field
    Given I follow "User Fields" in the sidebar
    And I follow "New Field"
    And I set the following values
      | Name     | Zodiac Sign |
      | Required | true        |
    And I click the "Create" button
    And I should see the following user field:
      | name        | required | key         |
      | Zodiac Sign | Yes      | zodiac_sign |

And define a step something like this:

Then(/^I should see the following user field:$/) do |table|
  # table is a table.hashes.keys # => [:name, :required, :key]
  field = UserField.find_by(name: field_name)
  dom_id = "user_field_#{field._id}"
  table.hashes.each do |row|
    dom_id = dom_id_for_field(row[:name])
    within("tr##{dom_id}") do
      expect(page).to have_text(row[:key])
      expect(page).to have_text(row[:required])
    end
  end
end

Test Your Test!

I also like to check my tests! That is, go to the code where the text “Yes” is defined, and change it to something else. If your tests still pass, you know your test is flawed!

Summary

By adding a “findable” id to the output, you can more exclusively assert some text is on the page in the correct location!

Other approaches

  • ensure you eliminate the other non-essential elements from the page, so there are no “false positives”
  • Check for a very bizarre string that will not accidentally appear, like “Zebra Fangs”

 

User Stories and FDD

FDD?

I bet you never heard of Feature-Driven Development, eh?

Well, Mike Cohn wrote this recent post:

Not Everything Needs to Be a User Story: Using FDD Features

Having worked with Peter Coad since the early 90s, and Jeff De Luca in the late 90s, I’ve been a fan of FDD and naturally turn to that style when “user stories” are not so user-centric. And yes, those are typically the minority items on our backlogs.

Software development is working through a prioritized to-do list. Most of the to-dos should be about addressing user needs. Call them user stories, call them features, maybe even call them requirements. Whatever works best to help you organize and communicate what needs to be built.

Another element of FDD is breaking down (or building up) the system into

  • Major Feature Sets (Quote Management), and their
    • Feature Sets (Clone Quotes, Create Quotation Documents), and their
      • Features (create a quote, edit a quote, archive a quote).

Major Feature Sets might loosely equate to epics 🙂

One of the keys to successful software development, is to combine the list of features with a domain model (and some UI mockups don’t hurt). The domain model need not be to the nth degree of UML detail. But one that clearly describes — in just enough detail — what your problem domain is all about. This eliminates the need to write all sorts of detail in the development issues, leaving that to the model. Then the feature list become more about the order in which we are building up various aspects of the product feature sets.

Thanks for paying a bit of homage to FDD. A blast from the past!

Zurb Magellan Navigation

Love the Zurb Foundation stuff. Love that they freely open-source these cool tools and provide documentation to the community. So, it is hard to complain about “free.” But, in the spirit of community, I think our frustration is often due to being excited about trying out a new, cool, thing, and getting bummed out when running into small roadblocks. (Especially for me, a hacker, who is not really qualified to jump in and discover some crazy cascading javascript or CSS explanation for the odd behavior.)

The disjointed and terse example on the Magellan docs page does leave one asking for more details.

Disjointed example:

  • Arrivals (build, js)

  • Destinations (arrival, destination)
   
  

Arrival

Destination

I had a great deal of trouble to get the nesting correct on my page that also included the topbar element. There seemed to be conflicts with having the topbar being contain-to-grid and fixed.

From what I have gleaned by looking at the page source and doing a lot of trial and error (:boom:), I got something to work “good enough” (as I got tired of the trial and error):

  • In one div, define the arrivals
  • Later in the page, define the matching destinations
  • And fiddle around with divs, nesting, classes, until it works the way you like

An example in haml (sorry for not doing it in HTML, but this is ripped from an app I am writing — modified slightly for this post):

- structure_elements = %w(Access Interior Roof Shutoff Drain FloorPlan SiteDetails)
- structure = @structure

%div{"data-magellan-expedition" => "fixed"}
  %dl.sub-nav
    - structure_elements.each do |element|
      %dd{"data-magellan-arrival" => element}
        = link_to element, "##{element}"
%article#structure
  %h4
    = link_to structure.name, edit_structure_path(structure)
    = link_to fa_icon('pencil'), edit_structure_path(structure)
%hr
= render partial: 'photos/photos', locals: {context: structure, preplan: preplan}
- structure_elements.each do |element|
  %a{name: element}
  %h3{"data-magellan-destination" => element}
    = element
  %div.panel
    ="#{Faker::Lorem.paragraphs(3).join(' ')}"

I hope this helps :heart_eyes_cat:

 


 

Kaminari Paging and Zurb Foundation

I am using Kaminari paging gem and Zurb Foundation 5, and here is what I did to make them work together in HAML fashion:

If you generate the theme (it might not matter which one), for example:

rails g kaminari:views bootstrap

You can see all of the “machinery” in the viewskaminari folder. Here is my “hack” to get Foundations Pagination working with Kaminari:

I tweaked _paginator.html.haml to reflect the Foundation class on the %ul tag:

= paginator.render do
  %ul.pagination
  ...

And I tweaked _page.html.haml to reflect Foundations current class (instead of Kaminari’s active class):

%li{class: "#{'current' if page.current?}"}

And then it just worked!

Kaminari and Foundation Paging

Kaminari and Foundation Paging


A Fool with a Tool

One of my quips that people seem to get a kick out of is:

“A fool with a tool is still a fool”

My point is simple: woodworking tools in the hands of craftsmen can produce fine furniture or musical instruments. But merely the availability of great tools “doth not a masterpiece make.” Not to take the woodworking analogy too far, but power tools can also make it easier for the amateur to get hurt.

The reason a quality piece can be turned out more efficiently with a tool is the ability for the craftsmen to more quickly realize the design and architecture. In addition, tools can help make patterns easier to replicate. From actual patterns (like certain cross-section shapes on molding), to templates (like violin bodies), to connectors (like Kreg pocket hole jigs). A woodworking shop will also make good use of building components to put into larger assemblies.

So, tools in the hands of experts can help realize the design. Tools that are able to help apprentices produce parts designed by the masters, can help produce more output and help train the apprentices.

But put me in a room with the most awesome woodworking tools, and I will not be producing Stradivarius-esque violins any time soon (or ever, most likely).

A Java Developer’s Switch to Rails

As I read this account of transitioning from Java EE to Ruby on Rails,”Java Web Apps to Rails, A Developer’s Experience,” I thought the following:

Regarding the lack of a good Ruby/Rails IDE:

When it was time to look at the code, I was a bit disappointed.  TextMate looked like a popular choice but it fell short in many ways.  I struggled to navigate the code, link the methods across files and follow the code. Grep was my only savior.

I am surprised he did not find RubyMine. JetBrains makes awesome IDEs (IntelliJ IDEA for Java, too). I have to admit at being very impressed that the underlying model of the ruby code within the RubyMine IDE is amazingly capable of giving you the same sort of features that it can for a “compiled,” or more type-centric language like Java.

Ruby

Next he mentioned about learning the language…

My approach to learning Ruby was to start looking at code and figuring out pieces of syntax that did not make sense.  That turned out to be a bad idea. Constructs like “do |x| x+1” threw me off. … I found it very important to understand the motivation behind creating the new language.

There are some good books out there, and other resources…

Another comment rang true with me:

I found it very important to understand the motivation behind creating the new language.

More about the motivation behind Ruby… or at least, how I interpret things.

Ruby treats you like an adult. It doesn’t baby you, or hold your hand, or make you type all sorts of (obfuscating, in my opinion) fluff that a compiled language needs. Your code is more compact and obvious and “dense with meaning,” leading to less need for things like method return types and method parameter data types. Or semicolons.

However, I miss parameters list, curly braces, return statements, camel case naming conventions…

Be patient… soon you will grow weary of having to read all that extra stuff when you go back to Java. If you write well-formed classes, and very small, compact, and obvious methods, you don’t need the extra frills. You will run across the concept of “duck typing” which really means that classic C++/Java/C# style interfaces are not needed. If you create a method that expects a passed-in object to respond to a method call (e.g., “torque”), any object of any class will do — as long as it has that method call! And if you pass in an object that does not have that method, Rails will kindly throw an exception.

The concept of ‘open classes’ that allow developers to go in and change a base class sounds scary.

Go back to my opening statement. “Ruby treats you like an adult.” If you are naive, you can blow your code up and break stuff. If you do everything the Ruby way, you’ll be fine — because you will catch it with tests (right?). There are good rules of thumb for how and why and when you should consider adding to an existing class — or worse, monkey-patching. In Ruby you can actually alter the behavior of an existing method of an existing class. Do it poorly, and you will pay the price. And maybe not for a year or two. Mwahahahaha.

Ruby’s metaprogramming is incredibly powerful (even if the syntax takes a bit of getting used to).

Rails

Rails is incredibly opinionated about how the MVC code should look. It is basically a model-driven architecture approach. The framework expects the MVC stack to have a model, a view, and a controller for each domain concept. (As a long-time domain modeler, and UML guy, this is a real treat.) You can use the default rails generators (interesting when first starting, or for banging out a quick prototype), or write your own twist on a generator. Instead of focusing on the boring framework bits with repetitive, template-like code for each domain object, you can focus on quickly creating features that people want to use and pay for 🙂

Supporting Cast

Ruby on Rails has a great ecosystem of wonderfully talented folks providing 1000s of gems to do all sorts of useful things. For example:

The ecosystem of supporting tools is incredible. Some of my favorites:

These all make it so easy to “do the right thing” and write code with BDD/TDD to provide quality from the start.

Personally, my switch from J2EE to Rails (not to mention SQL to NoSQL/MongoDB) has been one of pure pleasure. The kinds of rich functionality and the ability to build stuff faster is imprerssive. I only wish I were better at writing kick-ass Ruby, Rails, CSS, Javascript, MongoDB…

Is it perfect? Of course not. There are other cool things to look at as well… Meteor, Node.js, MEAN, etc. So much to explore, so little time.

Back to my continuous learning!