Many years ago I worked at Bankers Trust Australia, building derivative product applications with VMS Cobol for the user interface and Fortran for the numerically intensive parts. I mention the technology so that you can understand that this was the early days of the derivatives markets when there were only a few players in Australia, using relatively unsophisticated technology. I remember how proud we were of the first release, particularly of the way we validated all the user input and provided field-by-field feedback to the traders. Then I was lead into a trap.
"Wow, that validation is really impressive. It must have taken you quite a while to do that", said a trader.
"Yeah, it probably took a few weeks to get it all right", we replied.
"So you could have delivered it a few weeks earlier if you hadn't done that?"
"Yes, but the application would have crashed each time you made a mistake and you'd have had to start again", we said.
"We're pretty smart, and we can learnt to deal with that. Next time we'd rather have the features two weeks earlier so we can make some money from them thanks".
The underlying problem was that we hadn't talked to them about what was important (my excuse is that it was a long time ago and I was young and naive), but the lesson has stuck with me. In that situation, an input function vomiting it's guts on the screen was a scope issue, not a quality issue. In the years since I've regularly heard people say "we cut quality to go faster" or "we cut quality to finish earlier", but when I dig deeper I invariably hear that they altered the behaviour from the end-user perspective, and to me, a developer on a software project, that's cutting scope. I appreciate that other people with different perspectives might consider these features to be the difference between a high-quality or low-quality application, so when we start talking about "quality" we probably need to clearly understand which perspective we're talking about.
I was reminded of that by a recent post by Uncle Bob that starts with "People often make the argument that time to market is more important that quality. I’m not sure just what they mean by that. Do they mean that it’s ok if 20% of the features don’t work so long as they deliver quickly? If so, that’s just stupid.". I think that would be stupid, but what I think people mean is that the internal quality of the code has been sacrificed to reduce initial time to market, which is a very different proposition.
Showing posts with label development. Show all posts
Showing posts with label development. Show all posts
Wednesday, April 14, 2010
Tuesday, March 2, 2010
Seven Norms of Highly Powerful Software Teams
I found this, a handwritten copy no less, while cleaning out a filing cabinet tonight. At the bottom I've written "Charlie Alfred, Education Services Manager, Object Design Inc, Object Magazine, May 1994". Apparently I've been carrying this around for almost 16 years. Since Google didn't find the article, I reproduce here for your pleasure (and so I can find it again myself).
We strive to create an environment where the personal aspirations of each team member contribute to the goals of the team. We each are personally committed to achieving the goals of the team without sacrificing our lives outside work. We firmly believe that on the strongest teams the goals of the team agree with the goals of its members, rather than supersede them.
We share a common mission that is challenging, worthwhile, and clearly understood by all. This mission may be perceived by others as impossible or not worth the sacrifice. In this way, the mission helps us to identify our partners. Also, the more impossible the mission seems, the more we are forced to work together if we hope to succeed.
Quality is at the core of everything we do. If something is worth doing at all, it is worth doing right the first time.
We strive to fully understand the requirements of the systems we plan to construct, including being acutely aware of how those requirements evolve over time. Furthermore, we actively validate our understanding of these requirements with the system's intended beneficiaries.
Individually, we each contribute strengths that counterbalance each other's weaknesses. Collectively we possess all of the skills, attitudes, and habits necessary for team success. Wherever an essential skill, attitude or habit is missing (or lacking), one or more of us makes it a priority to develop it, or we seek to add a new member who possesses it.
We are open to sources of new ideas and new ways of doing things, and use the norm to resolve conflict. We listen to each other's points of views, aware that our commitment to the same mission means that differences of opinion identify alternate paths to the same goal rather than competing paths to different goals. Also, we continually learn about and apply the latest paradigms, processes, and products in our technical, organisational and interpersonal activities.
Around here we work smarter, not necessarily harder. We sprint all out toward our goals when it is necessary to do so, but also know how to relax and rejuvenate. We make the 80/20 rule work for us. We take no shortcuts and cut no corners on the 20% of our tasks that produce 80% of our results. If any sacrifices must be made (in the interest of time), they always fall in the 80% of our activities that produce 20% of our results.
Thanks Charlie!
Affinity for win/win
We strive to create an environment where the personal aspirations of each team member contribute to the goals of the team. We each are personally committed to achieving the goals of the team without sacrificing our lives outside work. We firmly believe that on the strongest teams the goals of the team agree with the goals of its members, rather than supersede them.
Common Mission
We share a common mission that is challenging, worthwhile, and clearly understood by all. This mission may be perceived by others as impossible or not worth the sacrifice. In this way, the mission helps us to identify our partners. Also, the more impossible the mission seems, the more we are forced to work together if we hope to succeed.
Quality
Quality is at the core of everything we do. If something is worth doing at all, it is worth doing right the first time.
Understanding Requirements
We strive to fully understand the requirements of the systems we plan to construct, including being acutely aware of how those requirements evolve over time. Furthermore, we actively validate our understanding of these requirements with the system's intended beneficiaries.
Interdependence
Individually, we each contribute strengths that counterbalance each other's weaknesses. Collectively we possess all of the skills, attitudes, and habits necessary for team success. Wherever an essential skill, attitude or habit is missing (or lacking), one or more of us makes it a priority to develop it, or we seek to add a new member who possesses it.
Receptivity
We are open to sources of new ideas and new ways of doing things, and use the norm to resolve conflict. We listen to each other's points of views, aware that our commitment to the same mission means that differences of opinion identify alternate paths to the same goal rather than competing paths to different goals. Also, we continually learn about and apply the latest paradigms, processes, and products in our technical, organisational and interpersonal activities.
Efficiency
Around here we work smarter, not necessarily harder. We sprint all out toward our goals when it is necessary to do so, but also know how to relax and rejuvenate. We make the 80/20 rule work for us. We take no shortcuts and cut no corners on the 20% of our tasks that produce 80% of our results. If any sacrifices must be made (in the interest of time), they always fall in the 80% of our activities that produce 20% of our results.
Thanks Charlie!
Labels:
agile,
agile development,
development,
professional
Thursday, January 7, 2010
Cogent Principles
Just in case you're interested :-)
- Feedback over Technical Elegance
- Reliability over Feedback
- Relationships over Code
- Learning over Producing
Labels:
agile,
business,
cogent,
development,
professional
Wednesday, January 6, 2010
Are we there (agile) yet?
I get asked this a lot, and let me say that I personally don't care very much. I do care whether or not the development process is effective or not, and mostly you know the answer to that before you ask me. But if I needed to form an independent opinion here are some questions that I'd ask you about feedback cycles. The underlying assumption is that a team will almost continually make mistakes (that vary dramatically in size) and that a lot of our practices and processes are about exposing those mistakes as quickly as possible. So how long is it between the these mistakes and the practice/process/activity that will expose that mistake, and how do you make that period smaller? These questions aren't presented in any particular order.
In addition, how long from a the time a feature is requested to the time that it hits production?
There are certainly other things that can go wrong with a project, but I think that reducing feedback cycle duration (time between event and feedback on the event) requires applying many agile principles and practices.
- A feature doesn't add any value
- Our code is unmaintainable
- We have duplicate code (or other quality problems)
- A developer introduces a new defect
- We've broken an existing feature
- What we're building doesn't match what was expected
- A feature is costing too much to be worth implementing
- A feature is unusable
- A feature works in isolation but not when integrated with other features
- The entire project is costing too much
- The project is going to cost too much
In addition, how long from a the time a feature is requested to the time that it hits production?
There are certainly other things that can go wrong with a project, but I think that reducing feedback cycle duration (time between event and feedback on the event) requires applying many agile principles and practices.
Labels:
agile,
agile development,
development,
professional
Monday, October 19, 2009
Roles in a self-organising team
One of the things that I'm asked to do fairly regularly is define the roles for an agile team, be it for Scrum, XP or some other flavour of agile. I usually end up doing this based on required skills, but my first impulse is to refuse, because I don't believe that a self-organising team actually has roles and I think that defined roles limit both the individual and the team. Let me examine that point before I explain how I do go about defining roles and why.
There is one role on a self-organising team - team member. The responsibility of that role is to bring all their skills to bear on the team's problems and organise their contributions to maximise the team's effectiveness.
When something needs to be done on an agile team everyone on the team should be able to see it, and in many cases it will be obvious which individual or individuals are the best suited to getting it done. The simplest approach is to allocate tasks based on skills, but the team might decide to use other criteria as well - they may need to grow their capacity in some area and decide to give the task to someone with less experience to give that person some practice; they may have limited capacity and be forced to give the task to someone who needs to learn the required skill, usually with mentoring from someone on the team. There will also be team-specific and project-specific reasons for not allocating tasks based simply on skill set. The important thing is that the reasons are well-articulated, and that the team member accepts responsibility for the task rather than having it arbitrarily assigned to them.
Although multi-skilled teams are normal and effective, provided the team is dedicated to achieving a result, has sufficient time and is reasonably self-aware you can imagine any arbitrary skills starting point. We could take a team that consisted entirely of testers and give them some work to do. The first tasks they encountered would require some analysis, so someone from the team would need to do this. They wouldn't complete the analysis as quickly or to the same quality as someone with the relevant experience, and they might not enjoy it as much. They might also need to get outside expertise (training and/or mentoring), but they would get through the work eventually. The team might find someone who wanted to grow into this role and make them the primary analyst, or they might decide that no one enjoys it and the role should be rotated through the team (this is probably less efficient, but it explicitly ranks satisfaction and retention ahead of efficiency). The same pattern can be repeated with development and anything else the team needs to get done.
Don't get me wrong - this is clearly a slow path to success and I wouldn't recommend it, but it is a valid approach. It's a contrast to the behaviour I see more often, which is "I can't do X, because I'm a Y". "Can't" is definitely the wrong word - finding the right word will determine how you respond to this assertion. If the person is really saying "I don't like doing X" then keep the assignment short and try to find some other way to make it attractive. If they're saying "I don't know how to do X", then they need training, guidance and support. If they're saying " I won't do X" then they probably shouldn't be part of the team.
That's why I don't like roles - why do I provide descriptions of roles and responsibilities? It's because I would rather start with a team with diverse skills than spend a lot of time developing the same skills, and most organisations understand that as a request for roles. I also appreciate that most people have gravitated towards a role that suits their preferences and skills, and asking people to move into other areas requires both time and motivation that we usually don't have a the beginning of project.
My hope is that companies that go to the trouble of assembling multi-discipline teams will also recognise the benefits of keeping those teams together for long periods of time. Time is the essential ingredient to building role-independent teams - it helps build trust between the team members, it lets people experiment and learn, and it gives the team opportunities to get feedback on different approaches to task assignment.
There is one role on a self-organising team - team member. The responsibility of that role is to bring all their skills to bear on the team's problems and organise their contributions to maximise the team's effectiveness.
When something needs to be done on an agile team everyone on the team should be able to see it, and in many cases it will be obvious which individual or individuals are the best suited to getting it done. The simplest approach is to allocate tasks based on skills, but the team might decide to use other criteria as well - they may need to grow their capacity in some area and decide to give the task to someone with less experience to give that person some practice; they may have limited capacity and be forced to give the task to someone who needs to learn the required skill, usually with mentoring from someone on the team. There will also be team-specific and project-specific reasons for not allocating tasks based simply on skill set. The important thing is that the reasons are well-articulated, and that the team member accepts responsibility for the task rather than having it arbitrarily assigned to them.
Although multi-skilled teams are normal and effective, provided the team is dedicated to achieving a result, has sufficient time and is reasonably self-aware you can imagine any arbitrary skills starting point. We could take a team that consisted entirely of testers and give them some work to do. The first tasks they encountered would require some analysis, so someone from the team would need to do this. They wouldn't complete the analysis as quickly or to the same quality as someone with the relevant experience, and they might not enjoy it as much. They might also need to get outside expertise (training and/or mentoring), but they would get through the work eventually. The team might find someone who wanted to grow into this role and make them the primary analyst, or they might decide that no one enjoys it and the role should be rotated through the team (this is probably less efficient, but it explicitly ranks satisfaction and retention ahead of efficiency). The same pattern can be repeated with development and anything else the team needs to get done.
Don't get me wrong - this is clearly a slow path to success and I wouldn't recommend it, but it is a valid approach. It's a contrast to the behaviour I see more often, which is "I can't do X, because I'm a Y". "Can't" is definitely the wrong word - finding the right word will determine how you respond to this assertion. If the person is really saying "I don't like doing X" then keep the assignment short and try to find some other way to make it attractive. If they're saying "I don't know how to do X", then they need training, guidance and support. If they're saying " I won't do X" then they probably shouldn't be part of the team.
That's why I don't like roles - why do I provide descriptions of roles and responsibilities? It's because I would rather start with a team with diverse skills than spend a lot of time developing the same skills, and most organisations understand that as a request for roles. I also appreciate that most people have gravitated towards a role that suits their preferences and skills, and asking people to move into other areas requires both time and motivation that we usually don't have a the beginning of project.
My hope is that companies that go to the trouble of assembling multi-discipline teams will also recognise the benefits of keeping those teams together for long periods of time. Time is the essential ingredient to building role-independent teams - it helps build trust between the team members, it lets people experiment and learn, and it gives the team opportunities to get feedback on different approaches to task assignment.
Labels:
agile,
agile development,
development,
professional
Tuesday, October 13, 2009
An interesting exchange
I wrote this in response to a customer email, but it seemed like something that I could put here:
On 14/10/2009, at 9:15 AM, ... wrote:
From: Steve
On 14/10/2009, at 9:15 AM, ... wrote:
Morning Steve,
Saw this article and thought it was interesting. http://www.javaworld.com/community/node/3530
Regards
...
From: Steve
It is interesting. I think it's hard to get the tone right when you're dismissive of agile zealots (who it's hard to agree with, almost by definition), without being dismissive of agile in general. Having been involved with agile for a long time I have a nice clear centre that tells me that agile should be adaptive, but I've also seen the problems that come from being too adaptive too early.
I totally agree that the process for one or two really talented, motivated people is different from the process you use for larger groups/applications. Alistair Cockburn has been very explicit about this in his writing about the Crystal family of methodologies, and Kent Beck has touched on the same subject from a different perspective when he wrote his blogs about "Flight of the Startup". The hard part for most of us is dispassionately looking our our team and ourselves and changing process over time. It's easy to err on the side of too much, too soon or too little, too late, but very hard to judge it just right.
On the "where's the Access of today", that's a question that we've thrown around within Cogent as well. My personal opinion, shared by some others in the company but not everyone, is that we've gone backwards over the last 10 years in productivity and our ability to deliver things quickly. Our capabilitity has increased - we can deliver bigger, more sophisticated applications - but in the process everything seems to have become harder.
I agree with the poster who mentioned the combination of Ruby on Rails and Heroku - that's the combination that I'm using for my personal projects now. I think it's the combination that's the winner - there are other frameworks that to me look more promising than RoR but with each of them I have to manage my production environment myself (for some of them even setting up a production environment is a challenge). Heroku takes care of that and make deployment as simple as possible.
On the OS X desktop MacRuby looks very promising, leveraging Inteface Builder with the power of Ruby. I don't play in the Windows space, so I don't have any idea what the possibilities are there.
...
Steve
Labels:
agile,
agile development,
development,
professional
Monday, September 7, 2009
Code Review for Git
I wanted to find a way to contribute to projects that I couldn't pair on, and to be able to scan a project for possible changes without sitting down and taking up someone's time. Sounded a lot like automated code review, so I had a look around at available code review tools. There are a few available - Review Board, Smart Bear and Crucible among them. I know Atlassian and generally like their products so I decided to install Crucible and give it a try.
There were a few confusing configuration problems. Until I read the documentation more closely (at all?) I wasn't aware that the beta Git plugin only worked against local git repositories, and I had to change a configuration file to convince Crucible that Ruby files should be treated as text instead of binaries, but once I got past these problems I clearly had a powerful tool for distributed, multi-party code reviews available to me.
So I created a review, looked at some code, and saw one thing that I would change. I wrote the comment, but things just felt wrong. It had taken me a while to type to comment (I'm not the world's fastest typist, but nor am I the slowest), and it felt like a waste of time. It would have been far faster to make the change and annotate the corresponding commit, but what I had was a code review tool, not an editor. Something wasn't working for me.
When I do a code review I want to achieve two things - I want to fix the code and I want to educate someone (where that someone may be me, if I wrote the original code). What I really wanted was something (an editor) that would let me focus on changes between versions, but let me change the latest version and save it. My VCS could store the comments against the (small) changes and I could point people to the VCS history to see what I'd done, potentially using the same tool.
After looking at a few different tools last night I've settled on Changes. Changes lets you compare directory structures and files, and it comes with some Ruby scripts that will help you retrieve specific revisions from Git, drop them into temp directories and review the differences. I've modified the script to use the current directory if you're comparing to HEAD, so that changes to the head are saved directly to disk and can be committed.
Here's my process:
1) Use GitX to determine the revision I want to use as the base
2) Use changes to view the differences
3) Incrementally work through the files either making changes or excluding the files.
I've created a (silent) video that shows me working through one review. I only make one small change, so it's mostly scrolling and excluding. One small point - the video uses an older version of my Ruby script that created a temp directory even if you were looking at HEAD, so changes were lost. I've fixed that in this version.
I saw some comments that Changes was rather expensive (US$49.99), but it's really cheap compared to many code review tools so I'm pretty happy with this approach.
There were a few confusing configuration problems. Until I read the documentation more closely (at all?) I wasn't aware that the beta Git plugin only worked against local git repositories, and I had to change a configuration file to convince Crucible that Ruby files should be treated as text instead of binaries, but once I got past these problems I clearly had a powerful tool for distributed, multi-party code reviews available to me.
So I created a review, looked at some code, and saw one thing that I would change. I wrote the comment, but things just felt wrong. It had taken me a while to type to comment (I'm not the world's fastest typist, but nor am I the slowest), and it felt like a waste of time. It would have been far faster to make the change and annotate the corresponding commit, but what I had was a code review tool, not an editor. Something wasn't working for me.
When I do a code review I want to achieve two things - I want to fix the code and I want to educate someone (where that someone may be me, if I wrote the original code). What I really wanted was something (an editor) that would let me focus on changes between versions, but let me change the latest version and save it. My VCS could store the comments against the (small) changes and I could point people to the VCS history to see what I'd done, potentially using the same tool.
After looking at a few different tools last night I've settled on Changes. Changes lets you compare directory structures and files, and it comes with some Ruby scripts that will help you retrieve specific revisions from Git, drop them into temp directories and review the differences. I've modified the script to use the current directory if you're comparing to HEAD, so that changes to the head are saved directly to disk and can be committed.
Here's my process:
1) Use GitX to determine the revision I want to use as the base
2) Use changes to view the differences
3) Incrementally work through the files either making changes or excluding the files.
I've created a (silent) video that shows me working through one review. I only make one small change, so it's mostly scrolling and excluding. One small point - the video uses an older version of my Ruby script that created a temp directory even if you were looking at HEAD, so changes were lost. I've fixed that in this version.
I saw some comments that Changes was rather expensive (US$49.99), but it's really cheap compared to many code review tools so I'm pretty happy with this approach.
Labels:
agile,
agile development,
development,
os x,
ruby,
software tools
Tuesday, July 28, 2009
Software Cultures
I think every programming language (and frameworks too) generates a dominant culture. It might be implicit in the language/tool itself, or it might happen more gradually through self selection. For example, here's how I distinguish three cultures (the boundaries are inherently fuzzy, and I'm aware that this is totally personal opinion, so people are bound to disagree by either raising counter-examples or saying they don't agree, and that's fine). I also have my tongue firmly in my cheek, but I believe there's an element of truth in each statement.
Java - a fascination with flexibility, generally achieved through complexity (and a healthy(?) does of XML). Ten years ago I would have said Java was focussed on solidity and reliability (in the meeting expectations sense), but I think this has changed over time. New functionality is implemented by adding new options. If it doesn't work, it's because you didn't configure it properly.
Rails - a fascination with bright, shiny new toys. Encourages the image of the developer as a person young enough to live in the code, who can deal with either new tools or tools that fundamentally change every three months or so. New functionality is achieved by implementing a new plugin/gem which needs to be compared to all existing alternatives. No solutions is 100% complete because people lose interest first. If it doesn't work, get in there and change the code yourself. [note - I don't comment on Ruby itself as I don't have enough exposure to the non-Rails community]
Seaside - I'm an old-hand in Smalltalk, just learning Seaside. So far I see a fascination with having something that just frackin' works (though it might be heavily engineered). The documentation sucks though, so get into the code. Changes are generally transparent and backwardly compatible. If it doesn't work, you did something wrong - the community is the documentation.
Each of these cultures has strengths and weaknesses. I'm 46 years old (shit, when did that happen), my raw memory isn't as strong as it was, and I don't think as quickly as I used to. But I have a load of experience in developing design models and applications - I want tools that get out of my way and let me build things. Given my Smalltalk experience, Seaside is a great match for me - much better than Rails. If there was the equivalent of "Agile Web Development Using Rails" then it would rock!
In an age when everyone needs to use portfolio theory to manage their software investments, starting low-cost initiatives by the dozen then abandoning the ones that don't work out, Rails is a clear winner over Java. It lets me experiment at low cost, it lets me get something out-the-door quickly. In that environment Java is a set of leg-irons. But the Rails culture thrives when people have enough time and energy to deal with a firehose of changes and alternatives - as an entrepreneur a lot of this is simply waste. One solution might be to standardise on a particular configuration - that seems like a false.optimisation.
Java - a fascination with flexibility, generally achieved through complexity (and a healthy(?) does of XML). Ten years ago I would have said Java was focussed on solidity and reliability (in the meeting expectations sense), but I think this has changed over time. New functionality is implemented by adding new options. If it doesn't work, it's because you didn't configure it properly.
Rails - a fascination with bright, shiny new toys. Encourages the image of the developer as a person young enough to live in the code, who can deal with either new tools or tools that fundamentally change every three months or so. New functionality is achieved by implementing a new plugin/gem which needs to be compared to all existing alternatives. No solutions is 100% complete because people lose interest first. If it doesn't work, get in there and change the code yourself. [note - I don't comment on Ruby itself as I don't have enough exposure to the non-Rails community]
Seaside - I'm an old-hand in Smalltalk, just learning Seaside. So far I see a fascination with having something that just frackin' works (though it might be heavily engineered). The documentation sucks though, so get into the code. Changes are generally transparent and backwardly compatible. If it doesn't work, you did something wrong - the community is the documentation.
Each of these cultures has strengths and weaknesses. I'm 46 years old (shit, when did that happen), my raw memory isn't as strong as it was, and I don't think as quickly as I used to. But I have a load of experience in developing design models and applications - I want tools that get out of my way and let me build things. Given my Smalltalk experience, Seaside is a great match for me - much better than Rails. If there was the equivalent of "Agile Web Development Using Rails" then it would rock!
In an age when everyone needs to use portfolio theory to manage their software investments, starting low-cost initiatives by the dozen then abandoning the ones that don't work out, Rails is a clear winner over Java. It lets me experiment at low cost, it lets me get something out-the-door quickly. In that environment Java is a set of leg-irons. But the Rails culture thrives when people have enough time and energy to deal with a firehose of changes and alternatives - as an entrepreneur a lot of this is simply waste. One solution might be to standardise on a particular configuration - that seems like a false.optimisation.
Tuesday, July 14, 2009
What would you like in a code quality tool?
Although continuous integration has been a huge step forwards for the development community I think that over time we've tended to treat it as a rather large bucket that we could keep tossing things into. Sure, someone should immediately address that method that's too long, but should it really stop the build and the release of the next version if all the tests pass? My feeling is no, it shouldn't.
I think that the agile community could do more to encourage various parallel continuous processes that test different aspects of the application. In particular, we could separate the static analysis of the code quality from the behavioural analysis that we perform with tests, be they unit, integration or functional tests. If we separate the two aspects then we can look to improve them at different rates and in different dimensions. This separation is the motivation behind an idea that Marty Andrews and Simon Harris have been kicking around for a few years (Marty is the author of Roodi and Complexian, and Simon is the author of Simian, so they have a long-running interest in code quality). Cogent is now planning to turn this into a product - something that you can point towards your source code repository and simply unleash.
We don't have a name for the product yet (suggest one if you like), but it will run static analysis tools (like Checkstyle, Simian, Roodi, Reek, Flay) against each revision of your code base so that you can see trends over time, and it will produce warnings when the values of the metrics exceed certain thresholds. The product will be free for open source projects.
We'll start with a simple, web-based version, probably to run over Ruby projects in public Git repositories (because that's low-hanging fruit for us), but we're going to be very community driven. With this in mind we have a survey that will let you influence the development direction, even before we start. If a tool like this is something that interests you, please fill in our product survey. As a bonus, the first 500 people to complete the survey will get unlimited free access to the product in recognition of their contributions.
I think that the agile community could do more to encourage various parallel continuous processes that test different aspects of the application. In particular, we could separate the static analysis of the code quality from the behavioural analysis that we perform with tests, be they unit, integration or functional tests. If we separate the two aspects then we can look to improve them at different rates and in different dimensions. This separation is the motivation behind an idea that Marty Andrews and Simon Harris have been kicking around for a few years (Marty is the author of Roodi and Complexian, and Simon is the author of Simian, so they have a long-running interest in code quality). Cogent is now planning to turn this into a product - something that you can point towards your source code repository and simply unleash.
We don't have a name for the product yet (suggest one if you like), but it will run static analysis tools (like Checkstyle, Simian, Roodi, Reek, Flay) against each revision of your code base so that you can see trends over time, and it will produce warnings when the values of the metrics exceed certain thresholds. The product will be free for open source projects.
We'll start with a simple, web-based version, probably to run over Ruby projects in public Git repositories (because that's low-hanging fruit for us), but we're going to be very community driven. With this in mind we have a survey that will let you influence the development direction, even before we start. If a tool like this is something that interests you, please fill in our product survey. As a bonus, the first 500 people to complete the survey will get unlimited free access to the product in recognition of their contributions.
Labels:
agile,
agile development,
announcements,
cogent,
development,
products,
professional,
rails,
ruby,
software tools
Friday, June 26, 2009
Emerging Agile UX Practices
I am not a UX professional, but I've interacted with a number of them over the last few years, in the context of agile development. The interaction hasn't always been smooth - the prevailing mood has been that agile development was asking UX professionals to do a bad job, but I've never felt that way myself. My feeling is that UX professionals and software developers have been on similar paths in regard to agile development, but the UX people are starting a few years later and have had less leadership so their challenge has been more difficult.
Why do I think the paths for both roles are similar? Because once-upon-a-time many software developers would have said that agile was asking them to do a bad job. After all, how could you do a good job with no upfront design, no long architecture phase, no detailed requirements? But what developers realised (either quickly or slowly, or perhaps not yet) was that agile values didn't mean doing a bad job, they meant doing a good job in a different way. Part of that was learning new skills and new ways to work. The software/programming community was lucky because they had early leadership in these skills and practices.
The feedback I've gotten in the past from UX folk was essentially "when we're in an agile project we can't work the way we work now", to which my answer was a resounding YES! You (as a profession) need to find new ways to work that produce good results faster. It's not your fault that those techniques don't exist yet, or that they may be hard to discover, but that doesn't invalidate the search. But I haven't done very well at explaining that.
However, practices for UX professionals on agile projects are emerging now, and Jeff Patton has done a good job of describing the practices that he sees working in this context. Moving to agile development means developing new approaches for everyone involved, and it's good that this is now a little easier for UX.
Why do I think the paths for both roles are similar? Because once-upon-a-time many software developers would have said that agile was asking them to do a bad job. After all, how could you do a good job with no upfront design, no long architecture phase, no detailed requirements? But what developers realised (either quickly or slowly, or perhaps not yet) was that agile values didn't mean doing a bad job, they meant doing a good job in a different way. Part of that was learning new skills and new ways to work. The software/programming community was lucky because they had early leadership in these skills and practices.
The feedback I've gotten in the past from UX folk was essentially "when we're in an agile project we can't work the way we work now", to which my answer was a resounding YES! You (as a profession) need to find new ways to work that produce good results faster. It's not your fault that those techniques don't exist yet, or that they may be hard to discover, but that doesn't invalidate the search. But I haven't done very well at explaining that.
However, practices for UX professionals on agile projects are emerging now, and Jeff Patton has done a good job of describing the practices that he sees working in this context. Moving to agile development means developing new approaches for everyone involved, and it's good that this is now a little easier for UX.
Labels:
agile,
agile development,
development,
professional
Tuesday, April 14, 2009
Failure is mandatory
A few days ago I had a conversation with Travis about failure. In some senses I'm a hard ass about failure - I think if you protect people from failure all the time you also protect them from learning anything. It's still important to protect people from potentially traumatic failure, but traumatic failure is the exception rather than the rule.
The context was how far our duty of care extends as consults, particularly in regard to the transfer of a solution to the customer. There's typically tension around this issue - the customer wants to maximise their investment in the solution itself, and in other projects as well, and that works against either documenting the solution or getting permanent staff involved. One position is that we should go out of our way to document/record knowledge of the solution for handover, even if the customer hasn't made that a priority. I think that's paternalistic (which is ironic given the example I'll use later). I think it's our responsibility to warn the customer that there's a handover risk, and to give some advice on how we'd handle that, but in the end it's up to the customer to decide how to invest their resources, and to wear the consequences of those decisions. I think it would be quite wrong of us to divert resources into documentation against the customers wishes. We might think the customer has made the wrong decision, but it's still their decision and they won't thank you for subverting it.
Another context that we talked about was when you see someone else about to do the "wrong thing". You should definitely draw attention to the problem as you see it, but if the person goes ahead anyway, should you do anything to protect the project from the outcome? My position is that you should not - you should let the project suffer the consequences (again excepting traumatic outcomes). It's possible that your fears won't be realised, in which case you'll learn something. If they are realised, the project team will learn something (including perhaps to pay more attention to your advice) and may be able to avoid similar problems in future. If you just fix it, then what the project team will learn is that there are no negative outcomes from that behaviour, so they'll quite happily repeat, and you'll have the same personal situation later. Ad infinitum.
The same kinds of things apply to my son. I try to protect him from traumatic outcomes, but sometimes I need to let him get hurt (physically or emotionally) so that he learns not to repeat a behaviour.
The context was how far our duty of care extends as consults, particularly in regard to the transfer of a solution to the customer. There's typically tension around this issue - the customer wants to maximise their investment in the solution itself, and in other projects as well, and that works against either documenting the solution or getting permanent staff involved. One position is that we should go out of our way to document/record knowledge of the solution for handover, even if the customer hasn't made that a priority. I think that's paternalistic (which is ironic given the example I'll use later). I think it's our responsibility to warn the customer that there's a handover risk, and to give some advice on how we'd handle that, but in the end it's up to the customer to decide how to invest their resources, and to wear the consequences of those decisions. I think it would be quite wrong of us to divert resources into documentation against the customers wishes. We might think the customer has made the wrong decision, but it's still their decision and they won't thank you for subverting it.
Another context that we talked about was when you see someone else about to do the "wrong thing". You should definitely draw attention to the problem as you see it, but if the person goes ahead anyway, should you do anything to protect the project from the outcome? My position is that you should not - you should let the project suffer the consequences (again excepting traumatic outcomes). It's possible that your fears won't be realised, in which case you'll learn something. If they are realised, the project team will learn something (including perhaps to pay more attention to your advice) and may be able to avoid similar problems in future. If you just fix it, then what the project team will learn is that there are no negative outcomes from that behaviour, so they'll quite happily repeat, and you'll have the same personal situation later. Ad infinitum.
The same kinds of things apply to my son. I try to protect him from traumatic outcomes, but sometimes I need to let him get hurt (physically or emotionally) so that he learns not to repeat a behaviour.
Wednesday, January 14, 2009
The cloud...it's full of *people*!
This is the story of the development of a small piece of software to deploy to the cloud, developed by a cloud of people, and how nominally unrelated groups interacted along the way.
I'm interested in having a way to easily create new Rails servers in the cloud (specifically AWS) and to deploy my apps to them. I'm familiar with the bits and pieces that are involved but I hadn't stitched them together. I started to write a Rails app to manage my AWS assets, partially as a path to learning extjs, but when the AWS Console came out I ditched that and started back on the original problem. Here are the different bits that I planned to use, and how I became aware of them:
The last piece to this puzzle is a web site called oDesk (http://www.odesk.com/). I was talking to a client last week and she mentioned that she thought Australian Rails developers were the most expensive in the world. When I asked her what she was doing she said that she was using off-shore Rails developers and was finding good people who would work for US$20/hr, from India but also from the USA. It seemed like the recession in the USA was having interesting side affects. I was definitely curious how using oDesk would work from a client perspective.
So I had this small problem that I didn't have time to work on, and my curiousity about oDesk, and it seemed natural to solve them together. I posted my job on oDesk - produce a script that, given an EC2 instance and an ESB volume, would automatically configure the instance to use Rails with Passenger and Postgres, storing the data on the EBS volume. In addition, provide a test application so I can verify the Capistrano deployment to the instance. I posted this as a fixed price job, and my plan was to use a few different people and compare the outcomes. I posted my job last Sunday (it's currently Thursday).
I had my first response in a few hours, from within Australia! Twenty four hours didn't bring any more responses, so I pushed my job in front of a number of Rails developers who had high ratings. Many declined as they were too busy, some thought the suggested price was too low given the need to learn about AWS, and some still haven't responded. I got two more positive responses, one from an experienced developer in St. Petersburg and one from a less experienced developer on the east coast of the USA. The bids were $333.33 (Australia), $250.00 (Russia), and $166.67 (USA). The expected development times were 1 day, 1 day and 1 week.
I accepted the responses and nominated a starting date of Tuesday. On Wednesday I got my solutions from Australia and St Petersburg. I've tested the Russian solution and it works fine. There seem to be couple of issues in the Australian solution but the developer
is being very responsive, and the USA solution isn't due yet.
What's more interesting is what else happened in the 24 hours of development. The Russian developer forked passenger-stack on GitHub and hosted the fork as a public repository on GitHub (which was fine by me). However, I found out about this through an email from Marcus Crafter, who knew I was looking for a Postgres solution and pointed the fork out to me! Then I saw these tweets from Ben Schwarz (@benschwarz) "@kouky Just so you know, someone forked passenger-stack overnight rolling postgres support in, I'll try and pull everything together :)" and "@atnan @kouky, I've just blindly merged the PostgreSQL stuff as I'm up in the hills. I'll check it all out tomorrow :)" The status message for passenger-stack on GitHub now says "Adding support for PostgreSQL. Sprinkle will prompt the user to select MySQL/PostgreSQL server and the relevant Ruby database drivers."
So it looks like my little experiment ended up sponsoring the change that I wanted in the core implementation of passenger-stack. I suppose I could have asked Ben to do it originally, but that seemed like an imposition and I would have only achieved one of my goals. Now I have a script to configure my EC2 instances automatically, a better feeling for oDesk and off-shore development, and I've discovered that you can always sponsor the features that you want in a piece of open source software. Well worth my costs :-)
I'm interested in having a way to easily create new Rails servers in the cloud (specifically AWS) and to deploy my apps to them. I'm familiar with the bits and pieces that are involved but I hadn't stitched them together. I started to write a Rails app to manage my AWS assets, partially as a path to learning extjs, but when the AWS Console came out I ditched that and started back on the original problem. Here are the different bits that I planned to use, and how I became aware of them:
- Sprinkle, by Marcus Crafter (http://github.com/crafterm/sprinkle/tree/master) - Sprinkle handles deployment of resources on Ubuntu boxes in a pretty easy-to-understand way. Unfortunately I have a strong preference for Postgres over MySql (blame Simon Harris) and the default Sprinkle deployment recipes all use MySql. Still, it didn't take me long to make some extensions to install Postgres instead of MySql.
- Passenger-Stack, by Ben Schwarz (http://github.com/benschwarz/passenger-stack/tree/master) - Sprinkles for Apache, Passenger, Mysql, Memcached & Git. I found out about this via a Ryan Allen tweet.
- Amazon Web Services (http://aws.amazon.com/) - well known, but the fairly recent addition of Elastic Block Storage (EBS) gives a way to easily create persistent data that outlives a given instance, say for a Postgres database.
The last piece to this puzzle is a web site called oDesk (http://www.odesk.com/). I was talking to a client last week and she mentioned that she thought Australian Rails developers were the most expensive in the world. When I asked her what she was doing she said that she was using off-shore Rails developers and was finding good people who would work for US$20/hr, from India but also from the USA. It seemed like the recession in the USA was having interesting side affects. I was definitely curious how using oDesk would work from a client perspective.
So I had this small problem that I didn't have time to work on, and my curiousity about oDesk, and it seemed natural to solve them together. I posted my job on oDesk - produce a script that, given an EC2 instance and an ESB volume, would automatically configure the instance to use Rails with Passenger and Postgres, storing the data on the EBS volume. In addition, provide a test application so I can verify the Capistrano deployment to the instance. I posted this as a fixed price job, and my plan was to use a few different people and compare the outcomes. I posted my job last Sunday (it's currently Thursday).
I had my first response in a few hours, from within Australia! Twenty four hours didn't bring any more responses, so I pushed my job in front of a number of Rails developers who had high ratings. Many declined as they were too busy, some thought the suggested price was too low given the need to learn about AWS, and some still haven't responded. I got two more positive responses, one from an experienced developer in St. Petersburg and one from a less experienced developer on the east coast of the USA. The bids were $333.33 (Australia), $250.00 (Russia), and $166.67 (USA). The expected development times were 1 day, 1 day and 1 week.
I accepted the responses and nominated a starting date of Tuesday. On Wednesday I got my solutions from Australia and St Petersburg. I've tested the Russian solution and it works fine. There seem to be couple of issues in the Australian solution but the developer
is being very responsive, and the USA solution isn't due yet.
What's more interesting is what else happened in the 24 hours of development. The Russian developer forked passenger-stack on GitHub and hosted the fork as a public repository on GitHub (which was fine by me). However, I found out about this through an email from Marcus Crafter, who knew I was looking for a Postgres solution and pointed the fork out to me! Then I saw these tweets from Ben Schwarz (@benschwarz) "@kouky Just so you know, someone forked passenger-stack overnight rolling postgres support in, I'll try and pull everything together :)" and "@atnan @kouky, I've just blindly merged the PostgreSQL stuff as I'm up in the hills. I'll check it all out tomorrow :)" The status message for passenger-stack on GitHub now says "Adding support for PostgreSQL. Sprinkle will prompt the user to select MySQL/PostgreSQL server and the relevant Ruby database drivers."
So it looks like my little experiment ended up sponsoring the change that I wanted in the core implementation of passenger-stack. I suppose I could have asked Ben to do it originally, but that seemed like an imposition and I would have only achieved one of my goals. Now I have a script to configure my EC2 instances automatically, a better feeling for oDesk and off-shore development, and I've discovered that you can always sponsor the features that you want in a piece of open source software. Well worth my costs :-)
Wednesday, January 30, 2008
Uses of OpenID
I'm a user of OpenID, but this video from Google is an excellent introduction to the concept, the uses, and the pros and cons.
Particularly interesting to me as a developer were the ideas of using OpenID as a 'lightweight' authentication mechanism for sites that want a low barrier for registration and access, and recognizing multiple openids so that a site can access id-specific features from each. Highly recommended!
Particularly interesting to me as a developer were the ideas of using OpenID as a 'lightweight' authentication mechanism for sites that want a low barrier for registration and access, and recognizing multiple openids so that a site can access id-specific features from each. Highly recommended!
Saturday, June 9, 2007
New introduction to agile methods
It's been a while since I posted, and it's mainly because I've been busy updating our introduction to agile methods. It's done now, at least well enough to show people. Warning - this is a large (7mb) pdf file. It's not intended to stand alone - the real value comes from someone talking it through - but you may still find it interesting, and there may be parts you can use (with accreditation please).
Friday, May 25, 2007
A New Agile Manifesto?
Brian Marick makes some great points here about things that are important to agile development, but weren't the first order of business when our major concern was getting permission to do it. If the default is that agile is acceptable, Brian points out that it's essential to understand what teams need to execute agile processes successfully.
Brian's pulls are "Skill, Disciple, Ease and Joy". Parts of this resonate with something I've said to plenty of people - too many software developers consider pain to be part of their jobs. I've seen some terrible things done and excused with "it's always hard", or "it has to be that way". For change to occur, we first need to see the potential for something better ("it shouldn't hurt like this"), and then we need to be able to envision that better thing (which requires skill). And the result is frequently things that are easier to use for everyone.
The joy thing is going to be even harder though. Programmers seem to have an habit of finding someone else to blame for their pain, rather than looking closely at themselves. If you don't believe me, go read some Dilbert. Dilbert's problems are caused by Catbert, by PHB, sometimes by Wally, and he's generally the good natured, innocent bystander. Now these characters are intentionally caricatures, and I don't want to stretch the analogy too far, but I think they capture the software development zeitgeist. We'd do better if we stopped seeing ourselves as victims, and involved ourselves in finding solutions to the problems we see, especially the ones that impact us! If you think your boss is making stupid decisions, make it your business to understand their perspective on the decision - maybe you're not even looking at the same problems!
Anyway, Brian says things better than I can right now, so go read his blog.
Brian's pulls are "Skill, Disciple, Ease and Joy". Parts of this resonate with something I've said to plenty of people - too many software developers consider pain to be part of their jobs. I've seen some terrible things done and excused with "it's always hard", or "it has to be that way". For change to occur, we first need to see the potential for something better ("it shouldn't hurt like this"), and then we need to be able to envision that better thing (which requires skill). And the result is frequently things that are easier to use for everyone.
The joy thing is going to be even harder though. Programmers seem to have an habit of finding someone else to blame for their pain, rather than looking closely at themselves. If you don't believe me, go read some Dilbert. Dilbert's problems are caused by Catbert, by PHB, sometimes by Wally, and he's generally the good natured, innocent bystander. Now these characters are intentionally caricatures, and I don't want to stretch the analogy too far, but I think they capture the software development zeitgeist. We'd do better if we stopped seeing ourselves as victims, and involved ourselves in finding solutions to the problems we see, especially the ones that impact us! If you think your boss is making stupid decisions, make it your business to understand their perspective on the decision - maybe you're not even looking at the same problems!
Anyway, Brian says things better than I can right now, so go read his blog.
Wednesday, April 18, 2007
Programming is important - really important
I wrote this in response to a comment on my post about Dreaming in code, but I wanted to expose it to people who view this via RSS, so here's the comment and my response.
Finally, something I can talk about.
I disagree totally.
Programming is not about code.
For me, a program or application doesn't live in the computer. It is not the bits and bytes. It extends much, much further.
For me, an application extends across everything the code affects. Not only is it the code, but it is also the users’ and the stakeholders’ mental models, processes and understanding of what the code does, what their organisation is and how to use the code to enhance their organisation.
Applications extend beyond computers into the people.
Example - a content management system is more that just the DotNetNuke code. It is also assigning the roles of writers and editors, it is understanding the people who will read the content and shaping the navigation and tone of the articles appropriately, it is teaching everyone in the organisation that they can request changes, and communicate their important stories with the world through the web.
When I am writing an application, I am not writing code. I am talking to people, I am trying to understand their issues, ideas and viewpoints. I am trying to work my way to the root of the problem. I am working out what questions to ask, talking to end users and training people to see things in different ways.
The application exists both in the computer and in the minds of people. As application building is not about code, it's not creative writing.
You don't look at the source code for great pieces of software. Or look at the architecture of great pieces of software. You don't look at their design.
What are patterns if not examples of great pieces of software and design?
What is MSDN - the magazine? Yes it is a Microsoft advertising vehicle, but it still has great code to read, understand and appreciate.
What are all the sites, forums and blogs on coding (including this one) but a sharing of knowledge on building applications and computing?
I use some of these words differently to you. I don't think a 'program' is that same as an 'application', and I don't think that 'software/application development' is the same as 'programming' at all. So I agree with all the things you say, up to the quote, about applications and application development, but at some point in application development we need to do some programming and to me that is absolutely, positively, by definition, about code. Programming isn't the only thing that we do in application development, but it's an important thing and I think there is a tendency to devalue it; to treat it as a typing exercise in which all programs that perform the same function are treated as equally worthy (you didn't say this, but I hear it a lot). I think application development would benefit from improvements to many disciplines, but I feel that programming is one of the most neglected disciplines at all.
When we write a program we write for two very different audiences - the program needs to be understood by the computer, which is apparent when it does (or doesn't) perform the expected functions, but it also needs to be understood by human beings. Most of our effort currently goes into pleasing the computer, but in some sense this is the easier of the two audiences. Gabrielle is saying (and I agree strongly) that we need to put more of our effort into satisfying the human audience for code. I'll assert as a corollary that finding ways to make code more expressive to people will also make it easier to write code that satisfies the computer as well, but I can't offer a proof in a mathematical sense.
As to what are patterns, and the code in places like MSDN and most web sites (including this one), they bear the same relationship to great programming that a power tool catalogue has to great building. They're focussed predominantly on efficiency, and on satisfying the computer, not on the aesthetics of programming as it's experienced by a human being. Christopher Alexander presented a keynote at OOPSLA many years ago, which I had the honour of attending, at which he said that he was ashamed of the way that the software community had applied patterns; that the heart of his idea was creating environments that appealed to our humanity but that software patterns has been sterilised - stripped of aesthetics and reduced to the equivalent of screwdrivers (my words, not his, but I think I'm faithful to the intent). Show me an article, or rather not one exceptional article but a body of work, that addresses different ways to name variables within the same programming idiom to improve expressiveness, or how to write code that brings a smile to your face, and we'll be heading down the path that Gabrielle is talking about, and we'll have taken one tiny programmatic step towards Alexander's goals.
You once asked me in email why I went back to uni to study psychology - my reply should have been because I think it would make me a better application developer. If I wanted to become a better programmer I wouldn't choose psych, I'd choose creative writing and literature, and that I haven't speaks to lack of time and dedication to my craft, not to a lack of need.
Finally, something I can talk about.
I disagree totally.
Programming is not about code.
For me, a program or application doesn't live in the computer. It is not the bits and bytes. It extends much, much further.
For me, an application extends across everything the code affects. Not only is it the code, but it is also the users’ and the stakeholders’ mental models, processes and understanding of what the code does, what their organisation is and how to use the code to enhance their organisation.
Applications extend beyond computers into the people.
Example - a content management system is more that just the DotNetNuke code. It is also assigning the roles of writers and editors, it is understanding the people who will read the content and shaping the navigation and tone of the articles appropriately, it is teaching everyone in the organisation that they can request changes, and communicate their important stories with the world through the web.
When I am writing an application, I am not writing code. I am talking to people, I am trying to understand their issues, ideas and viewpoints. I am trying to work my way to the root of the problem. I am working out what questions to ask, talking to end users and training people to see things in different ways.
The application exists both in the computer and in the minds of people. As application building is not about code, it's not creative writing.
You don't look at the source code for great pieces of software. Or look at the architecture of great pieces of software. You don't look at their design.
What are patterns if not examples of great pieces of software and design?
What is MSDN - the magazine? Yes it is a Microsoft advertising vehicle, but it still has great code to read, understand and appreciate.
What are all the sites, forums and blogs on coding (including this one) but a sharing of knowledge on building applications and computing?
I use some of these words differently to you. I don't think a 'program' is that same as an 'application', and I don't think that 'software/application development' is the same as 'programming' at all. So I agree with all the things you say, up to the quote, about applications and application development, but at some point in application development we need to do some programming and to me that is absolutely, positively, by definition, about code. Programming isn't the only thing that we do in application development, but it's an important thing and I think there is a tendency to devalue it; to treat it as a typing exercise in which all programs that perform the same function are treated as equally worthy (you didn't say this, but I hear it a lot). I think application development would benefit from improvements to many disciplines, but I feel that programming is one of the most neglected disciplines at all.
When we write a program we write for two very different audiences - the program needs to be understood by the computer, which is apparent when it does (or doesn't) perform the expected functions, but it also needs to be understood by human beings. Most of our effort currently goes into pleasing the computer, but in some sense this is the easier of the two audiences. Gabrielle is saying (and I agree strongly) that we need to put more of our effort into satisfying the human audience for code. I'll assert as a corollary that finding ways to make code more expressive to people will also make it easier to write code that satisfies the computer as well, but I can't offer a proof in a mathematical sense.
As to what are patterns, and the code in places like MSDN and most web sites (including this one), they bear the same relationship to great programming that a power tool catalogue has to great building. They're focussed predominantly on efficiency, and on satisfying the computer, not on the aesthetics of programming as it's experienced by a human being. Christopher Alexander presented a keynote at OOPSLA many years ago, which I had the honour of attending, at which he said that he was ashamed of the way that the software community had applied patterns; that the heart of his idea was creating environments that appealed to our humanity but that software patterns has been sterilised - stripped of aesthetics and reduced to the equivalent of screwdrivers (my words, not his, but I think I'm faithful to the intent). Show me an article, or rather not one exceptional article but a body of work, that addresses different ways to name variables within the same programming idiom to improve expressiveness, or how to write code that brings a smile to your face, and we'll be heading down the path that Gabrielle is talking about, and we'll have taken one tiny programmatic step towards Alexander's goals.
You once asked me in email why I went back to uni to study psychology - my reply should have been because I think it would make me a better application developer. If I wanted to become a better programmer I wouldn't choose psych, I'd choose creative writing and literature, and that I haven't speaks to lack of time and dedication to my craft, not to a lack of need.
Friday, April 13, 2007
RCov measurements
I'm busy setting up a Rails development project at a client site, and we've chosen to use rSpec for specification/testing, and rCov to report coverage. They work quite well together, but there's one caveat - classes that aren't loaded don't appear in the coverage report at all, so for a single class there's effectively no difference between 0% coverage (no tests at all) and 100% coverage. Of course this is an oversimplification, since Ruby loads files, not classes, but it's a good enough approximation on most projects, and there's clearly some sort of problem regardless of the details.
Our solution has been to force rSpec to load everything in app/models and app/controllers before the specs are run. We do this in the rspec_helper, and since this is loaded multiple times (on different paths) it's also useful to restrict this code so it only runs once.
First, here's the code that loads the models and controllers:
There are two things to note about this code:
Next, let's look at the code that we put in rspec_helper.
If we can't reference ForceLoader we load it and run it. Once the class is loaded the rescue code won't be invoked, so this ensures once only execution.
Hopefully this approach will give you more accurate coverage reports with minimal overhead - it's certainly uncovered at least one problem on our project so far. It can also be extended to cover other parts of your app in a fairly straightforward way.
Our solution has been to force rSpec to load everything in app/models and app/controllers before the specs are run. We do this in the rspec_helper, and since this is loaded multiple times (on different paths) it's also useful to restrict this code so it only runs once.
First, here's the code that loads the models and controllers:
class ForceLoader
def self.run
["models", "controllers"].each do | app_component |
directory = File.join(RAILS_ROOT, "app/") + app_component
Dir[directory + "/**/*.rb"].each { |file| require_dependency file }
end
end
end
There are two things to note about this code:
- we use require_dependency for consistency with other Rails loading, rather than require or load;
- we need to ensure that the path of the file passed to require_dependency is the same as the path used by default by Rails. Ruby loading is path passed, and if you refer to the same file with two different path representations you may load it twice.
Next, let's look at the code that we put in rspec_helper.
begin
ForceLoader
rescue
require File.dirname(__FILE__) + '/force_loader'
ForceLoader.run
end
If we can't reference ForceLoader we load it and run it. Once the class is loaded the rescue code won't be invoked, so this ensures once only execution.
Hopefully this approach will give you more accurate coverage reports with minimal overhead - it's certainly uncovered at least one problem on our project so far. It can also be extended to cover other parts of your app in a fairly straightforward way.
Saturday, March 31, 2007
Code Retrospectives
I bet that most of the people who read this blog have been through a code review at some point - a session where a bunch of people get together, look at a piece of code, identify all the things they consider problems and document them. Then the developer goes away and fixes all the problems.
Usually these reviews are relatively infrequent, time consuming, and exhausting. The focus is on finding errors and correcting them, and I know that when I was having my code reviewed this way I found the process quite stressful as well.
I think this model of reviews is pretty much broken. These days I want to get "code reviews" done at least a few times each hour, whether there's anyone else around or not, and the only way to get that is to use automation. In the Java world, tools like Checkstyle, Simian and Complexian provide a wealth of checks - far more than a human team could check in any reasonable amount of time. And despite the names these checks aren't just "style" checks - they help you enforce metrics thresholds as well (which is a separate discussion). Plus there's much less emotion associated with feedback from an automated tool, and the tool has infinite patience.
Once significant chunks of what's covered by traditional code reviews have been handed off to automated tools, the humans are free to use code reviews in a different way. Instead of looking for mistakes, the team can look for opportunities to learn. Accept that the code is the way it is, that everyone was doing the best they could at the time, and review the process that created the code rather than the code itself, all the way back to the root cause. Certainly you'll find some things in the code that must be fixed before you move forwards, but lots of things will be tolerable if you can fix the process so that they don't recur.
In this context, "process" is a broad term - it includes the way you hire people, the training you give them, the tools, the incentives, the requirements; anything that might impact the final code. The Toyota "Five Whys" can be a good way to get to the root cause. (make some note in here)
At this point we've transcended code reviews - what we're doing is far more like a retrospective, focussed tightly on our code. Although retrospectives are usually associated with ends of iterations and releases, we can use code retrospectives much more often.
So instead of treating your code reviews as opportunities to find the mistakes that your colleagues have made, switch to code retrospectives and improve the process that created the code.
Usually these reviews are relatively infrequent, time consuming, and exhausting. The focus is on finding errors and correcting them, and I know that when I was having my code reviewed this way I found the process quite stressful as well.
I think this model of reviews is pretty much broken. These days I want to get "code reviews" done at least a few times each hour, whether there's anyone else around or not, and the only way to get that is to use automation. In the Java world, tools like Checkstyle, Simian and Complexian provide a wealth of checks - far more than a human team could check in any reasonable amount of time. And despite the names these checks aren't just "style" checks - they help you enforce metrics thresholds as well (which is a separate discussion). Plus there's much less emotion associated with feedback from an automated tool, and the tool has infinite patience.
Once significant chunks of what's covered by traditional code reviews have been handed off to automated tools, the humans are free to use code reviews in a different way. Instead of looking for mistakes, the team can look for opportunities to learn. Accept that the code is the way it is, that everyone was doing the best they could at the time, and review the process that created the code rather than the code itself, all the way back to the root cause. Certainly you'll find some things in the code that must be fixed before you move forwards, but lots of things will be tolerable if you can fix the process so that they don't recur.
In this context, "process" is a broad term - it includes the way you hire people, the training you give them, the tools, the incentives, the requirements; anything that might impact the final code. The Toyota "Five Whys" can be a good way to get to the root cause. (make some note in here)
At this point we've transcended code reviews - what we're doing is far more like a retrospective, focussed tightly on our code. Although retrospectives are usually associated with ends of iterations and releases, we can use code retrospectives much more often.
So instead of treating your code reviews as opportunities to find the mistakes that your colleagues have made, switch to code retrospectives and improve the process that created the code.
Thursday, March 22, 2007
Drawing the reader in
I read a lot of material - some short, some long. A lot of it is mandatory work-related reading, so I can get quite selective about the remaining pieces - if you want me to read something, you need to convince me. I'm willing to give you some of my time upfront, but that may be less than 5 seconds (I kid you not). If what I read in that period seems interesting then I'll give you some more of my time, but even then my commitment isn't open ended; you need to continually convince me to keep going (at least until I can see the end in sight). So how do you do this?
You should be able to see the solution in a typical newspaper article. The article probably has this structure:
Each reader should be able to read until they've got the level of detail they need - they shouldn't be forced to read from beginning to end just to get an overview.
We have the same problems whenever we write a document presenting something complex (especially when we need someone to make a decision based on the material), and particularly when we write a resume. Make sure that the first few paragraphs contain some sort of summary, something that will convince the reader that it's worth continuing. If a resume starts with the details of the candidates current job, it better be a very interesting job, and if I'm your reader you've got less than 5 seconds to convince me. Bullet points are easy for me to scan in that time; dense text isn't. As you increase my interest and commitment, you can be more demanding of me and I'll be more tolerant.
When you're working on the web you have other structure you can work with as well. Maybe you can build something with Javascript so that the details are available only when the reader asks for them; in that case you don't need to adopt the linear, gradual descent style of the newspaper, you can make the details available wherever they're needed. You can also present sidebars, summaries and pictures that might not have a place in a text only, paper based document.
You may or may not need to give the reader a sense of closure. If you need a decision or an action, you need to make that clear early on, but you should also restate it at the end of the work. You might also benefit from a summary of the main points, related back to the original introduction. But for something like a resume you can probably get away with "here are the rest of the details" - it's expected, and the reader knows they'll only be interested in some of it, but you still should make it easy to pick one point from another.
Be conscious of this approach - see if you can spot in what you read, and bear it in mind when you're writing. Eventually you'll refine it until the transitions are seamless, and your reader will never know why they find your work so interesting!
You should be able to see the solution in a typical newspaper article. The article probably has this structure:
- the impact of the story is captured in the headline;
- the first paragraph gives a summary of the whole story;
- the next few paragraphs expand on the first paragraph, but still omit details;
- the details are contained in the main body of the article
Each reader should be able to read until they've got the level of detail they need - they shouldn't be forced to read from beginning to end just to get an overview.
We have the same problems whenever we write a document presenting something complex (especially when we need someone to make a decision based on the material), and particularly when we write a resume. Make sure that the first few paragraphs contain some sort of summary, something that will convince the reader that it's worth continuing. If a resume starts with the details of the candidates current job, it better be a very interesting job, and if I'm your reader you've got less than 5 seconds to convince me. Bullet points are easy for me to scan in that time; dense text isn't. As you increase my interest and commitment, you can be more demanding of me and I'll be more tolerant.
When you're working on the web you have other structure you can work with as well. Maybe you can build something with Javascript so that the details are available only when the reader asks for them; in that case you don't need to adopt the linear, gradual descent style of the newspaper, you can make the details available wherever they're needed. You can also present sidebars, summaries and pictures that might not have a place in a text only, paper based document.
You may or may not need to give the reader a sense of closure. If you need a decision or an action, you need to make that clear early on, but you should also restate it at the end of the work. You might also benefit from a summary of the main points, related back to the original introduction. But for something like a resume you can probably get away with "here are the rest of the details" - it's expected, and the reader knows they'll only be interested in some of it, but you still should make it easy to pick one point from another.
Be conscious of this approach - see if you can spot in what you read, and bear it in mind when you're writing. Eventually you'll refine it until the transitions are seamless, and your reader will never know why they find your work so interesting!
Thursday, March 15, 2007
Building a store
I just finished watching the video of Building the Store from ClickableBliss, which explains why Mike Zornek build his own web store, and what he learned.
My notes from the presentation:
Sorry if I'm cryptic - the video is worth watching :-)
My notes from the presentation:
- ELC Technologies RoR::PayPal - not a complete interface, doesn't provide express checkout, which is essential
- vPayPal gem : never got it to work, seemed to have deficiencies, used as a reference
- Tobias Lutke's PayPal gem - not specific to websites payment pro, related to instant payments
- ActiveMerchant : couldn't get certain things related to PayPal to work, code submitted by contributor, not maintained. But it's now 1.0 and may work better.
- SOAP : not used SOAP before, but was the eventual solution
- These experiences were from about August 2006.
- If you're going to accept confidential information in a Rails application, make sure you don't log it:
class ApplicationController < ActionController::Base
filter_parameter_logging "password"
filter_parameter_logging "credit_card"
end
Sorry if I'm cryptic - the video is worth watching :-)
Subscribe to:
Posts (Atom)
