Donnerstag, 18. Oktober 2012

The Agile Manifesto – Refactored

Most of you know the infamous "Manifesto for Agile Software Development":
We are uncovering better ways of developing
software by doing it and helping others do it.
Through this work we have come to value:
Individuals and interactions over processes and tools
Working software over comprehensive documentation
Customer collaboration over contract negotiation
Responding to change over following a plan
That is, while there is value in the items on
the right, we value the items on the left more.
The last paragraph is often overlooked which results in counterproductive chaos. This might be related to the specific wording. Recently, another wording occurred to me that might be more intent-revealing and might resolve some misunderstanding. It is a little more focused on the work in agile development.
We use processes and tools as long as they do not impede individuals and interactions
We provide comprehensive documentation as long as it does not impede working software
We do negotiate contracts as long as it does not impede customer collaboration
We follow a plan as long as it does not impede responding to change
What do you think?

Mittwoch, 30. November 2011

"Models" at Agile Testing Days 2011

Out there are numerous, brilliant articles on Agile Testing Days 2011. Most of them focus on a single talk or a single conference day. I would like to take another approach: I am going to pick some topic that connects multiple talks and take a look at the conference from this specific point of view.
The one topic that seems to be the most prominent one is simply "models".

Definition
I would like to start by giving my "favorite" (academic) definition of a model. According to Herbert Stachowiak, a model has at least these three attributes:
  • transforming: a model is a transformation of a natural or artificial original (which can be a model by itself),
  • reducing: a model does not include all attributes of the original, but only those that seem to be relevant to the model creator or model user
  • pragmatic: An original does not have a single, unique model. Models are designed to replace the original
    • for certain subjects (who?),
    • within a certain time interval (when?), and
    • in respect to certain mental or real operations (what for?).
Building Models: Learning
According to Liz Keogh, learning is the process of building (mental) models. When we build models, we delete, distort and/or add information. Based on observed data, we filter the data, generate assumptions, draw conclusions and finally build beliefs. Unfortunately, our beliefs influence our mental filters and thus might constrain our ability to learn. In order to improve our filters we have to adjust our beliefs.
As Esther Derby pointed out, humans are good at spatial reasoning, but bad at temporal reasoning. When we have to analyze temporal problems, we should try to convert them into spatial problems. One option is a graphical model of temporal data, e.g. time lines.
Michael Bolton gave a very good demonstration of the model building process. In the TestLab, he built a model of an application under test through Exploratory Testing. Based on James Bach's "Heuristic Test Strategy Model", he developed a rather comprehensive mind map describing the product and came up with lots of ideas for further testing activities. It became obvious that "Exploratory Testing is simultaneous test design, test execution and learning."

Using Models
David Evans emphasized that "[test] coverage is [implicitly] measured by reference to models". That is why "you can have complete coverage of a model, but you can never have a complete model". This is due to the reducing nature of any model. And finally David pointed out that "the more complete the model is, the less you can economically cover."
When it comes to complex systems, "there are no clear cause and effect relationships. Accept Uncertainty and complexity. Experiment and measure what really makes things better" (Liz Keogh). You might visualize some relationships using Diagrams of Effects aka. Causal Loop Diagrams (Esther Derby)
Gojko Adzic presented two specific models during the conference: effect maps are a way to model the relationships between software features and a business goal. They can be used to deduce possible activities from a business goal, select the most promising activities and measure their impact on the business.
Gojko started the initiative visualisingquality.org to gather models that facilitate the communication of quality attributes to stakeholders and management. He presented the ACC Matrix that was developed by James Whittaker at Google as one measure.

And What's the Tester's Job?
In a nutshell, testers challenge / break models. They help developers to make more accurate models (Liz Keogh). Thus, model creation is one of the main responsibilities of effective testers.

Donnerstag, 3. November 2011

On the Status of SoCraMOB (Software Craftsmanship in Münster,Osnabrück,Bielefeld)

