All atomic-powered posts filed in “Test Driven Development”:



Agile Alone?

Is it possible to work alone and produce Agile-quality code at the same time? Here at Atomic Object we try to practice pair programming whenever we can, but there are times when it doesn’t work out that way for a project. As fate would have it, I have just come off three consecutive assignments covering a period of over a year that involved working alone for a great majority of the time. I’ve been an agile development proponent for more than five years now and I do actually try to practice what I preach, but my experiences over the last year have tested the bounds of what I would consider “Good Agile Practices.” In this post I’d like to share some of these experiences and describe some of the steps I took to try to stay on the Path.

Read the rest of this entry

Presenter First in GTK and C

Recently Mike Karlesky and I spent a week in the Baltimore area leading up a workshop-style training course. The intent of the workshop was to demonstrate Agile techniques applied in the embedded domain.

As part of the workshop, I created a small GTK application to demonstrate Presenter First and Model-View-Presenter. (Although a GUI application may not seem particularly embedded, the principle is the same: the view walls off some untestable library; the presenter and model allow us to test around it.) GTK turned out to be a good choice, since the events flying out of its widgets were much like the asynchronous events that come out of other windowing toolkits or hardware devices.

And here it is: the aptly named PF Calculator. Guess what? It’s a calculator. The calculator’s functionality is quite limited, in that it can only divide integers, but it still demonstrates Presenter First concepts quite well:
  • The ApplicationPresenter responds to events from the ApplicationModel and ApplicationView.
  • The ApplicationView fires events roughly corresponding to events coming from GTK widgets. Along the way, it does some translation to only relay the relevant information and remove traces of GTK in the event.
  • The ApplicationModel is used to compute the “business logic” (haha, I love that term, especially when applied in such a silly context). The Model delegates to the NumberValidator to get some help when needed.
  • And last (but not least), all of the above code was written Presenter First.

Everything is implemented in C. Here are a few notes about the implementation:
  • In a language with automatic object construction, I’d have the Presenters wire up their events in their constructor methods. Since that strategy isn’t available here, I’ve instead implemented a Presenters_RegisterForEvents function. The purpose of the function is to rip through all of the Presenters and tell them to RegisterEvents. It would be trivial to have the build system automatically generate this file in a project with many Presenters.
  • I only support one subscriptor to any single event. This is because I didn’t feel like implementing a bounded array or linked list to hold the function pointers. I did see something about a GSList data structure available in the GLib documentation, but I never got around to trying it out.
  • I call the gtk_init function in main before firing up the application. I’m not wild about this GTK-specific knowledge leaking outside of the view, but for this very simple example, it was the cleanest way to handle this detail. In a real project I’d strive to keep GTK specifics confined to views.
I depend on a number of libraries and tools to get them job done. More notes:
  • I’m using the Ceedling build and test harness developed by Mike Karlesky, Greg Williams, and Mark VanderVoord. Ceedling gives me easy access to unit testing via Unity, C mock generation via CMock, and C exceptions via CException. Ceedling also weaves everything together to create the executables.
    • Ceedling hasn’t had a 1.0 release yet, but the code available from the Sourceforge project is quite functional.
  • I used this project as an excuse to monkey around with the PCRE library. I didn’t use it extensively, but it was enough to get a taste. It turns out PCRE is tasty.
  • I also recently heard about bstring and tried it out. Again, I didn’t use it for much, but enough such that I’m sold on it.
Warning: I haven’t tried to build this code on anything other than my personal Linux system, so I can’t say how portable it is. Here are some details about my system:
  • The Linux distribution is Ubuntu 10.04.
  • The GTK development files have been installed via the libgtk2.0-dev package.
  • The PCRE development files have been installed via the libpcre3-dev package.
  • bstring is bundled with the project.
  • The build system relies on Ruby and Rake. The build system uses pkg-config commands to gather the build flags for PCRE and GTK. Hopefully this means it will be easier to build the project on an arbitrary system.

To build and run the application, type rake. To run all the tests, type rake test:all. To test an individual module, like ApplicationModel, type rake test:ApplicationModel.c.

Big thanks to Mike Karlesky for assisting with Ceedling, CMock, and Unity. Also thanks to Greg Williams and Mark VanderVoord for helping develop this great software.

Resources:

Edit July 13, 2010: The article was initially published without the Ubuntu package names filled in. This has been corrected.

An intern's first impressions of agile at AO

I am a student at Grand Valley State University, and I have the privilege of interning at Atomic Object this summer. AO has a good relationship with the school, and I had heard quite a bit about the company. When I was looking for an internship in the summer, I placed AO at the top of my list for local companies, but I secretly hoped that I could get accepted to a bigger corporation. Motorola labs scaled back their internship program and my interview with Apple never materialized into a job. Fortunately, Atomic was willing to invest in me this summer. After 4 weeks, I am glad that the other companies turned me down.

