Syndicate

OPML
RSS
Atom

ThoughtWorks Studios

ThoughtWorks' Agile Project Management application

Alumni

Ade Oshineye (feed)
Adewale Oshineye (feed)
Aidan Rogers (feed)
Alan Francis (feed)
Alex Ruiz (feed)
Alex Verkhovsky (feed)
Alla Zollers (feed)
Amit Rathore (feed)
Andres Taylor (feed)
Andrew Palmer (feed)
Andrew Trigg (feed)
Aslak Hellesoy (feed)
Ben Griffiths (feed)
Ben Hogan (feed)
Ben Stopford (feed)
Benno Rice (feed)
Bernardo Silva (feed)
Bill Six (feed)
Bradford Cross (feed)
Bret Pettichord (feed)
Brett Dargan (feed)
Brian Oxley (feed)
Candace Wong (feed)
Carlos Villela (feed)
Cenk Civici (feed)
Chaoqun Li (feed)
Charles Lowell (feed)
Charles Tse (feed)
Chris Brown (feed)
Chris Matts (feed)
Chris McMahon (feed)
Christian Kvalheim (feed)
Christian Taubman (feed)
Christopher Johnston (feed)
Craig Cruden (feed)
Damana Madden (feed)
Damian Guy (feed)
Dan Berlin (feed)
Dan North (feed)
Dan Wieringa (feed)
Daniel Manges (feed)
Daragh Farrell (feed)
Darren Hobbs (feed)
Dave Astels (feed)
Dave Hoover (feed)
David Kemp (feed)
Dennis Byrne (feed)
Dragos Manolescu (feed)
Drew Olson (feed)
Duncan Cragg (feed)
Dustin Aleksiuk (feed)
Elizabeth Keogh (feed)
Fabio Gavilondo (feed)
Fred George (feed)
Garrett Smith (feed)
Gautam Ramamurthy (feed)
Geoff Oliphant (feed)
George Malamidis (feed)
Greg Luck (feed)
Greg Wdowiak (feed)
Gregor Hohpe (feed)
Griffin Caprio (feed)
Hsue-Shen Tham (feed)
Igor Stoyanov (feed)
Isaiah Perumalla (feed)
Ivan Moore (feed)
Jack Bolles (feed)
Jake Scruggs (feed)
James Mead (feed)
James Ross (feed)
James Webster (feed)
Jason Huggins (feed)
Jay Fields (feed)
Jeff Patton (feed)
Jeff Santini (feed)
Jeremy Stell-Smith (feed)
Jeyageethan A (feed)
Joe Homs (feed)
Joe O'Brien (feed)
Joe Walnes (feed)
Jon Eaves (feed)
Jon Pither (feed)
Jon Tirsen (feed)
Jonathan Rasmusson (feed)
Josh Evnin (feed)
Josh Price (feed)
Joshua Graham (feed)
Julian Simpson (feed)
Karthik Chandrasekariah (feed)
Kashan Arshad (feed)
Kent Spillner (feed)
Kerry Todyruik (feed)
Kiran Bellubbi (feed)
Kurt Schrader (feed)
Kurtis Seebaldt (feed)
Li Xiao (feed)
Marco Abis (feed)
Marcus Ahnve (feed)
Mark Thomas (feed)
Marty Andrews (feed)
Matt Clarkson (feed)
Matthew Buckland (feed)
Matthew Deiters (feed)
Matthew Ueckerman (feed)
Megan Folsom (feed)
Michael Klynstra (feed)
Michael Schubert (feed)
Michael Ward (feed)
Mike Mclaughlin (feed)
Mike Melia (feed)
Mike Roberts (feed)
Mike Williams (feed)
Muness Alrubaie (feed)
Narayan Raman (feed)
Narayan Raman (Sahi) (feed)
Naresh Jain (feed)
Narla Keshav Ram (feed)
Nat Pryce (feed)
Nathan Arthur (feed)
Nicholas Carroll (feed)
Niket Kumar Bhumihar (feed)
Niranjan Peranjape (feed)
Obie Fernandez (feed)
Obie Fernandez (feed)
Obie Fernandez (JRoller) (feed)
Owen Rogers (feed)
Pankaj Nakhat (feed)
Patrick Farley (feed)
Paul Coia (feed)
Paul Gross (feed)
Paul Holser (feed)
Paul Ingles (feed)
Paul Julius (feed)
Paul Miles (feed)
Peter Barry (feed)
Peter F Ryan (feed)
Philippe Hanrigou (feed)
Prashant Gandhi (feed)
Rene Duquesnoy (feed)
Richard Watt (feed)
Ricky Lui (feed)
Ross Niemi (feed)
Ryan Kinderman (feed)
Shane Duan (feed)
Shane Harvie (feed)
Simon Stewart (feed)
Siva Jagadeesan (feed)
Srushti Ambekallu (feed)
Stacy Curl (Digital Compulsion) (feed)
Steve Freeman (feed)
Szczepan Faber (feed)
Ted Neward (feed)
Thamarai Poomalai Selvan (feed)
Thomas Looy (feed)
Tim Bacon (feed)
Tim Goodwin (feed)
Tim Velvick (feed)
Vishnu Iyengar (feed)
Vivek Vaid (feed)
Wilkes Joiner (feed)
William Caputo (feed)
Xiaoming Wang (feed)
Xin Huang (feed)
__ThoughtBlogs-Admin (feed)

Selenium Grid is an adventure that started in 2007. Faced with a challenging rescue mission of a software project in Atlanta, my team decided that – in order to succeed – we needed a quick and reliable feedback loop for tests written at the browser level. The idea was to be able to safely refactor the code as well as the unit and functional tests we inherited: All were poorly written, the rescue team had lost faith in them, and progress on this project had ground to a halt.

We really needed these in-browser tests, yet we were also very wary of the maintenance effort and delay in the feedback loop. We had all already been burnt by acceptance tests that were not only expensive to maintain but that had also, over time, evolved into gigantic beasts that took hours to run. So we wanted a tool that would arm us with an efficient feedback loop as well as provide a fertile experimentation ground. At the time there were no tool around we could find that would fit the bill, so we did what good engineers do… we built our own!

Zak Tamsen, Dan Manges, and David Vollbracht went on to write DeepTest, a distributed test runner for Ruby, while I created Selenium Grid, a tool to intelligently distribute Selenium test sessions across multiple machines.

The rest is history – we rescued the project, open-sourced DeepTest and Selenium Grid , which are now both used in a couple of high-profile companies.

The reason I am starting this post with a trip down memory lane is to explain that the next two announcements do not come easy. As a matter of fact they are quite charged with emotions on my part.

Selenium Grid 1.0.5 Release

First, I am announcing a new Selenium Grid release, which provides new self-healing features to better cope with unresponsive Remote Controls and Hub restarts.

Selenium Grid Needs a New Maintainer

Second, I am ceasing development on Selenium Grid. This is my last release. I will no longer be managing patches, bug reports, support requests, and feature requests nor actively contributing to the project.

