I am not a Pr0n Star: avoiding unavoidable associations

I just read Matt Amionetti’s thoughtfully worded response to the reaction he’s got from his presentation, “CouchDB: Perform like a Pr0n star”.

Indeed, reading the response, it seems almost inconceivable that anyone could possibly be offended by his presentation. Matt warned people beforehand that there would be potentially offensive images, I believe in his stated intentions, and I heed his call that we should be contributing something useful to the discussion.

So, I’d like to give you, the reader, a little bit of insight into the human brain, how it makes connections and comparisons, and help you to understand your power over other people and their perceptions.

I’d like to start by telling you another story.

The Tale of the T-Shirt

On one dress-down Friday, a colleague came in wearing a beach T-shirt, featuring a topless woman coming out of the surf. It was just a black and white image, and the focus was on the scene as a whole, but nonetheless some of us felt that it was inappropriate. So I asked him not to wear it again.

“Why?” our colleague said. “I didn’t think it would offend anyone.”

“It’s not really that it’s offensive,” I said, “but think about this. I’m pair-programming with you, sitting next to you at a table. Someone else comes along to talk to both of us. They see your T-shirt, with that image, and then they scan across from that image to me. Can you see the comparison they’re making in their mind? Even subconsciously? That’s why I would prefer you not to wear that T-shirt – so that people don’t think about topless women while they’re talking to me, and while I’m trying to work. At worst, the comparison is offensive. At best, the t-shirt is distracting.”

Our colleague took the feedback very well, and agreed not to wear the t-shirt again.

How the brain makes associations

The human brain consists of a bunch of neurons, between which connections and pathways are built. Those pathways form associations. There are associations of which we’re conscious, associations of which we’re not conscious, and a blurred space in between.

Here’s a conscious association. If I want to remind myself to pick up my dry-cleaning after work, I can hide my handbag. Sound strange? Well, as soon as I go to pick up my handbag, and it’s not where I left it, I’ll remember why I hid it. I’ve built myself a conscious association between the absence of the handbag, and the task I had to remember.

For a subconscious association, watch yourself thinking of all the things you remember about Germany, when I say the word “Germany”, or “Elephant”. The vast majority of our associations are not in, and often not available to, our conscious mind. They add to our personality, drive the learning we get from our experiences, and there are simply too many of them for us to be aware of them all.

For an example of the blurred space between, I offer my fiancé’s habit of driving directly home from the station, even though we agreed we’d stop at the Chinese takeaway on the way home. He associates the act of driving down a particular road with a particular route, and consciously manipulates the car to follow his subconscious association.

So what does this have to do with pr0n stars?

Human beings learn associations by – amongst other things – proximity; either in time, or in place. That is; they will build associations more easily if two or more things are experienced close together.

If you’ve watched Matt’s slideshow, and you find yourself using CouchDB on a project in the future, will you be thinking of his slideshow? It was very memorable. I think I will find it hard in the future to disassociate that slideshow from the featured product. That’s a conscious association I’ve built. I’m aware of it.

There’s a subconscious association going on in that show, too; another proximity which is harder to spot. We’ve just experienced words of technology – key phrases like scalability, REST, public interfaces – with images of women whom we’re told are available for visual sexual gratification. There are a few men in some of the images; they appear to me to be in positions of power and influence. The images of women, on the other hand, tend to be submissive. So we’re learning, subconsciously, that women associated with technology are also associated with sexual gratification and submissiveness. (The only strong women in the slideshow are associated with conflict, which we try to avoid.)

If you doubt this is true, look through the presentation (and bear in mind that it might be considered Not Safe For Work). At some point, Matt introduces a picture of a typical development team. To which team member are your eyes drawn, and why?

At the very least, we start making comparisons. No wonder she doesn’t look happy.

The power of people with influence

Earlier this year, I finished reading Robert Cialdini’s “Influence”. It’s a very readable, memorable book. It explains some of the ways in which associations are made. In particular, he describes these mechanisms for influencing other people (his titles, my poor definitions):
 

  • Social proof – if other people do it, we should do it too
  • Authority – if someone in a leadership position tells us to do it, we should do it