From September 1 through September 2 I participated in SoCraTes 2011, a gathering of German software developers who are interested in Software Craftsmanship. It became the spark for a German Software Craftsmanship Community that is now organized under the label "Softwerkskammer". Me and three other participants volunteered to build up a regional community in Münster/Bielefeld/Osnabrück.
On October 19 we set up a kick-off meeting in the .space Osnabrück. Fortunately there are quite a few other people in the area who are deeply interested in the matter. It was easy to mobilize them for the kick-off. There were 11 people in the meeting; only four of them had been to SoCraTes!
In my opinion we had a great discussion on different aspects of Software Craftsmanship - agile processes, domain-driven design, test-driven development, educating junior developers. All the attendees were very energized.
This was the beginning of the regional community; we named it "SoCraMOB" ("Software Craftsmanship in Münster, Osnabrück & Bielefeld").
It turned out that a relevant number of members live/work in Münster. And people did not feel up to traveling to one of the other cities for (short) evening events in the future. We agreed on a different form of meetings: We are going to organize whole-day workshops on every second Saturday in a quarter. The program will be a mixture of open space sessions and coding dojos. The first one will be on January 14 in Münster. The members in each of the cities are free to organize local events.
Besides, Martin Klose and Jaroslaw Klose are going to stage a code retreat in Bielefeld in the context of the Global Day of Code Retreat.
The next step is to spread the word in the area. We already talked to the local .NET User Group on October 26. The people there were all energized and interested in the matter, too; all developers across technological barriers seem to have similar problems in terms of organization, development process, and team communication. The .NET User Group set up a coding dojo immediately for November 30.
The local Münster community are going to meet for a round-table on December 21. One of the topics will be the organization of the first SoCraMOB on January 14.

Montag, 17. Oktober 2011

Kick-Off: Software Craftsmanship in Münster/Osnabrück/Bielefeld

During the kick-off meeting for the German Software Craftsmanship Community (SoCraTes 2011) from September 1st through September 3rd I joined a group of participants who want to organize a regional Software Craftsmanship Community in the area of Münster/Osnabrück/Bielefeld.
I am happy to announce the first community meeting for the next Wednesday, October 19th, in the .space Osnabrück. We hope to bring several people from the area together. We are going to discuss what modern sensible software development should look like nowadays. Whatever language you use or which frameworks you employ, everybody is warmly welcome.
For more information and registration please see the Xing event page.

Sonntag, 18. September 2011

SFD Münster: PDF reports with Cucumber

By this post, I want to complete my talk on "Executable Specifications using Cucumber" during Software Freedom Day Münster.

Yesterday the JUG Münster and the produktivhaus | Coworking Space organized a local event associated with the world-wide Software Freedom Day. In my opinion, the event was quite a success.
In the course of the afternoon talks, I also took the opportunity. I chose the topic "Executable Specifications using Cucumber". All in all, my was not too bad, I suppose. But one thing bugged me: after delivering my talk (and a small, live-coded example), one participant asked me, what was the special advantage of using Cucumber for writing acceptance tests. Generally, I think that the advantage is the understandability / readability of the feature files. Gherkin (the language in which the features are described) has only minimal syntactical demands. Most of the content is simple prose (and some tables). This is easy to read and understand for business users what facilitates discussions, because they and the developers are nearly instantly able to write new feature specifications, change (and maintain) existing ones etc.
Another pro is the possibility to create PDF reports automatically. This is useful for management information, printing and archiving. I wanted to demonstrate the feature. Unfortunately, there was some kind of problem with the PDF generation mechanism. I was not able to resolve the issue immediately, so I could not prove my argument. I want to make up on this with this post.
When the event was over, I analysed Cucumber's log output. Finally, I found out that Cucumber relies on the Prawn gem to create PDFs. And Cucumber is built against an old version of Prawn, 0.8.4. I had not defined the desired version of the gems in my Gemfile, so Bundler downloaded the most recent version, which is 0.11.1, respectively 0.12. Because obviously the API changed in the meantime, Cucumber terminated untimely. The correct content of the gemfile is:

source :rubygems

gem "cucumber"
gem "capybara", ">=1.1.0"
gem "selenium-webdriver"
gem "rspec", ">=2.6.0"
gem "prawn", "~> 0.8.4"
gem "prawn-layout", "~> 0.8.4"

Executing
bundle install
and
bundle exec cucumber features --format pdf --out report.pdf
finally creates a feasible report:


Montag, 20. Juni 2011

My (unauthoritative) list of book recommendations

After my workshop on Ruby on Rails on Saturday I was asked to recommend some books on programming, Agile and similar topics. I don't feel like an authority, because I didn't read at least half of the books I assume to be import. But these are my current recommendations.
(I allowed myself to link the titles to Amazon using a personalized link; when you order one of the books by following a link within this post I will be rewarded a small amount of money; you might reward my gratuitious engagement for the SkillShare workshop this way)

Ruby on Rails books

I just advice the classics on Ruby and Rails:

My personal top 3

  1. Martin Fowler: "Refactoring" (also available as Ruby Edition). This book was a real eye-opener for me. Afterwards software was way "softer" to me. I became able to knead my code towards the direction I want.
    And besides, Refactoring is the basic ability in becoming agile. It enables you to evolve and extend your code and it is one of the three phases in TDD which is the next level when becoming agile.
  2. Robert "Uncle Bob" Martin: Clean Code. This book literally boosted the quality of my code. It gives lots of tips on the common principles when programming like good naming, refactoring the code, unit-testing, concurrency, and so on.
  3. Lasse Koskela: "Test Driven". This book was a key source for my diploma thesis in 2010. It gives a nice introduction to TDD, ATDD and an agile development process. A nice book to get you started.