It has warmed my heart to see Selenium Grid take off and used in so many projects. However I have finally come to terms with the fact that I do not have sufficient cycles to work on this project. Since this has been the state of things for a while, I am simply getting too burnt out on Selenium Grid. It was a hard decision to make, but I am convinced that, in the end, finding new leadership is better for the project and for the community.

This is not the end of Selenium Grid though. So if you are interested in becoming the new maintainer of Selenium Grid, please send me a quick email. It would be great to swiftly identify new project leadership and start the transition.

Thank You

When I look back at these years spent on Selenium Grid my strongest feeling is gratitude, and this is how I want to end this post.

I am deeply indebted to Zak Tamsen who motivated all of us to find a solution to transparently distribute tests accross multiple machines and provided the environment and management buy-in necessary to make it happen. Thank you so much also to Dan Manges and David Vollbracht for DeepTest: without it Selenium Grid would not have much sense. And obviously thank you to the entire ThoughtWorks’s team in Atlanta for their support, original brainstorming discussions, and insightful ideas. I miss you all.

I am also incredibly grateful for the warm welcome and support that I immediatly received from the Selenium leadership team, and especially from Patrick Lightbody, Jason Huggins, Dan Fabulich and Paul Hammant. Thank you guys!

Finally, I cannot express how much I appreciate the support from everyone who has contributed code and patches back to Selenium Grid, shared their success stories, or even simply shared some kind words and encouragement. It means a lot to me. Special shout outs go to Matt Todd, Benjamin Lee,Bob Cotton, Kevin Menard, Carlos Sanchez, Christian Eager and Shannon Lal who contributed significant chunks of code or documentation.

Alberto Gutierrez has a great list of development principles any agilist should take to heart. I like that the list is organized in such a way I can easily present it to management.

I also enjoy his post formatting and layout — it's like reading a good newspaper with modern typography. Into my reader feed goes Alberto.

Dear Apple,

Although I love your products, as long as you continue to pursue your lawsuit against HTC, I shall no longer be buying any of them for the forseeable future.

Best regards,

Darren

Claim Token - TSUMZ23P479U
Dates: April 17th and 18th 2010
Venue: The International Centre,

Goa University Road,

Dona Paula Post office, Goa- 403 004

Format: Open Space

Agenda: Each day we start at 9:00 AM and end at 5:30 PM.

Each Day:

  • Lightning Talks (1 hr)
  • Opening the Space (30 mins)
  • Creating the agenda (30 mins)
  • Break-out sessions (5 hrs)
  • Closing the Space / Retrospective (30 mins)
  • Social Outing (optional)

Budget:

  • We plan to hire the main hall for 2 days. Each day cost is roughly about 10,000 Rs. For 2 days it would be about 20,000 Rs.
  • Lunch + Tea/Cofee Breaks would cost 200 Rs per person.
  • Venue has good A/C accommodation. Its Rs 1500 per day for single room and Rs 1800 for double room.

(Please note that this is a special discount rate for Goa University.)

I’m expecting about 25 people to show up.

So basically each individual will be spending about:

  • 3000 Rs for the room
  • 400 Rs for food
  • max 1000 Rs for the hall
  • Evening outing: up to the individual

(if we find a sponsor, then the cost of the hall and food will be absorbed by the sponsor.)

Prep Work: Answers to the following questions will facilitate the following:

  • help us come more prepared for the Coach Camp
  • get a sense of the quality of the participants
  • start some knowledge sharing amongst the group
  • set certain context and potential topics for further discussion at the Coach Camp

We’ll confirm your participation on successful completion & submission of this form. The sooner you submit the form, the sooner we can confirm your participation.

*Dead line to submit the form: 22nd March 2010.

Loading…

38: The Golden Lock
39: The other Picadilly

I just listened to a great Scott Hanselman podcast (Jan-8-2010) talking about a book I have always read (or write) called:

Hello World! Computer Programming for Kids (and Other Beginners): Computer Programming for Kids and Other Beginners

Written by the father son combo Warren and Carter Sande, this book seems perfect for kids (and even adults) who are looking for a fun easy way to get into programming.

I haven’t read the book, but the amazon reviews are excellent. All I know is the code samples are written in Python.

So if you are looking for a fun way to get your kids into software, this may be the book you are looking for.



Filed under: books Tagged: beginners programming, Carter Sande, hello world, kids, programming, Python, Warren Sande

The Agile Software Community of India (ASCI), (a registered society founded by a group of Agile enthusiasts and practitioners from companies all around India) has successfully organized yet another agile conference in India called ‘Agile India 2010’. For the first time in India, we had 4 Gordon Pask Award Winners at a single conference: David Hussman, Jeff Patton, J. B. Rainsberger and Naresh Jain. Also for the first time, ASCI organized a unique twin-city conference, where this 2-day event was held in Mumbai (Jan 16th and 17th) and in Bangalore (Jan 22nd and 23rd, 2010).

The Goal of the conference was to challenge the process dogma, provide food for thought for creative problem solving and help us take the art-of-software-development to the next level. This year, the focus of Agile India 2010 was on real Agile practitioners who’ve “been there, done that and wanted to explore the future of Agile.” Targeted at Agile enthusiasts, researchers and educators, Agile India 2010 offered an ideal platform for attendees to network and learn about the latest research and cutting-edge Agile industry practices directly from the experts through talks, hands-on technical sessions, workshops, competitions and tutorials.

The conference featured 26 recognized National and International speakers, over 250 enthusiastic participants from over 75 companies, 7 Keynote talks, 10 Workshops/Tutorials, 5 Product Demos, 7 Experience Report, 25+ Lightning talks and a thrilling Programming with the Stars competition.

Like every year the conference participants were gifted with a Conference T-Shirt and a carefully selected book as a souvenir. This year the participants had a choice between 3 books:

  • Apprenticeship Patterns
  • The Art of Lean Software Development
  • The Productive Programmer

ASCI is proud to partner with our sponsors, BNP Paribas, ThoughtWorks and Xebia and our Mumbai host Mukesh Patel School of Technology Management & Engineering to bring this conference to you. Our sponsors, also corporate members of ASCI, have been long-term supporters and promoters of Agile Software Development methods globally. A special thanks to Industrial Logic for providing the support to organize this event possible. Also a big thanks to our supporters, Directi, Binary Essentials and Agile Alliance.

Some of the highlights of Agile India 2010 included “Programming with the Stars” - a fun post-lunch segment each day where “ordinary” conference attendees paired with legendary developers from top companies around India, who have attained a high degree of mastery in Agile development. The duos perform live on stage in front of a panel of judges, David Hussman, J. B. Rainsberger and Jeff Patton. PWTS lived up to its expectations by being both entertaining and educational. Rajesh & Amit were rated as the best pair in Mumbai. While Bhavin and Mukesh won the best pair title in Bengaluru.

The conference also featured over 25 lightning talks where participants shared their thoughtful, unique idea about Agile in under 3 minutes.