Examples which Cialdini uses to demonstrate these concepts include the mass suicide at Jonestown, and the Milgram experiment.

So, if a community is building associations, or you’re recognised as or portraying yourself as an authority telling people to build associations, those associations will be stronger than normal. People will be more likely to act on those associations. In the same way that my fiancé takes the turning for home, “routes” will be set which the brain naturally follows, and acts upon. And it will seem perfectly reasonable, or justifiable, to do so – at the time.

So what can you do now?

If you were sitting in Matt’s presentation, or have experienced similar presentations or associations in the past:

  • you might consciously choose to wear a topless women on your t-shirt, because your brain subconsciously confirms that it’s acceptable.
  • You might expect women to be more submissive; to accept delegated tasks more easily, or question process less, or accept lower pay.
  • You might find it uncomfortable to have a female manager or team lead.
  • You might cause the women around you start dressing in less feminine ways, to distance themselves from any association.
  • You might erroneously think you have a chance of scoring with your female colleague (notwithstanding cases of genuine mutual attraction).
  • You might not expect the woman on your team to be able to teach you anything new.

And, if you’re Matt, or one of the many commenters whose opinions I’ve read, you might not completely understand the backlash. Hopefully this post helps.

If you’re not suffering these or similar biases, trust my experience that others are, or have done, and start thinking about how you might have been influenced. The associations aren’t helpful for me, and I doubt they’re helpful for the people who have them. Recognising the influence of others will help you to consciously choose different paths.

Hopefully if you’ve found the presentation through this blog, you’ve now read through this post and are now better guarded against these associations. (That’s why I didn’t put the link at the top).

You can also strengthen more useful associations. Go find the women in your team and talk to them about their technical abilities; the things that brought them to IT; times when they’ve felt empowered and assertive. Find strong female role-models – I recommend Esther Derby, Desi McAdam, Sarah Taraporewalla, Johanna Rothman, Cyndi Mitchell, Rachel Davies, Angela Martin, and many others too numerous to list here. If you’re looking for something more entertaining to get into your subconscious, try Ellen Ripley, Buffy Summers, Alan Moore’s “Promethea” or Manda Scott’s “Boudica” series.

And, if you’re thinking of presenting something similar in the future, be aware of the power that you have.

On engendering subconscious reactions

Matt entitled his response, “On Engendering Strong Reactions“. I’m worried about the subconscious reactions; about the effect that it has on the people who see that presentation and the way in which they react to me, and to my other female colleagues, afterwards. Matt said, “I would have hoped that people who were likely to be offended would have simply chosen not to attend my talk or read my slides on the internet”.  That doesn’t stop the associations being built, and I can’t necessarily avoid working with people who have built those associations.

So I’m not offended by the presentation – I can understand why some women might be – but I am concerned by it. Hopefully this provides some positive insight into why. Matt – I hope you find it useful and enlightening; please let me know.

Posted in breaking models, feedback | 54 Comments

Why you should write tests last

Prompted by Szczepan’s post.

I have written tests after code when

  • the code is already there, but I / others don’t know what it does or how to use it, and we need to
  • I wrote a spike which turned out to be pretty good code, and I wanted to describe what it does and how to use it
  • I realised I needed to add some simple yet important behaviour while making a different test pass, and forgetting to add the code would possibly introduce serious bugs, so I added it as I went along and now I’m going back to show what it does and how to use it
  • I was learning how to write the tests first, and wanted to know what they would look like.
Posted in bdd | Leave a comment

Goodbye, ThoughtWorks – Hello, Worlds

Today is my last day with ThoughtWorks.

It feels strange to be leaving a job I love with the most amazing company in the world, at a time when I should rightly be thankful for having a job in the first place. So, let me explain why I’m going.

Remember this post, back in November? I decided to actually do some work on the novel which has been hanging around my head for some years. Remember all the follow-up posts in which I told you how I was getting on?

No, neither do I.