Agile is people-centric. On my first day, when the employees welcomed me at the standup meeting, the focus on relationships was evident. The office is free of cubicles and open to everyone. This creates an atmosphere where ideas are easily transferable and people are free to communicate. I was pleased to attend an Atomic Spin Down, where the employees and their families enjoyed a Friday night at the office socializing and playing Rock Band. The employees clearly love their job and working with each other.

The care for the individual continues with Atomic’s clients. It is evident that AO works hard to make sure the clients’ projects succeed. On my second day at work, I was able to participate in a Research, Design, and Planning session where we analyzed the potential users of an application. The client arrived to the meeting with their ideas already formulated for the application. After a little bit of prodding, they were excitedly creating personas of the users. When they left, all parties involved had a deeper understanding of the application. Instead of working with stacks of requirements, AO seeks to understand people.

Agile is test-driven. I have to admit that when I first saw test-driven development, I was a little skeptical. The tests seemed really narrow in scope and I thought you had to write twice as much code. I am still learning a lot about testing, but I definitely appreciate a full suite of tests double-checking our code. Programmers like to trick themselves into believing that they never make mistakes and can always remember what every method does. In reality, we are not perfect. Writing test may take a little more initial investment, but it reduces time tracking down bugs. My current project has made major changes mid-stride. Refactoring code is usually an arduous task, but the tests ease the process.

I have soaked up a ton of information in 4 weeks, and I hope to continue learning across the remainder of the summer. If you are looking to learn more about agile practices, I recommend reading some of the books I have read this past month.

Information Radiators

stoplight

For a business that by definition occupies a highly technical domain, we have some relatively low-tech means of conveying information internally. Sure we e-mail, Twitter, Yammer, and even Skype with each other on a regular basis, but we also make use of yarn, note cards, cork boards, and old traffic equipment. I’m talking about our information radiators, objects around our office that align the team by sharing important information in a fun and hard-to-miss way.

Read the rest of this entry

Testing terminology

Working with some new customers this year has given me fresh perspective on how confusing the terminology of the testing world can be. I think terms and definitions matters a lot, and not just because I’m a recovering academic. Several times recently I’ve found myself in a conversation taking a position in apparent opposition to my companion, only to eventually determine that we were in fact talking about the same thing. Or we might have been using the same words, but actually meaning very different things. I don’t know that the testing world is any more inconsistent in their terms than other technical fields, but it sure seems like it sometimes.

Read the rest of this entry

Harvard Business Review motivates TDD

In the article What Really Motivates Workers, the January-February 2010 issue of Harvard Business Review reports on a multi-year study of top performance motivators. Between these five contenders:
  • Instrumental support
  • Progress
  • Interpersonal support
  • Collaboration
  • Important work

progress was the top motivator by a large margin.

(Unfortunately, when the researchers surveyed 600 managers they found that most of them believed that “recognition for good work” was the top motivational factor.)

I think the study explains why test-driven development (TDD) is self-sustaining once mastered. Large software projects done in traditional fashion may go for months without finishing or delivering anything. That’s a hard situation in which to see progress, and hence un-motivating. The same project done with TDD results in a smaller system becoming functional more quickly, daily progress as you integrate your working code and tests with others, and even hourly progress in the form of the “green bar” of passing tests. Progress is more visible and more reliably and regularly experienced.

The author also found that the most de-motivating days were those where people experienced the opposite of progress: a setback. Anyone who’s worked on a body of un-tested legacy code knows how common it is to make a change and break something. Setbacks are a de-motivating experience made more common by the lack of any test control.

Developers are motivated by the progress TDD brings and shows them.

Faster, better, cheaper! TDD wins in a simple experiment

Earlier this year I had the unusual opportunity to work on a project with another developer (I’ll call him Dave – not his real name) in which each of us was free to choose our own method of application development.

This is certainly not an ideal situation. At first I considered following the client’s (Dave’s company) development methods just for consistency, but I ultimately decided to follow TDD for my portions of the project for several reasons:

Read the rest of this entry

Testing Swing applications using JRuby

Demetrius Nunes recently posted about his Swinger library to the JRuby mailing list. Swinger uses Cucumber and Jemmy to provide a test harness for automating Swing tests.

I responded to Demetrius letting him know how great it is to hear others are interested in automating Swing testing. We’ve been using a combination of FEST and Ruby helpers specific to our own Swing applications. As Demetrius notes, Swing tests can be frustratingly brittle, but they are still well worth the investment. Swinger looks like it is both extensible and can help alleviate some Swing testing pain.

You can check out my response here and the entire discussion here.

Nesting RSpec Describes

Like many people at AO, I have come to enjoy testing code in Jay Fields' one assertion per test style.

This style is great for testing because it clearly establishes intent for each test. This point is invaluable when another developer either inherits your code, or you revisit it at some point in the future. The main problem with this style is the need to create stubs for all the calls in the describe's before block, or resort to using stub_everything for all your mock objects. These are both fine solutions for simple code, but as soon as the logic encounters a condition you may be setting yourself up for potential testing bugs, and difficulty when you add new logic.