This list might change with the next Amazon shipping ;-)

    Books I'm about to read / I was adviced to read

    When you are interested in more books, just leave a comment and I will post further tips. You might also name a specific topic.

    Montag, 6. Juni 2011

    Introducing New Features - Done Right

    One of my customers offers articles in campaigns to his customers and allows orders for these campaigns. Once upon a time I was involved in the creation of the specific web application with some fellow students. And I am still engaged in maintaining and extending the system.
    So far there was the restriction that there are no temporally parallel campaigns, they had to be in strict chronological order. Now my client wants to offer several campaigns at a time. Up to now, the concept of a "campaign" was hidden within a GUI component, namely a JavaServer Faces backing bean. So the following requirements had to be fulfilled:
    • Present multiple, parallel campaigns to the customer
    • Select one of those campaigns
    • Present the order process for the selected campaign
    So first of all, as an apprentice of the Acceptance Test-Driven Development community, I wrote an acceptance test for the new feature (slightly simplified):
    Given there is an active campaign C with product P
    And there is an active campaign D with product Q
    When I order 17 pieces of P
    And I order 42 pieces of Q
    Then I want to receive 17 pieces of P
    And 42 pieces of Q
    
    Afterwards I automated the acceptance test as an end-to-end test using Selenium/Webdriver 2. Good boy!

    The Mistake

    I carried out the necessary implementation steps in the wrong order.
    1. First of all I blew up all of my unit / integration tests by introducing a list of the former unknown concept "Campaign". Afterwards it took me more than a week to move the functionality from the backing bean to the new Campaign class and refit the existing tests.
    2. Bad enough, but I could do worse. I spotted several dirty parts in the existing nested objects of Campaign, respectively the backing bean (e.g. an Order or an OrderLine). And I started to fix them immediately: specialize and devide some functionality in subclasses, generalize other parts and so on. But I didn't formulate and rearrange my unit tests first, I just changed the production code. So while my tests were already failing, I changed the production code even further, breaking more and more tests. So what should have been a small change ended up in more than a week of work for a single commit...

    So what went wrong?

    While succeeding in ATDD, I simply missed basic concepts of TDD:

    1. Test comes first, afterwards refactor the code or write new code to pass the test.
    2. When a change is hard to do, refactor first to enable the change.

    I didn't evolve the new functionality from the existing one, but did a rewrite in fact (and reused parts of the existing code).

    How you do better

    At first, extract the concept of a Campaign from the backing bean (Extract Class Refactoring); reference just one Campaign from the backing bean. By forwarding the method calls to the backing bean to the new Campaign object, all of the tests stay green while moving attributes and methods. When all of the functionality is moved bit by bit to the new Campaign class, you can inline the delegating methods in the backing bean (Inline Method Refactoring). So these methods disappear and the access to the newly created Campaign field will become explicit in the tests. Finally move the existing tests concerning the functionality of Campaign from the existing BackingBeanTest to a new CampaignTest. All the tests stay green all the time. And that gives you
    • little risk
    • more confidence
    • and a whole lot of fun. Commit.
    While browsing the code you might spot some ugly parts. But don't touch them while changing another part of the system. Simply write it down on your todo-list. When your first change is done, you can turn toward the next item. When you want to rename some of your classes for the sake of more expressiveness, you can search for the corresponding name in your build path. Then you rename the class, all references to that class, the corresponding test class, and the variables referencing an object of the class, consistently (Rename Class Refactoring). Commit.
    One method to clean up a class violating the Single Responsibility Principle is creating subclasses addressing the different responsibilities. You split up the existing test class into two separate test classes. You can then pick the necessary test cases / methods from the former test class and assign them to the new test classes by their relevance to the former mixed up responsibilities (similar to the Replace Type Code With Subclasses Refactoring, see also the "Anti-If" school). You can pull up common custom assertions into the superclass. After reorganizing the test cases you can split the production code into two subclasses, move the method and fields specific to just one subclass in the corresponding file and keep common functionality in the superclass. This process takes a little more time but it's a task of reasonable size. Commit.
    Ah, and finally you can introduce the list of Campaigns easily and determine the selected one in the backing bean. Change done. Acceptance test passes. Mission accomplished.

    What I learned from my mistake

    • Refactoring and evolving a new functionality are fundamentally different. The sequence of the steps is nearly inverse.
    • Refactoring demands more discipline.
    • And the top priority is the following: don't ever break your tests!