The truth is that my day-to-day work – coaching, development, and learning about how brilliant, technical people think – has been taking up huge amounts of my life, time and creativity. I have no regrets about the energy I’ve put into it; watching teams and individuals learn and grow, knowing that I’ve been part of that, gives me pride and hope for the world. Learning how to help them better, and having them teach me, is fun and uplifting. It’s also incredibly draining on my creative energy. Looking back, I’ve hardly written any haiku in the last six months, and I’ve had no poetry published in two years. Nor have I made much progress with the novel.

So I’m going to leave ThoughtWorks and strike out part-time as an independent consultant. (I’m ideally looking for about three days a week leading or helping with Agile transformations, and will be flexible.)

The rest of my time will be going into ongoing training and development – giving my brain the space it needs to learn properly, to create the workshops and training courses which will be most effective – and, of course, writing my book. Maybe more than one of them.

So, from one world to others. I’ll be spending the next month or so in the diverse company of Grey the cat, Susan, Susan’s chair-dragon, Pigeon, Koley, Aquila, the Lunivore and the dryad of Islington Green.

They’re wonderful to be with, but I’ll still miss you.

Posted in writing | 7 Comments

Given / When / Then granularity

When we first wrote JBehave 1.0 we quickly recognised that there was power in the scenarios; in the conversations that they could help to drive, and in the reusability of the steps.

I loved the ease with which you could combine smaller steps to make bigger ones, use scenarios as the contexts of further scenarios, and take the necessarily procedural automated tests and turn them into sets of reusable objects.

Now BDD is more widely used, and people out there are using JBehave 2 and RSpec, and I hear complaints. Amongst them, this is one of the more common:

“Every time I change this screen, I have to go through fifteen files and add another step.”

Since JBehave uses plain text scenarios you can’t rely on the common refactoring tools, and that can make it a bit more painful than just messing with code. So, I thought I’d have a go at explaining how I avoid this issue; by sharing some of the ways in which I divide or combine contexts, events and outcomes into reusable components that help me avoid duplication in my scenarios.

Given a context

A context is a state which was set up by irrelevant forces, and which is used within the scenario to alter the outcome resulting from the events.

If the manner or time in which the context was set up matters, then that, too, is part of the context; unless it’s part of the behaviour you’re looking for, in which case it’s an event. The only reason for separating the contexts in which a scenario occurs from the events which are performed in the scenario is because it doesn’t matter how they were created. This means that Givens have more flexibility in implementation than Whens.

A context should matter. If you can remove the context from the scenario without changing the outcomes, it isn’t part of the Givens.

A context should be independent of other contexts. So, I prefer Given a wet newspaper to Given a newspaper / Given that the newspaper is wet. The first is less likely to require refactoring than the second.

A context should create an abandonable artifact. By this I mean that the forces which created the artifact – data in the database, files on the disk, a particular page at a given URL – can safely forget about the context they’ve created. Given an article about Iraq is a good context. Given I am logged in is not so good, even though we frequently use it as an example. Sorry. If it helps, it’s a step that rarely needs maintenance. Given we’ve filled in the comment box and are ready to submit it is likely to cause issues, because of all the other tiny steps that you have to use to get there.

When an event happens

An event exercises the feature whose behaviour you’re interested in when describing or running the scenario.

If you don’t care whether it works as long as it leaves things in a clean state, it’s a context. If you don’t actually need to do anything to cause an outcome – you’re simply checking that given some state, some other state is also present – you don’t need to write an event; just skip straight from Given to Then.

An event should create a valuable outcome.The granularity of the ideal event is very similar to that of the ideal context. As a user, I don’t want to go to the screen with the book, click the purchase button, navigate to the basket, enter the credit card number and click “submit”. I just want to buy a book. By specifying the steps which a user purchases a book inside the granularity of this larger step, we capture the value of that step. Since people rarely do things that they (or their sponsor, paymaster, loved one, etc.) don’t find valuable, this can usually be reused as one large step.

An event may be dependent on context or on another event. So, when I buy a book, and when I cancel my order within 15 days, then I should not be charged for the book.

An event should cause or contribute to an outcome. The outcome is something measurable. It could be that the outcome you’re looking for is an absence of something, for instance if a user’s preferences have been changed, and you no longer want to see all those Facebook groups. If it doesn’t cause an outcome, it’s a fairly irrelevant event.