Also this year the conference tried to be as environmental friendly as much as possible. Some of the steps taken at the conference were:

  • Skipped handing out printed material like conference program, printed handouts & slides (except for what the conference sponsor handed over).
  • Skipped handing over notepads & pens. Another big source of wastage. Very few people take notes and they usually carry their own.
  • Lunch and snacks were served in washable plates & steel spoons. Usually conferences use throwaway plates and plastic spoons.
  • For drinking tea, coffee & juice, we requested the conference participants to carry their own mugs & water bottles.
  • Conserving Electricity: We tried to switch off projectors and Air Conditioners when ever possible.

To back all of this, both locations had an enlightening talk from Captain Planet (aka Saurabh Arora) showing the effect of global warming and how we can take small steps everyday to avoid further worsening the situation.

Like every Agile India conference in the past, this conference left delegates coming away with new ideas on how to improve their software development process by applying Agile practices to development and delivery. All the conference slides are available from the conference program page on our site www.agileindia.org/agileindia2010.

By now you must have heard/read numerous people explain the pitfalls of multi-tasking and why its evil.

multitaskingevil

Some people offer some decent advice on how to avoid Multi-tasking:

While I agree with everyone here. There are things in my daily life that contradicts (to some extent) what they are claiming to be universally true for all humans. For Ex:

  • I listen to the news on the radio every morning while I brush my teeth
  • I have interesting, deep conversations with friends/family while driving on Indian roads (driving itself involves multiple tasks. Driving on Indian roads adds a whole new dimension to it)
  • The Indian Gods had attainted a whole new level of multi-tasking ;)

multitasking

What I’m trying to highlight here is not all multi-tasking is bad/inefficient. If I take the driving example, I can do other tasks while I’m driving. My efficiency starts to go down if I’m driving to new destinations. It further goes down if I’m driving in a different lane-system and a different car.

Its important to note that multi-tasking does not hurt you much if the activities you’re performing are routine activities (embedded in your long-term memory and is referred to as muscle memory.) Multi-tasking becoming significantly exhausting, error-prone and inefficient if the tasks you are performing requires conscious processing/thought (.i.e. uses your prefrontal cortex intensively.) Five brain functions, understanding, deciding, recalling, memorizing and inhibiting thoughts, make up majority of conscious thought. Activities like planning, problem solving, communication, etc use these functions heavily. Hence multi-tasking on such activities is a bad idea.

Harold Pashler come up with a phenomenon called Dual-Task Interference. Via various experiments he showed that performing 2 cognitive tasks at once can reduce the cognitive capacity drastically. But if an individual performed 2 tasks, out of which only one task required conscious processing, then the cognitive capacity did not see the same drop.

There are simple activities which illustrates that one cannot normally carry out two tasks completely independently when each of them requires a choice of response.  When we try to do so, substantial delays occur in one or both tasks.  This is true even when neither task is anything that would be described as mentally challenging. Much research in this area argues that one particular mental operation is almost invariably carried out sequentially in tasks like this: the planning of responses.   The same is true of certain types of decision operations and memory retrievals.  On the other hand, the brain seems capable of perceiving stimuli while it is choosing a response, and actually producing motor responses in one task can overlap with the choice of a response in another.

Again, not all tasks requiring a choice of responses are subjected to this sort of processing bottleneck. Tasks that involve extremely “natural” mappings between stimuli and responses appear not to be.  For example, repeating words aloud as you hear them is a task most people can carry out in parallel with other tasks (McLeod & Posner, 1984).  The same is true of moving your eye to look at a spot (Pashler, Carrier & Hoffman, 1993).

Are humans capable of only uni-tasking? Not at all. If one of the tasks does not involve a choice of responses (e.g., if it merely involves repetitive rhythmic tapping, or requires perceiving and identifying stimuli without the need to decide on responses), interference is often reduced or even absent (subsequent demos on this site will illustrate this point).  Laboratory experiments in which response times are analyzed in detail have lent considerable support to the idea of a “central bottleneck” in response planning and indicated that other operations are often processed in parallel between the two tasks (for recent reviews, see H. Pashler, The Psychology of Attention, 1998, MIT Press; P. Jolicoeur, Journal of Experimental Psychology: Human perception and Performance, 1999, 25, 596-616).

Summary: Multi-tasking activities which require conscious processing is exhausting, error-prone and inefficient, hence a bad idea.

Kyle Cartmell has a year-old post entitled Five Common java.lang.Process Pitfalls that recently turned up as "new" on DZone. The post is really top flight and will set you straight if you need to fork processes from inside Java.

I know it’s a cliché but indeed I cannot believe 1 year has already gone by! My ‘A new challenge‘ post was published on Monday 16th March 2009, the day I left ThoughtWorks and joined Sourcesense as the new UK managing director.

If you are reading this it means you are still following my old blog, please head over to the new one to read the entire post, thanks! :-)

No related posts.

Related posts brought to you by Yet Another Related Posts Plugin.

In 2007 & 2008 I wrote several blog entires on Pair Programming (tagged with pair programming). Pair programming solved a lot of problems for me: knowledge transfer, mentoring, code review, etc. It also solved another problem at the same time, even though I wasn't aware of it. Pairing helps reduce the number of cooks in the kitchen.



These days I'm working on a project with some really talented people. The pace at which we deliver features is far faster than any project I worked on before I joined DRW. However, I've seen two effects of having so many talented developers on the same team: wiki coding and spork sharing. (both metaphors coined by my tech lead, badams)



Wiki coding occurs when the churn on a class or component is so great that whoever commits last ends up deciding what it should do. Wiki coding leads to inconsistent design and lack of convention. Spork sharing occurs when a fork is designed and a spoon is also needed. Instead of creating a spoon, you want to share the handle, so you create a spork instead. Now, you have no spoor or fork, you have a spork, and sporks suck. Both problems seem to stem from differing vision for the classes or components.



It appears that the more talented programmers you put on a team, the more fractured the vision for the project becomes. Of course, complexity (as well as many other factors) can also increase the fracture.



You won't catch me advocating for 'hard-working average programmers'. What I do believe is: you should stock your team with only rockstars, between 2 and 4 of them. I've worked on teams that only had 3 people. I've worked on teams with about 16. I was a consultant, I've worked on a lot of teams - big and small. My experience was that the smaller teams were much more effective, every time.