One way to avoid this problem is to leverage the power of rspec, and use nested describe blocks for each condition statement. This helps limit the before block for each describe to only define the stubs for that condition block. This is helpful because it prevents the tester from accidentally defining a stubbed expectation for something that should not happen. It also creates a nice placeholder for adding logic into the code in the future.

The following example shows how nesting rspec describes works. It is important to note that the branch that contains the most logic should be encapsulated in the sub-describe.

Example Source Code:

1
2
3
4
5
6
7
8
9
10
11
12
13
class Example 
  def run(director, runner)
    runner.prepare
    if director.go?
      runner.run
      if runner.complete?
        director.stop
      end
      runner.stop
    end
    runner.finish
  end
end

Example Test Code with nesting describes:

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
describe Example do
  before do
    @target = Example.new
  end
  
  describe '#run' do
    before do
      @director = mock
      @runner = mock
      
      @runner.stubs(:prepare)
      @director.stubs(:go?).returns false
      @runner.stubs(:finish)
    end
    
    it "should prepare the runner" do
      @runner.expects(:prepare)
      @target.run @director, @runner
    end
    
    it "should check the director" do
      @director.expects(:go?).returns false
      @target.run @director, @runner
    end
    
    describe 'director returns true for go' do
      before do
        @director.stubs(:go?).returns true # redefine
        @runner.stubs(:run) 
        @runner.stubs(:complete?).returns false
        @runner.stubs(:stop)
      end
      
      it "should run the runner" do
        @runner.expects(:run)
        @target.run @director, @runner
      end
      
      it "should check if the runner is complete" do
        @runner.expects(:complete?).returns false
        @target.run @director, @runner
      end
      
      describe 'runner returns true for complete' do
        before do
          @runner.stubs(:complete?).returns true # redefine
        end
        
        it "should stop the director" do
          @director.expects(:stop)
          @target.run @director, @runner
        end
      end
      
      it "should stop the runner" do
        @runner.expects(:stop)
        @target.run @director, @runner
      end
    end
    
    it "should finish the runner" do
      @runner.expects(:finish)
      @target.run @director, @runner
    end
    
  end
end

I realize the test code gets a bit long, but it is very easy to understand and extend. Also, nesting on conditional breaks creates an easy framework to follow when writing test code.

Building scaleable web apps

Web entrepreneurs, at least the ones we’re experienced with helping, have limited budgets. They’re also inherently optimistic people, believe deeply in their idea, and want confidence that their development team will build something that handles the heavy traffic that success will bring. The answer they want to hear is usually something like, “we design scaleability in right from the start”. Our experience tells us there’s a better way.

Read the rest of this entry

Using Tests for Requirements Management

Everybody who gets excited about requirements management and documentation – raise your hand. Okay. Thank you. You’re free to go. For those left – you can mate automated tests with a bit of convention and scripting magic to simplify your requirements management life. Here’s how.

Read the rest of this entry

Saved by Tests - Upgrading to Rails 2.2.2

Two weeks ago, I upgraded a project from rails 2.0.2 to 2.2.2. I had done some polymorphic associations, and I needed more powerful eager loading to prevent N+1 queries. The latest version of rails happens to meet my needs perfectly.

I told the customer that this work needed to be done and that it might take a few days to do it right, as it's a large project and depends on a large number of gems and plugins. The customer was very reasonable and said if it had to be done, then we'd take the time to do it right. So I did the upgrade.

Read the rest of this entry

Testing Ensemble Productions

This article is a follow-up to Test Automation in InterSystems Cache and Ensemble. An Ensemble production is a configuration of objects that interact with each other and perform different tasks. A typical HL7 production is composed of inbound services, message routing processes, transformations, and outbound operations.

Typically productions are tested manually by observing desired outcomes. However, manual tests do not exercise individual components of the system and do not lend themselves to automated regression testing. We at Atomic Object have had great success breaking up a production into its components and building automated functional and unit tests for these components.

Read the rest of this entry

Testing and Legacy Code, A Primer

In the last few weeks, customers and potential clients have asked me on several occasions how Test-Driven Development relates to legacy code (incidentally, one fitting definition for legacy code is code having no test suite).

As much as we all might like to throw out legacy code (especially when it’s craptacular) and “do it right”, that’s often an entirely impractical option or just a plain dumb thing to do. Reality is that there’s no magical formula or one-size-fits-all procedure for dealing with testing and legacy code. Each case is unique and requires a thoughtful, responsible approach. That said, I offer here guidelines toward tackling the challenge in a thoughtful, responsible way.

Read the rest of this entry

Test Automation in InterSystems Cache and Ensemble

Atomic Object has been providing development and consulting services for a company in the healthcare industry. We’ll refer to this company as DoctorsInc hereinafter. Our primary focus was to bring agile project management and TDD practices to DoctorsInc’s development process. The group that we worked with at DoctorsInc uses a powerful ETL tool called Ensemble.

Ensemble is a product developed by a company called InterSystems that sits on top of another product called Cache. Cache is an integrated development platform and OODB that provides a powerful set of tools for development, database management, and much more.

Read the rest of this entry