Then an outcome occurs

An outcome describes the benefit that your system or application provides when the events are performed in the given context.

An outcome should have teeth. If a particular error message doesn’t have the exact wording expected, the world will not come to an end. If my credit card gets billed for the books but I don’t get them when I expect, it might.

An Outcome should be Specific, Measurable, Achievable, Relevant and Timeboxed. Ask a QA if you don’t know what this means. QAs are wise and can break anything.

An Outcome should represent the valuable purpose of the events. Instead of checking that a series of menus exist when you navigate to a particular screen, write a scenario that uses those menus and check that the benefits they provide are accessible through them.

Stories and regression tests

It can take quite a while to run scenarios. I sometimes like to turn mine into regression tests by combining them. I like to add contexts, events and outcomes to existing scenarios to better describe the benefits of using any particular feature in any particular context. This may mean that scenarios are related to more than one story. This will help keep them maintainable, and isn’t a bad thing.

I have never found the need to add a context to a scenario half-way through that scenario, even if it’s been created from several others.

I do frequently use one scenario as the context for other scenarios.

Unteaching the business

Sometimes, we accidentally train our business to talk to us about the solutions they’d like, occasionally in the language of software development. In that case, they’ll quite happily discuss the particular steps they need to take in the GUI to achieve the desired outcome, and may even have an idea of the underlying database tables and discuss what ought to be in those tables after the events.

If this happens, try to draw the conversation back to how the data will be used; why it’s valuable to produce that artifact in the first place. You never know; you may find you need to do less work than you thought you did.

Posted in bdd, jbehave, stories | 2 Comments

What does “Not Agile” look like?

Last week, the XtC London group met up with the SPA2009 attendees. Joseph Perline ran a panel session with Tim Mackinnon, Rachel Davies and others in which they discussed the weakening of the Agile brand.

One of the most interesting comments was Tim’s assertion that Agile “fails the purchase test”. That is; if someone won’t buy the opposite of what you’re selling, then the brand of what you’re selling has no value. In Agile terms, if no team will claim to be “not Agile” then the word “Agile” itself no longer has any value.

How many teams nowadays will actively claim to still be running Waterfall, for any flavour of Waterfall? Of course not. We’re all “Agile”, aren’t we?

At an Agile 2008 keynote, Uncle Bob asked everyone who was on an Agile project to raise their hands, then put them down if they failed any of certain criteria: no unit tests, no acceptance tests, iterations of more than two weeks, no showcases to the business, etc. By the end, hardly anyone had their hands up.

So, given that those of us who are on Agile projects are often less than perfectly Agile, how do you decide whether you’re actually in that space, or are merely one of the teams weakening the brand?

Do you know what “not Agile” looks like? And are you sure it doesn’t look a bit like you?

Posted in breaking models | 4 Comments

Tests should make things easy to change

People often ask me to review their unit tests, or answer questions on how to write different aspects of tests. I frequently find myself making the same suggestions over and over again. So, if you were thinking of asking one of these questions, maybe these common BDD refactorings will help.

I have 10 different instances of this class or enum. Does that mean 10 tests?

Tests should make things easy to change. What you’re doing is pinning down your code so that it’s hard for people to break it. I know that when your code is changed and the test breaks, people will look at the tests and work out what went wrong; that’s because your tests are brittle. Instead, I’d rather people came and looked at the tests because they’re clear examples of how to use the code and why it’s valuable.

QAs use equivalence partitioning. They say, “If I do this, it’s equivalent to doing these 5 other cases. So I don’t need to do those.” They also look at boundary conditions, where a shift in context starts to produce different behaviour. If we can do this too, we can cut down the number of different examples we need to produce for one aspect of behaviour.

So, for your ten cases, I might have just a few examples. This makes it easy for people to add more examples, and encourages them to understand the boundaries and partitions. We want it to be easy for people to change the code.

How do I do <this complicated thing> with my mocking framework?