Reflecting on the past few years, I came up with the following reasons for keeping your teams small:
  • New Technology: Small teams can more easily come to a decision to try a new technology. Also, if a small team selects a new technology, the entire team is likely to learn the new technology. However, an individual on a larger team may find a way to never learn the new technology and never contribute to that area of the code. Worse, a larger team may shy away from trying new technology because they cannot come to a consensus. New technology can offer productivity boosts, and missing those boosts can hurt a teams efficiency.
  • Smaller Problems: Smaller teams generally implies solving smaller problems. Most problems can be broken down into smaller, less complex problems. Once the problem is broken down, it should be easier for the small teams to craft elegant solutions that can integrate to solve the larger business need.
  • Improved Maintainability: Smaller teams generate less code, which allows all team members to have depth and breadth concerning a solution. Having depth and breadth allows you to easily share vision and fix broken windows.
  • Ownership: Ownership isn't bad. Single points of failure are bad, but having a small team that feels ownership over an application will generally lead to higher quality and more emotional attachment to it's success.
  • Context Switching: Smaller codebases maintained by small teams solving a smaller problem will context switch less, because there's nothing else to context switch to.
  • Responsibility: The Bystander Effect applies to code (e.g. production bugs) as well.
  • Unified Vision: In a large team it's easy to have an opposing vision and never be proven wrong. In a small team it's likely that you will agree on a vision for the project (process, technology, etc) as an entire team.
  • Adding: Adding one more person to a 2 person team will likely result in a new productive team member relatively quickly. Smaller team, smaller problem, smaller codebase = easier team to join.
Sometimes I wonder if consultancies sell large teams, and then use pairing to make the large teams more effective. It's definitely my experience that large teams pairing are much more effective than large teams that aren't pairing. However, I wonder if anyone ever stopped to ask: would a smaller team have been sufficient (or, better)?



I still believe pairing is an answer to many problems. However, the best solution to making a 8 person team more effective isn't pairing. I believe that a superior solution is finding a way to solve the problem with a smaller, more effective team (or teams).
ScaleWell is having a call for applications. This opens up their second grant period. The first one ended last month with $1000 cash and some additional services given to Michael Una at Unatronics

So if you've got an idea for a startup and are looking for some feedback and a chance to win some cash and services, apply today!
I choose Programming Scala - Tackle Multicore Complexity one the Java Virtual Machine as the book to guide me learning Scala as a relative noobie. This blog is a brief review; Pro's and Con's followed by a brief summary and rating.
InfoQ has published an article I wrote about memory barriers and the JVM. Here's an excerpt:



"A trip to main memory costs hundreds of clock cycles on commodity hardware. Processors use caching to decrease the costs of memory latency by orders of magnitude. These caches re-order pending memory operations for the sake of performance. In other words, the reads and writes of a program are not necessarily performed in the order in which they are given to the processor. When data is immutable and/or confined to the scope of one thread these optimizations are harmless. Combining these optimizations with symmetric multi-processing and shared mutable state on the other hand can be a nightmare. A program can behave non-deterministically when memory operations on shared mutable state are re-ordered. It is possible for a thread to write values that become visible to another thread in ways that are inconsistent with the order in which they were written. A properly placed memory barrier prevents this problem by forcing the processor to serialize pending memory operations."



You can read the rest over at InfoQ ...
Two weeks ago I got what at first glance was yet another electronic greeting, the sort I've come to barely look at for couple of reasons: 1) like everyone else, I never seem to have enough time for everything, and 2) I guess I've become jaded - if someone wants to say hi, I'd rather get a personalized SMS or one sentence email than getting yet another irrelevant "funny" greeting lacking personality. Seconds after hitting the delete button I restored it from my trash to visit later.

I finally got around to it this evening while catching up on my email, curious as to why I had undeleted it. For one, it's simple, with lots of white space and only two, clear links: one smack in the middle and an unsubscribe link - noteworthy because unlike most unsubscribe links, it was obvious.

For another it was from Cooper, the interaction design firm. Over the holidays I'd read Alan Cooper's provocative The Insane are Running the Asylum which resonated with me. (Just ask the folks at work who must be tired of me ranting, "what do you get when you cross a phone with a computer? A computer!" A phone that takes 3 minutes to reboot is more computer than phone, no matter what it looks like.)

I then clicked the link and was pleasantly surprised, for what I found was a short, witty presentation with thoughtful design tips, paired with music composed by Philip Glass. The tips included:

  • Remember users' preferences.
  • Aesthetics matter.
  • Stop dialog-boxing your users.
  • Communicate with them.
  • Don't follow, lead.

But don't settle for my summary of it, check it out for yourself.

These tips are indicative of the ideas in his books. The Inmates are Running the Asylum lucidly illustrates various problems that arise when design is merely an afterthought. (Note: his primary focus is on interaction, not aesthetics.)

One such problem is one I alluded to earlier, about the convergence of various electronics with computers. When everyone else's focus is on technology and features rather than on user interaction, Apple handily beats them at their own game time and again. By the by, I contend that this is not because Apple is doing interaction design well as it is because everyone else isn't doing any.

The Insane are Running the Asylum also contained an intriguing discussion of confirmation dialog boxes. Alan points out that confirmation dialog boxes were a misguided "solution" to a user losing their data. By adding a dialog box, such a loss was no longer due to poor design, instead it became the user's fault. Why these miserable dialog boxes persist in the days of unlimited undo and Recycle bin recovery is beyond me.

About Face (which I am still reading) focuses on the how instead of the why of interaction design. It's an interaction design tome. (I want to point out that it includes an excellent primer on business analysis, covering persona and scenario composition.) It distinguishes between implementation, mental and represented models. Simply, the implementation model is the set of classes that encodes the business domain, the mental model is the user's picture of the domain and the represented model is the way the implementation model is presented to the user.

This is in stark contrast to Domain Driven Design's "One Team, One Language" mantra. By insisting that the implementation must match up with the mental model, it can make our job of building software even more difficult than inherently is. Or we do the reverse, forcing the implementation model on our user, who thank you very much, already understands her business and will vehemently resent being told what her business really entails.

By introducing a represented model, we acknowledge that a mental and an implementation model are not equivalent. The represented model, the result of interaction design, can map from one to the other, facilitating usage and implementation.

If software could make resolutions, it might resolve to be considerate. Interaction design is part of what will get us there.

Update (3/8/10): Updated code to work with version 0.1.30 of node.js

I’ve been thinking about high availability websites lately. In particular, I want sites that can be upgraded (including database migrations or even infrastructure changes) without downtime.

I’ve also been playing with node.js lately, and I decided to spike out a web proxy that would sit between users and the actual website (eg, a rails app). When performing upgrades, the proxy would hold users connections and wait. Once the upgrade was done, the proxy would forward requests as usual. Users would see an extra long request, but as long as the upgrade was short (eg, less than a minute), the user should not know the site was down.

This type of proxy server seems like a good fit with node. Node’s event model means that there will be very little overhead when holding connections. There are no threads stacking up and waiting. Since everything is non-blocking, this server should scale well.

Here is a very simple version of the code:


var fs = require('fs'),
   sys = require('sys'),
  http = require('http');

http.createServer(function (req, res) {
  checkBalanceFile(req, res);
}).listen(8000);

function checkBalanceFile(req, res) {
  fs.stat("balance", function(err) {
    if (err) {
      setTimeout(function() {checkBalanceFile(req, res)}, 1000);
    } else {
      passThroughOriginalRequest(req, res);
    }
  });
}

function passThroughOriginalRequest(req, res) {
  var request = http.createClient(2000, "localhost").request("GET", req.url, {});
  request.addListener("response", function (response) {
    res.writeHeader(response.statusCode, response.headers);
    response.addListener("data", function (chunk) {
      res.write(chunk);
    });
    response.addListener("end", function () {
      res.close();
    });
  });
  request.close();
}

sys.puts('Server running at http://127.0.0.1:8000/');

Here is a gist if anyone would like to fork.

Basically, I use http.createServer to create a web server on port 8000. On incoming requests, I call checkBalanceFile. This method will try to stat a local file called balance. If it finds it, it will call passThroughOriginalRequest, which forwards the request to another web server on port 2000. If the balance file does not exist, I use setTimeout to call checkBalanceFile again in one second.

With a proxy server like this, the main application can be upgraded by removing the balance file. While the file is missing, the node web server will hold all of the connections and check every second for the reappearance of the balance file. Once it comes back, all requests will be forwarded along and then streamed back to the user.

Currently, this spike only works with GET requests and does not pass any headers through, since I wanted to keep the code simple.

Taking my family out for lunch today, I noticed something interesting. While waiting to sit down, my 2.5 yr old nephew asked for my sisters iPhone. He grabbed it, unlocked it and proceeded to navigate to the SpongeBob Square Pants game that she had on there. Sitting there quietly, he played until we had to move.

Now, tell me what other full blown computing device you could put in front of a young kid and have him use. Think about what it takes to even launch a game on Windows or Mac OS X.

What I just described is exactly what people are missing from the iPad announcements. The iPad is not aimed at 'us' as in techies, developers and people generally comfortable ( to some extent ) with computers as they are. It's aimed at people who would otherwise not be using computers. Such as children and the elderly. People who either a ) missed out on the 'computer' generation or b ) haven't been exposed to the current file / folder / desktop metaphor of computers.

Frankly, it's the 'Wii' of computers. Just like the Wii found a largely untapped market of people who would never buy a video game system, the iPad will become the computer for generations ( young and old ) and demographics ( soccer moms, travelers, etc.. ) that normally wouldn't buy one. The computer that is useful enough to carry with them, while at the same time being fun and easy to use. No drivers. No disks. No hassle. No confusion.

Just functionality & simplicity.
When I taught source control and continuous integration in 2007 (for the GS04 course at UCL) I used Subversion for the source control lab and build-o-matic for the continuous integration lab.



In the labs this year, I'll be using Mercurial instead of Subversion, and Hudson instead of build-o-matic.



What would you choose for teaching source control and continuous integration (and for bonus marks, why)?



Copyright © 2009 Ivan Moore
As one would expect, PowerShell is very capable of launching processes. Sometimes, it is necessary to launch a process that doesn't block (such as a user-interface based application) and wait for it to close.



Here is a little snippet of code to do this:



$p = [diagnostics.process]::start("something.exe", "--arg1 --arg2")

$p.WaitForExit()



One limitation is that the "Working Directory" of the spawned process is set to the user's home directory by default, which is often unacceptable. Here is another little snippet that explicitly sets the working directory to the current directory before spawning the process:



$psi = New-Object  System.Diagnostics.ProcessStartInfo("something.exe", "--arg1 --arg2")

$psi.WorkingDirectory = (Get-Location).Path

$p = [Diagnostics.Process]::Start($psi)

$p.WaitForExit()



This took me just enough time to figure out on my own where I thought it warranted a blog posting. Happy scripting...
Internet Explorer 7 (IE7) appears to have a bug (limit) that ignores more than 31 <style> tags. I wrote it up here since searching for it myself didn't uncover this.



I encountered this in a programatic use of Yahoo's User Interface Library (YUI), where it just so happened that I was outputting more than 30 button instances. Each button was outputting a small style snippet to set a background image as per their example. As a work-around, I'll need to come up with a way to collect all of the styles and then output a single <style> tag.



Here is a snippet that demonstrates this bug if this post is opened in IE, or you can place the HTML in a file and load it up separately. I'll post it on Microsoft's forum and update this if I find anything new.



If any span is not green, the style tag was ignored.



#e1 { color: green; }

Span 1



#e2 { color: green; }

Span 2



#e3 { color: green; }

Span 3



#e4 { color: green; }

Span 4



#e5 { color: green; }

Span 5



#e6 { color: green; }

Span 6



#e7 { color: green; }

Span 7



#e8 { color: green; }

Span 8



#e9 { color: green; }

Span 9



#e10 { color: green; }

Span 10



#e11 { color: green; }

Span 11



#e12 { color: green; }

Span 12



#e13 { color: green; }

Span 13



#e14 { color: green; }

Span 14



#e15 { color: green; }

Span 15



#e16 { color: green; }

Span 16



#e17 { color: green; }

Span 17



#e18 { color: green; }

Span 18



#e19 { color: green; }

Span 19



#e20 { color: green; }

Span 20



#e21 { color: green; }

Span 21



#e22 { color: green; }

Span 22



#e23 { color: green; }

Span 23



#e24 { color: green; }

Span 24



#e25 { color: green; }

Span 25



#e26 { color: green; }

Span 26



#e27 { color: green; }

Span 27



#e28 { color: green; }

Span 28



#e29 { color: green; }

Span 29



#e30 { color: green; }

Span 30



#e31 { color: green; }

Span 31



#e32 { color: green; }

Span 32



#e33 { color: green; }

Span 33



#e34 { color: green; }

Span 34



#e35 { color: green; }

Span 35



In a constant battle for sweet tests (readable & maintainable) I developed another weapon. Have a look at this tool for acceptance testing: Sweetest. What do you think?
Build failed today: ERROR: Failed to update http://svn.dev.sabre.com/svn/apd_centiva2/trunk org.tmatesoft.svn.core.SVNException: svn: blah blah blah ‘Bummer, I need to log in to the ci box and figure out what’s wrong with svn.’ – I thought. Being in the middle of something I didn’t get to it immediately. Then I got another notification from Hudson: Updated failed due to local files. Getting [...]
Not sure I like the punchline but the story is real. Once upon a time there was a project, pretty bad one actually. The were big performance and stability issues. The were no docs about functionality whatsoever. The code base quality was disastrous. There was even a local framework implemented that dealt with mapping java classes [...]
One of my colleagues told me the other day: “Szczepan, last year, when I started working in the X team someone warned me not to speak too loud about unit testing” Apparently, there were feisty TDDers in the X team and they witch-hunted devs who not necessarily had written test-first. I guess it’s easy to become a [...]

James Shore writes about Large-scale Agile. Half a decade ago I was at ThoughtWorks and heard tale of massive agile undertakings in the UK by TW under the aegis, "distributed agile". I never experienced it first hand (but I can read about one such project) and I'd love to hear from any other TWers or alums who worked firsthand on these.