Tests should make things easy to change. If you’re doing something complex with mocks, this is what it looks like:

  • Given <this context>
  • Expect <this outcome>
  • Also <this really complex stuff that you have to read carefully>
  • When <this event happens>
  • Then <go back to the expectations and read them, because this is where that gets checked>

If the mocking you’re doing is making it harder to change the code, or you don’t have access to something like Mockito, try rolling out your own. This will make it easier to do the things you want in a legible way, and any assertions can happen at the end of the test, along with the rest of the outcomes.

I’ve called my test should. Is that right?

Tests should make things easier to change. Why is returning true valuable? Because it triggers some business process? All right, then let’s call it should. This will encourage people to read your tests. While you’re at it, you might want to rename the method to the same thing.

Yes, you’ll get duplication between the test name and the code name. That’s because your method is doing what it says on the tin, and you’re providing an example of how to do that.

Now my test is called should. Do I need to write shouldNot?

Tests should make things easier to change. If I have to look in two different places for the examples of behaviour I want to change, then it’s not so easy. So, maybe not.

There are three ways of doing this. I’m guessing that triggering the process is the “happy path”. If this is the only valuable thing that happens, and it always happens, that’s fine – that’s the first way. But we know you were returning true, so there’s something else we need to consider. Is the happy path valuable without the sad path? For instance, a list tells you when it’s empty. That’s not valuable unless it also tells you accurately when it’s not empty. True for empty, false for not – they’re the same piece of behaviour. Neither is valuable without the other.

If you have two tests – one for each – you might want to put them in the same test method. Now you’re describing the behaviour holistically. I know Dave Astels said “one assertion per test”. We’re only looking at one aspect of behaviour. That’s the second way.

Of course, you might have a third way too. If you have several exceptional cases, you can list these as exceptions. So you’ll have one shouldNot for each context in which the process is not triggered. Validation is a good example of when this happens; you would normally have one description of the happy path, and one description for each of the exceptions.

I can’t write these automated tests. It’s very difficult to describe how to use my class.

Really? Probably it’s quite a difficult class to use correctly, then. How did you think of that API? Did you think of the class first, then think about how to use it?

Instead, try thinking as if you were the consuming class. Think, “I need something that does this for me. This is how it should look. This is how I want to use it.” Then write some code that does exactly what you want.

Because you’ve thought about how your class is going to be used, it will be easier to describe how to use it in the examples. It will also be easier to understand. So when you do successfully write your tests, you’ll know that your code is easier to change.

Posted in bdd | 2 Comments

Oops!

I was warned that there would come a point when the few spam posts I was getting would suddenly multiply to the point where I couldn’t keep up with them, but I didn’t listen. That point just came today.

I’ve deleted over 100 spam posts this morning, and installed a filter. If you made a comment that hasn’t appeared, or has mysteriously disappeared, I apologise – please feel free to repost. It should hopefully make it through the noise this time!

Posted in life | Leave a comment

You’ve heard of BDD, DDD and TDD

Damien Guard introduces the other *DDs..

I particularly like “Psychic Driven Development” and “Golf Driven Design”. Thanks, Damien.

Posted in bdd | 1 Comment

The pair chair

Finally, an approach to pairing which maximises colocation. It’s guaranteed to bring people closer to my thoughts. I can’t wait for the new batch to arrive.

Posted in humour | Leave a comment

Empowerment

Simon Baker has written a superb post, capturing the elusive nature of empowerment.

He mentions “an environment that tolerates mistakes to cultivate learning”. For me, this is an essential part of innovation; of the Lean metaphor that suggests a Software Development team is more like a Product Development team (designing new cars) than a Production Line (churning out the same thing repeatedly).

In a Production Line, we try to minimise variance (think Jidoka and Continuous Integration and Deployment).

In a Product Development team, we try to maximise learning opportunities, which means experimenting (think risk, innovation and doing things no one’s done before).

“There is no such thing as a failed experiment, only experiments with unexpected outcomes.”
Richard Buckminster Fuller

Are mistakes in Software Development really mistakes? Or just experiments from which we learn something new? And if they keep happening… what didn’t we learn?

Posted in lean | Tagged , , | 1 Comment