(Thanks to Rod Coffin for pointing out Shore's post to me.)

ThoughtWorks announces Twist 2.0 availability from 31st March 2010:

http://www.prnewswire.com/news-releases/thoughtworks-studios-new-twist-20-provides-collaborative-agile-test-management-85809582.html



Tyto Software has been collaborating with ThoughtWorks Studios to integrate Sahi with Twist and results will be visible in Twist 2.0.



"Twist 2.0 has added Sahi as an additional option for web testing. The main benefit of Sahi is that it abstracts out most difficulties that testers face while automating web applications. Its features include an excellent recorder, platform and browser independence, no XPaths, no waits and multi-threaded playback. In addition, it allows you to identify UI components within the application as you record test scenarios." Announcing Twist 2.0: Available for download on March 31

Update (3/2/10): Updated code to work with version 0.1.30 of node.js

I’ve continued to play with node.js, and I’ve decided to do a follow up spike to my previous one: Web proxy in node.js for high availability

The previous spike used node to proxy requests directly to a web server. This spike uses node to put messages into a (redis) queue. Ruby background workers read from the queue, process the requests, and respond on a different queue. When node receives the response from the background worker, it sends the response back to the waiting user.

Just like my first spike, this type of architecture can be used for high availability web sites. Since all messages go into a queue and node holds the connections from the users, the site can be upgraded (including database migrations or infrastructure changes) as long as node and redis stay the same. Once the upgrade is finished, the workers can resume working from the queue. Users would see an extra long request, but as long as the upgrade was short (eg, less than a minute), the user should not know the site was down.

A queue has a lot of advantages over a straight proxy:
  1. Easy to scale up and down by adding or removing workers
  2. Can use priority queues to prioritize more important web requests
  3. Easy to monitor (eg, how many messages are in the queue, how fast are they being added)

Here is a very simple version of the code. First, the node webserver (using redis-node-client):


var sys = require('sys'),
   http = require('http'),
  redis = require("./redisclient");

var queuedRes = {}
var counter = 1;

http.createServer(function (req, res) {
  pushOnQueue(req, res);
}).listen(8000);

function pushOnQueue(req, res) {
  requestNumber = counter++;

  message = JSON.stringify({
    "class": "RequestProcessor",
    "args": [ {"node_id": requestNumber, "url": req.url} ]
  });

  client.rpush('resque:queue:requests', message);
  queuedRes[requestNumber] = res
}

var client = new redis.Client();
client.connect(function() {
  popFromQueue();
});

function popFromQueue() {
  client.lpop('responses', handleResponse);
}

function handleResponse(err, result) {
  if (result == null) {
    setTimeout(function() { popFromQueue(); }, 100);
  } else {
    json = JSON.parse(result);
    requestNumber = json.node_id;
    body = unescape(json.body);
    res = queuedRes[requestNumber];
    res.writeHeader(200, {'Content-Type': 'text/plain'});
    res.write(body);
    res.close();
    delete queuedRes[requestNumber];
    popFromQueue();
  }
}

sys.puts('Server running at http://127.0.0.1:8000/');

Also available as a gist.

pushOnQueue() is called on incoming web requests. This creates a JSON message and pushes it on the resque:queue:requests queue. It also puts the res object into a hash so it can be retrieved again on the way back.

At the same time, a queue listener is set up using redis.Client(). On connect, popFromQueue() is called. This method pops messages from the responses queue and calls handleResponse(). If the pop did not find a message, it is scheduled to call again in 100 milliseconds. If it did find a message, the message is parsed with JSON, the requestNumber is pulled out, and the original res object is pulled out of the queuedRes hash. The res object is then sent the body of the message from the queue, which makes it back to the user.

On the other side, I have a ruby worker using resque:


class RequestProcessor
  @queue = :requests

  APP = Rack::Builder.new do
    use Rails::Rack::Static
    use Rack::CommonLogger
    run ActionController::Dispatcher.new
  end

  RACK_BASE_REQUEST = {
    "PATH_INFO" => "/things",
    "QUERY_STRING" => "",
    "REQUEST_METHOD" => "GET",
    "SERVER_NAME" => "localhost",
    "SERVER_PORT" => "3000",
    "rack.errors" => STDERR,
    "rack.input" => StringIO.new(""),
    "rack.multiprocess" => true,
    "rack.multithread" => false,
    "rack.run_once" => false,
    "rack.url_scheme" => "http",
    "rack.version" => [1, 0],
  }

  def self.perform(hash)
    url = hash.delete("url")

    request = RACK_BASE_REQUEST.clone
    request["PATH_INFO"] = url
    response = APP.call(request)

    body = "" 
    response.last.each { |part| body << part }

    hash["body"] = URI.escape(body)
    cmd = "redis-cli rpush responses #{hash.to_json.inspect}" 
    system cmd
  end
end

Also available as a gist.

The worker can be started with:


env QUEUE=requests INTERVAL=1 rake environment resque:work

This worker uses resque, which polls the queue and calls perform when a message is received. The perform method builds the Rack request and runs the URL from the message through Rails. It then pushes the response body onto the responses queue using redis-cli.

As before, this spike only works with GET requests and does not pass any headers through to keep the code simple. Comments and forks are welcome.

A long time ago Joe Walnes ran a session at the Extreme Tuesday Club where he encouraged us all to draw maps of our personal practices. As he put it:

We want your personal practices that you find important. Different people work in different ways, so we thought it would be interesting to discuss this.



In your own time, make a list of your 10 most important practices for coding and design. These do not have to be XP related and should be the most important things in your mind. For example: Separate interfaces from implementation, mock objects, follow the Law of Demeter, test driven development. Controversy encouraged - everyone's different.

Try to determine any relationships that may exist between these. Specifically, which practices support other practices. For example: unit testing supports refactoring and test driven design.

Draw a map of the relationships - like this: http://joe.truemesh.com/sample-structure.gif





Sadly the old XTC wiki has gone to that great stand-up in the sky but I was able to use the Wayback Machine's copy to rescue some people's maps.

Despite my honest intention to travel less this year, I still have a particularly long list of conferences and events that I'm attending, sponsoring or otherwise involved with. Will keep this blog entry as up to date as possible as changes occur.

SpeakerConf in Aruba (February 9-11)

Had an awesome time hanging with folks way smarter than me, learned a lot, drank way too much and came back with a tan. Please don't hate me.

Hashrocket Chicago Grand Opening Party (March 5)

Meet a bunch of Hashrocket folks and a good chunk of the local Ruby community for a cocktail party to celebrate the opening of our Chicago branch office. Details and RSVP

NoSQL Live in Boston (March 11)

In support of our growing reputation in MongoDB circles, we've decided to sponsor this promising event and are sending a couple of Rocketeers to present: Les Hill creator of MongoDoc and Durran Jordan creator of Mongoid. The conference is sold out, but you should be able to catch a live simulcast.

SXSW Interactive in Austin (March 11-16)

I've been attending SXSW for the last couple years and always learn a ton and enjoy the great networking opportunities. This year I'm excited to participate in the program as a panelist on the What Guys are Doing to Get More Girls Into Tech panel.

Together with our design team, I'll also be premiering our the results of our rebranding effort and the relaunch of hashrocket.com. Special limited-edition prints to honor the occasion will be available to select friends of Hashrocket in attendance at SXSW.

RubyConf India in Bangalore (March 17-21)

I'll finally put my Indian visa back to work when I travel back to Bangalore to speak at the inaugural RubyConf India, which we are sponsoring as Hashrocket. If you've been following my blog for awhile or know me personally, you know that in 2006 I lived in Bangalore for three months as a ThoughtWorks University trainer and loved it! I have a special fondness for my friends and associates in India, so this trip is particularly near and dear to my heart. I can't wait to reconnect with everyone and make new friends.

I still haven't decided what my talk will be, but I'm leaning towards an updated version of The Hashrocket Way. Let me know what you think about that via twitter.

Pune Visit (March 22-24)

Before leaving the subcontinent, I'm hoping to visit old friends at the ThoughtWorks India office in Pune, as well as meeting with other folks from the thriving Ruby on Rails scene in that city.

Scottish Ruby Conf (March 25-28)

On my way back from India, I'm spending a few days in Scotland for what's quickly becoming a yearly Hashrocket tradition. Jon Larkowski, Robert Pitts and Jim "Big Tiger" Remsik are representing us on the speaker list.

April & May

Recuperating from insane March travel schedule. Then likely that I'll spend the last three weeks of May working in Boston (but the details of that trip are secret for now).

Hashrocket University in Baltimore (June 6)

Your very exclusive opportunity to study the tools and processes behind Hashrocket's success, hands-on and directly from actual Rocketeers, pairing on our equipment. Presented in partnership with the excellent folks at JumpstartLab. Plus, you're going to be in Baltimore for RailsConf 2010 already!

Ignite RailsConf in Baltimore (June 6)

Ignite events are lightning talks, where 16 speakers each get 5 minutes to talk about a subject they are passionate about, but with a twist: the speaker's slides are automatically advanced every 15 seconds. At Hashrocket, we think Ignite events are fucking awesome. That's why we're sponsoring this one, which promises to be an awesome pre-party kickoff for...

RailsConf 2010 in Baltimore (June 7-10)

I'll be part of a contingent of at least 10-15 people from Hashrocket, many of us speaking (hopefully). I've proposed several talks including a great new experience report called "Million Dollar Mongo" about our work on a large and successful production deployment of a MongoDB/Mongoid/Rails app.

July

Planning to spend most of middle and late July working out of our Chile office.

BizConf 2010  in Amelia Island (August 4-6)

My own conference promises to be one of the greatest learning events of 2010 for people that run software operations. Registration is now open and seats will go fast due to limited capacity. Seriously, what are you waiting for? (Okay, maybe you're waiting for me to post the program - I promise to do it soon.)

Burning Man in Black Rock City (September 1-5)

Oh man, I can't wait for this. Been trying to go for at least 5 years and I lost count. I think I'll be able to go this year, in fact have promised special friends that I will do so.

GoGaRuCo 2010 in San Francisco (September 10-11)

Probably moderating a panel discussion. More details as they become available.

AYE Conference in Phoenix (November 7-11)

Haven't bought tickets yet, but learned so much at last year's event and enjoyed it so much that I doubt I'll be able to resist this year. A conference of legendary reputation, which you should really check out and consider. If I could only attend one learning event this year, it would probably be this one.

Rails Summit 2010 in Sao Paolo (October ?)

More details as they become available.

Conferencia Rails 2010 in Madrid (November ?)

More details as they become available.

YOW! 2010 in Melbourne (December 2-3) and Brisbane (December 6-7)

Presenting on Rails 3. More details as they become available.

After this post about the current state of WS-* specs, I thought it would be funny to go back and look at the second blog post I ever wrote:

WS-* Specs De-*'ed

I got about 10% into the main SOAP spec and gave up. What a load of crap those things were / are.
It used to be so simple – just code invocation via the web. So I write this post as I recently had a wonder through the WS-* specifications to see if anything was actually of some use.
This blog documents my initial experiences wading through the reference architecture and related explanations of SOA. My intention is briefly summarize SOA, condense important terms used in the architecture and offers reasons why the architecture can be of some value.

Started in 1996, Artemis is a nationally recognized outreach program to encourage girls from local public schools to pursue careers in Computer Science, and more broadly in science and engineering.

From their website description:

The Artemis Project is a free, five-week summer day camp for rising 9th grade girls in the Providence area who are interested in learning about science and technology. Traditionally, it has been run by four undergraduate women from Brown University in connection with Brown's Computer Science Department. This year, Artemis is pleased to announce that we will additionally have a coordinator from Boston University.

By teaching students computer skills, programming, and computer science concepts through engaging activities, the Artemis Project encourages young women to join the field of computer science. According to my friends in DevChix, early experience in computer programming is essential to stemming attrition rates among women in CS programs at the university level.

So here's a great opportunity to help sustain a program that has been getting girls excited about CS for 15 years. Artemis needs to raise $25,000 to keep the program going this year. My company, Hashrocket, will be making a sizable donation. If you or your company also is able to donate, you can do one of the following things...



1. Send a check made out to "Department of Computer Science, Brown University, Artemis Program" to:



Amy Tarbox

Department of Computer Science, Brown University

Box 1910, 115 Waterman St.

Providence, RI 02912




2. Donate online by going to https://gifts.development.brown.edu/Brown/ChooseGifts.aspx and under the "Other Current-Use Priorities" section, fill in "Artemis Program"



For more information on potential sponsorship arrangements, contact Amy Tarbox: abt@cs.brown.edu

Martin Fowler writes about blue-green deployment, a technique I will try out for my next production project. With posts like these, Fowler shows why ThoughtWorks continues to turn out brilliant agilists.

At the Agile India 2010 conference, there was a lot of interest for agile coaching in India.

Today, in India, I believe we have many Agile coaches (internal and external, more internal coaches). If you are helping bring Agile/Lean/Light-Weight thinking into your company, you are playing the Agile coach role (you like it or not). You could be in the leadership role doing this or you could have taken the ownership and facilitating/influencing your team. While doing so, we all need a lot of help, advice and reassurance of our strategies. To facilitate this, help people network and to push the boundaries of Agile, in 2008, Deb and I created the first Agile Coach Camp in US.

In the past I’ve considered doing something similar in India, but always felt we’ve not reached the point yet. Now (esp. after the agile india 2010 conference), I feel we might be at this point.

So if you are interested in participating in a 2 day invitation only, all open-space based conference, over a weekend in March/April, inform me by filling out the following form:

Loading…

Also please vote for which city you would like to have the conference in:

online surveys

And what dates work best for you?

customer survey

I've become more and more interested in lean software development over the past 5 years. Seeing it as the next logical step to typical agile development processes, I've started to refine my approach to software development. If you consider agile to be the 'how' of developing software, lean could almost be considered the 'why' of development.

Unfortunately, one can't get far into reading about lean before you recognize a key property of its application: large teams. Most of the work in lean is centered on multiple multi-person teams trying to work in unison to build and release a product. Something that doesn't really apply to startups, especially bootstrapped ones. Knowing how productive lean can make a team, I'm keen on applying it to 1530.

So, as I've spent the last 1.5 years building 1530, I've tried to apply lean principles not only to some client work that we've been doing, but also to the construction of our own products. As the months progress, I've started to come up with small optimizations or best practices for applying lean to a small companies and teams. I'm calling this "Small Team Lean". I'll be posting these small tidbits on this blog. I would welcome some feedback and/or criticism.
37: Intimacy doesn't scale
Steve Freeman and I are teaching a course at UCL called "Tools and Environments".

The course we wish we’d had in college, only we didn’t know it at the time.



We cover subjects such as source control systems, automated builds, automated testing and continuous integration.



In preparing for the course, I've been reminded of how few books there are which we can use as a "course text". There are plenty of books for specific tools (e.g. Ant) once you know that you need those tools, but few books which explain the sorts of things that you need for real software development projects, and why you need them.



The book we're using for our "course text" is Practical Development Environments (and we'll also be recommending Continuous Integration as that also covers much of the material of the course).



If you have other recommendations please add a comment!



Copyright © 2009 Ivan Moore

I have just published SystemTimer 1.2 release on Gemcutter. This new version provides support for custom timeout exceptions, will let you specify sub-second timeouts and plays nicer with Ruby interpreters compiled with -disable-pthreads.

Install SystemTimer latest version with:

sudo gem install SystemTimer

Support for Custom Timeout Exceptions

This version adds support for custom timeout exceptions. This is useful when you want to avoid interference with other libraries already using/catching Timeout::Error (e.g. Net::HTTP)

require 'system_timer'

begin
  SystemTimer.timeout_after(5, MyCustomTimeoutException) do
    # Something that should be interrupted if it 
    # takes too much time...  even if blocked on 
    # a system call!
  end
rescue MyCustomTimeoutException => e
  # Recovering strategy
end

This patch was kindly contributed by runix

Sub-second Timeouts

SystemTimer is going through too many layers to be able to reliably guarantee a sub-second timeout on all platforms, so – in the original SystemTimer implementation – the timeout had to be expressed as a number of seconds.

You can now specify timeouts as a fraction of a second and SystemTimer will do its best to reduce the timeout accordingly. e.g.

SystemTimer.timeout_after(0.5) do 
  # timeout after 500ms
end

Note that for stability reasons SystemTimer will not allow you to go below 200ms, e.g.

SystemTimer.timeout_after(0.01) do 
  # timeout at best after (uncompressable) 200ms 
  # even if 10ms is requested
end

This feature is based on an idea and original contribution by Dmytro Shteflyuk (of Scribd fame).

Better Compatibility with -disable-pthreads

Changed SystemTimer implementation from using Mutex to Monitor. Mutex causes thread join errors when Ruby is compiled with -disable-pthreads.

Thanks again to Dmytro Shteflyuk who contributed this patch.

Nearly ten years ago, I wrote an article exploring how to find a method on a Java class using reflection, given the class's name, the method name, and an array of arguments, whose parameter types would be most compatible with the runtime types of the actual arguments. This might be handy for, say, simple scripting languages sitting atop Java.

I sure wish someone would have told me about java.beans.Expression and java.beans.Statement when JDK 1.4 came out (2002?). Looks like it handles the exact kind of method/constructor lookup I wrote about. Plus, its ambiguity resolution is almost certainly more JLS-accurate.

The Expression/Statement facility doesn't seem to support primitive widening conversions:

import java.beans.Expression;

import org.junit.Test;
import static org.junit.Assert.*;

public class BeansExpressionTest {
    public static class Foo {
        public String bar(int i) {
            return "int";
        }

        public String bar(byte b) {
            return "byte";
        }
    }

    @Test
    public void shouldWidenPrimitives() throws Exception {
        Expression expr = new Expression(new Foo(), "bar",
            new Object[] { Short.valueOf("3") });

        assertEquals("int", expr.getValue());
    }
}

shouldWidenPrimitives() raises NoSuchMethodException. Oversight on Sun's part? Misunderstanding on my part regarding how such a call should be resolved? If I already have a handle on Foo#bar(int), the reflective call would widen a Short argument.

I’ve kicked off another open-source project, WiPFlash.

This is a little automation framework with a number of goals:

  • To let me learn how to do .NET UI Automation
  • To fix a couple of things that White doesn’t do yet
  • To automate scenarios as fast as possible
  • To provide examples that anyone else can look at, if you want to do the same thing.

The project is written in C#, and is exclusively focused on WPF Windows GUIs. Currently WiPFlash can:

  • Launch or reuse an existing application or window
  • Enter text in TextBox, RichTextBox, and editable ComboBox
  • Select values and retrieve selection in ListBox or ComboBox
  • Retrieve values from RichTextBox (and its children), TextBox, TextBlock, editable ComboBox
  • Click buttons.

It also provides an example of a Prism application, complete with MVVM paradigm, command binding, dependency injection using Unity, etc.

Please feel free to try it out and add any requests and/or issues, bearing in mind that the purpose of the framework is not to replace White. For instance, I have no plans at this time to support drag-and-drop or mouse and keyboard input, nor am I going to respond to bugs with WiPFlash not working on WinForms, SWT, etc.

If you’re looking for something similar for Java and Swing, check out my other automation framework, Tyburn.

36: A fine and private place
Here is a brief video which shows how Sahi can be used to automate ZK based applications. Notice how Sahi uses neither XPaths nor explicit waits, and works with the same script on both Firefox and IE.



As part of my efforts to create more concise Unit Tests in Java, Steve McLarnon and I recently added the ability to create a stub and stub one method with only one line.



The implementation relies entirely on Mockito, so my example assumes you were already using Mockito to create the stub.



The Mockito documentation has the following example for stubbing:
LinkedList mockedList = mock(LinkedList.class);

when(mockedList.get(0)).thenReturn("first");
Using the code Steve and I put together you can simplify this to the following single line.
LinkedList mockedList = create(aStub(LinkedList.class).returning("first").from().get(0));


The implementation is simple, but does rely on static state. There are ways to improve the implementation; however, this works for us. If you have more specific needs, feel free to change it to suit you.



The implementation follows:
public class MockitoExtensions {

public static T create(Object methodCall) {

when(methodCall).thenReturn(StubBuilder.current.returnValue);

return (T) StubBuilder.current.mockInstance;

}



public static StubBuilder aStub(Class klass) {

return new StubBuilder(mock(klass));

}



public static class StubBuilder {

public static StubBuilder current;

public final T mockInstance;

private Object returnValue;



public StubBuilder(T mockInstance) {

current = this;

this.mockInstance = mockInstance;

}



public T from() {

return mockInstance;

}



public StubBuilder returning(Object returnValue) {

this.returnValue = returnValue;

return this;

}

}

}
Disclaimer: ThoughtWorks embraces the individuality of the people in the organization and hence the opinions expressed in the blogs may contradict each other and also may not represent the opinions of ThoughtWorks.