Ages ago in "Code and other Laws of Cyberspace" the idea of "The New Chicago" is mentioned. It says that behaviour is regulated by four things: the market, the law, social norms and architecture (or nature, the world you are in). In the original context it is described as a way that behaviour is limited in cyberspace and society and that the law can effect the other three to cause indirect behavourial change.
It seems equally appropriate in the context of a project. There are ideas that you can apply in a project that are (or at least should be) constrained in the same ways: laws, markets, social norms and architecture. In a project each constraint does not seem to have an equal effect on the smooth running of a project (they certainly could of course).
Laws don't usually have an impact on the constraints of a project. While people may break the law during the project or whatever and may have to go to court, get arrested, etc. the impact, at least in the projects I've been in, are quite minimal. They may effect certain requirements on the project (compliance to certain laws for instance) but generally they are well known or least able to be handled in a fairly straight-forward manner. No one generally argues whether a certain law should be abided by and usually people are available to ensure that the laws are readily adhered to.
Similarly, market forces have only a few effects on project cohesion as many decisions are already made for you - language, operating system and other infrastructural decisions are not usually up for grabs in a project. While some people may wish to do C# on Linux or Ruby instead of Java most people and projects limit scope in this way and resources are usually selected (or self-selected) on this basis. You don't usually find a .NET programmer amongst 10 Java programmers trying to convince them that Microsoft is the way to go.
The two key areas that do seem up for grabs and do cause problems are with norms and architecture.
The type of teams really dictate the level at which these two things can change and the methodology you use to achieve it. A well run XP project seems to allow a more participatory effect (mainly through pairing and pair swapping). If new ideas are accepted and tried then overall the team seems to have more of say. Certainly, the norms imposed on individual developers seems much higher in an XP project.
The opposite effect, somewhat of a project anti-pattern, is where a developer (or worse more than one) will go off and find a proposed solution and try to apply it to the entire project using a different norm or architecture. The rest of the team, quite rightly, does not feel ownership of the new technique or code. The effect of this is the opposite of what XP is trying to achieve - code ownership and cohesion. The key pushback to this is that no code goes into the project unless it has been paired on. If it is a project that does require a lot of investigation then each member of the team should get the ability to devise a solution to be considered.
There is of course limits placed on any project to change - moving languages or paradigms (OO, procedural, functional, etc) that XP has to abide by too. But in some ways XP seems much more honest (or from some perspectives limited) especially considering the "Extreme Programming Bill of Rights" where these kinds of changes will effect estimates, quality and progress.
Showing posts with label xp. Show all posts
Showing posts with label xp. Show all posts
Sunday, July 02, 2006
Wednesday, June 28, 2006
Agile Anchors
XP2006 Patterns lists a summary of experiences in adopting agile development practices including anti-patterns: Unpaid Debt, Lots of Bugs Found by Customer. Some metrics to help drive agile software development with this not so contraversial claim, "Code coverage metrics measure the percentage of methods and classes under test. Developers should strive for 100% test coverage on classes that are behaviorally intense. The CCN can be used as a baseline for the number of tests required per method. If a method has CCN of three, a good starting point to exercise all paths through code would be three tests. Additional tests may be required that exercise error conditions and alternate behaviors. A robust suite of unit tests provides the courage necessary to refactor." Also mentioned, in "Examining Test-Driven Development, "The reality is that your unit tests form a large part of your design specification, and similarly acceptance tests form a portion of your requirements specification..."
Wednesday, June 21, 2006
Test First Saves Time
To obtain good code, writing tests and code is faster then code alone "Ron Jeffies, one of the XP gurus stated that "in order to obtain good code, writing tests and code is faster then just code". To find out if this is true or not let's make a small experiment."
Tuesday, May 23, 2006
Keep it on the Green
Recently, Martin Fowler updated his Continuous Integration paper, "For most projects, however, the XP guideline of a ten minute build is perfectly within reason. Most of our modern projects achieve this. It's worth putting in concentrated effort to make it happen, because every minute you reduce off the build time is a minute saved for each developer every time they commit. Since CI demands frequent commits, this adds up to a lot of time."
"The commit build is the one that has to be done quickly, as a result it will take a number of shortcuts that will reduce the ability to detect bugs. The trick is to balance the needs of bug finding and speed so that a good commit build is stable enough for other people to work on."
"A simple example of this is a two stage build. The first stage would do the compilation and run tests that are more localized unit tests with the database completely stubbed out. Such tests can run very fast, keeping within the ten minute guideline. However any bugs that involve larger scale interactions, particularly those involving the real database, won't be found. The second stage build runs a different suite of tests that do hit the real database and involve more end-to-end behavior. This suite might take a couple of hours to run."
Breakage patterns for a build is listed in, "Avoiding Continuous Integration Build Breakage Patterns" it includes: "Five O'clock Check-In", "Spoiled Fruit" and "It Is a Small Change".
The overall effect of having a slower build is that tested user visible functionality becomes more difficult over time. Each new high level test increases the build time and understanding what has broken takes longer. Often time is not taken to ensure that your faster atomic/unit/integration tests cover what was missing. So the importance of maintaining a green build when you have worse feedback becomes more important but the cost of maintaining it becomes more expensive.
Some of the discussion that I've had is on this thread on the boost mailing list.
"The commit build is the one that has to be done quickly, as a result it will take a number of shortcuts that will reduce the ability to detect bugs. The trick is to balance the needs of bug finding and speed so that a good commit build is stable enough for other people to work on."
"A simple example of this is a two stage build. The first stage would do the compilation and run tests that are more localized unit tests with the database completely stubbed out. Such tests can run very fast, keeping within the ten minute guideline. However any bugs that involve larger scale interactions, particularly those involving the real database, won't be found. The second stage build runs a different suite of tests that do hit the real database and involve more end-to-end behavior. This suite might take a couple of hours to run."
Breakage patterns for a build is listed in, "Avoiding Continuous Integration Build Breakage Patterns" it includes: "Five O'clock Check-In", "Spoiled Fruit" and "It Is a Small Change".
The overall effect of having a slower build is that tested user visible functionality becomes more difficult over time. Each new high level test increases the build time and understanding what has broken takes longer. Often time is not taken to ensure that your faster atomic/unit/integration tests cover what was missing. So the importance of maintaining a green build when you have worse feedback becomes more important but the cost of maintaining it becomes more expensive.
Some of the discussion that I've had is on this thread on the boost mailing list.
Tuesday, April 11, 2006
Optimal Pair Swapping: 90 minutes
Promiscuous Pairing and Beginner’s Mind: Embrace Inexperience "It often takes days for a given pair to be comfortable enough with each other to be able to achieve Pair Flow at all. This means that pairings tend to be long. The longer the mean time between pair swaps, the less effectively pair net distributes information through the team."
"While two people are paired, they share knowledge. When the pair splits for a pair swap, the knowledge then spreads to all four participants. In this way, knowledge will slowly but automatically spread around the group."
And the surprising result:
"This makes it easy to see the shape of the curve near the 90-minute optimal point. However, we did note that longer pair times had slightly higher mean velocities."
So you think you're doing extreme XP and someone always has to crank it up one more level. 90 minutes seems pretty close to me to be the minimum period of time to actually get a chunk of work done - considering that getting work done by yourself usually requires an hour.
I was actually looking for evidence that pair programming's flow state is better/worse than normal. Specifically,
"While two people are paired, they share knowledge. When the pair splits for a pair swap, the knowledge then spreads to all four participants. In this way, knowledge will slowly but automatically spread around the group."
And the surprising result:
"This makes it easy to see the shape of the curve near the 90-minute optimal point. However, we did note that longer pair times had slightly higher mean velocities."
So you think you're doing extreme XP and someone always has to crank it up one more level. 90 minutes seems pretty close to me to be the minimum period of time to actually get a chunk of work done - considering that getting work done by yourself usually requires an hour.
I was actually looking for evidence that pair programming's flow state is better/worse than normal. Specifically,
- How much more or less is "pair flow" susceptible to interruptions,
- Whether pairs are able to resume, after interruption, more quickly into a shared flow state,
- Whether it's faster or slower to get into a "pair flow" state, and
- The effects experience has on the above.
Even Flow
"Flow is a mental state of operation in which the person is fully immersed in what he or she is doing, characterized by a feeling of energized focus, full involvement, and success in the process of the activity. Proposed by psychologist Mihaly Csikszentmihalyi, the concept has been widely referenced across a variety of fields."
Alister Cockburn's Team Per Task, "It takes about 20 minutes to reach this state of flow, and only a minute to lose it. Our designers found that it took about an hour to get into flow and make progress after having been stopped. If a meeting or other task arrived during this hour, the entire period was essentially lost. As it also took energy to get into the flow, a distraction cost but energy as well as time."
Pairing to to the rescue (again). When a pair gets into a flow it's more resilient to distractions - it seems to allow one person in the pair to get back into it more quickly after being distracted. Maybe it is related to mirror neurons (video).
Alister Cockburn's Team Per Task, "It takes about 20 minutes to reach this state of flow, and only a minute to lose it. Our designers found that it took about an hour to get into flow and make progress after having been stopped. If a meeting or other task arrived during this hour, the entire period was essentially lost. As it also took energy to get into the flow, a distraction cost but energy as well as time."
Pairing to to the rescue (again). When a pair gets into a flow it's more resilient to distractions - it seems to allow one person in the pair to get back into it more quickly after being distracted. Maybe it is related to mirror neurons (video).
A Point of Difference
Reading, "Organizational Patterns of Agile Software Development" it suggests code ownership because "Something that is everybody's responsibility is really no one's responsibility". He does note some concerns related to one owner of the code including, "...tunnel vision, the implied risk of having only a single individual who understands a piece of code in depth, and a breakdown of global knowledge." as well as the bus factor and introduction of bottlenecks.
This disagreement between XP and Coplien's agile software development was noted by Kent Beck in a 1999 interview: "KB: I was talking about it with Cope [Jim Coplien] yesterday; this is our favorite fighting topic. The rule is, if you see a problem with code anywhere in the system, you fix it. So we’re sitting there with our DB40 transactions, and we say, “Y’know, if this export object over here was just structured this way, it would be really easy for us to do our stuff.” If it would clean things up else-where, we just do it."
"JV: So anybody can change anything, anywhere…
KB: Yup, absolutely. If you see it, and you got your partner there, and you’re going to run the tests within a few minutes—so it’s not like you’re going to break something—you just do it. And the system’s going to get better.
Now, I came up with this because I was working in strict individual code ownership shops, and we’d say, “Gee, we keep calling these same three methods in this object. Why don’t we just make a method in the object that calls the three methods for us?” “We don’t own that.” “But the guy’s just across the hall—” “Naah, don’t wanna bother him.”
The pace of evolution in projects that use individual code ownership, in my experience, is glacial compared to what is possible to do, in a controlled way, if everybody takes responsibility for making all the code as good as they can make it."
"JV: Has this been without pitfall?
KB: Yes. It’s just not a problem. You’ve got to have collective ego instead of individual ego. That’s the hardest problem, so that no one comes up and says, “Hey man, you changed my class.” "
See also: Ron Jefferies' Code Ownership and a list different kinds of code ownership.
This disagreement between XP and Coplien's agile software development was noted by Kent Beck in a 1999 interview: "KB: I was talking about it with Cope [Jim Coplien] yesterday; this is our favorite fighting topic. The rule is, if you see a problem with code anywhere in the system, you fix it. So we’re sitting there with our DB40 transactions, and we say, “Y’know, if this export object over here was just structured this way, it would be really easy for us to do our stuff.” If it would clean things up else-where, we just do it."
"JV: So anybody can change anything, anywhere…
KB: Yup, absolutely. If you see it, and you got your partner there, and you’re going to run the tests within a few minutes—so it’s not like you’re going to break something—you just do it. And the system’s going to get better.
Now, I came up with this because I was working in strict individual code ownership shops, and we’d say, “Gee, we keep calling these same three methods in this object. Why don’t we just make a method in the object that calls the three methods for us?” “We don’t own that.” “But the guy’s just across the hall—” “Naah, don’t wanna bother him.”
The pace of evolution in projects that use individual code ownership, in my experience, is glacial compared to what is possible to do, in a controlled way, if everybody takes responsibility for making all the code as good as they can make it."
"JV: Has this been without pitfall?
KB: Yes. It’s just not a problem. You’ve got to have collective ego instead of individual ego. That’s the hardest problem, so that no one comes up and says, “Hey man, you changed my class.” "
See also: Ron Jefferies' Code Ownership and a list different kinds of code ownership.
Thursday, March 09, 2006
Graphing Gaffs
Five Signs of Trouble in an Iteration "During the course of an iteration, an agile team is able to track it's own progress through the use of burndown charts. The team and the process facilitator can use the burndown chart to watch for signs of trouble. As a coach, I find the following five burndown shapes are common indicators of trouble."
The sixth one I would put down to doing work, like refactoring, test utilities and the like, and then making the expected work less.
The sixth one I would put down to doing work, like refactoring, test utilities and the like, and then making the expected work less.
Wednesday, March 08, 2006
More on Benefits of Pair Programming
A slight dated bibliography on Pair Programming.
A Pair Programming Experience "The error analysis showed the project had achieved an error rate that was three orders of magnitude less than normal for the organization. Integration of the first two components (approximately 10,000 source lines) was completed with only two coding errors and one design error. The third component was integrated with no errors. The remaining three components had more errors, but the number of errors for these components was significantly less than normal."
Also, linked via Pair Programming.com.
A Pair Programming Experience "The error analysis showed the project had achieved an error rate that was three orders of magnitude less than normal for the organization. Integration of the first two components (approximately 10,000 source lines) was completed with only two coding errors and one design error. The third component was integrated with no errors. The remaining three components had more errors, but the number of errors for these components was significantly less than normal."
Also, linked via Pair Programming.com.
Wednesday, March 01, 2006
XP Sunscreen
The New XP "...nature continuously uses fractal structures, which are similar to themselves but at various scales. The same principle should be applied to software development: we should be able to reuse similar solutions, in different contexts."
Or as Greg says, "Only by pursuing code reuse in the small will you ever achieve code
reuse in the large."
"Software defects must be looked for, found and fixed in many ways (pair programming, automated testing, sit together, real customer involvement, etc.). This is redundant, because many defects will be found many times. However, quality is priceless."
"...quality must be always at maximum. Accepting a lower quality does not yield neither savings, nor faster development. On the contrary, improving quality necessarily makes an improvement of other system features, like productivity and efficiency. Moreover, quality is not only an economic factor. Team members must be proud of their work because it improves team self-esteem and effectiveness."
"It is easy to order to developers “Do this”, or “Do that”, but it does not work. Unavoidably, you ask less than what could be achieved or, more likely, more than that can be accomplished."
Or as Greg says, "Only by pursuing code reuse in the small will you ever achieve code
reuse in the large."
"Software defects must be looked for, found and fixed in many ways (pair programming, automated testing, sit together, real customer involvement, etc.). This is redundant, because many defects will be found many times. However, quality is priceless."
"...quality must be always at maximum. Accepting a lower quality does not yield neither savings, nor faster development. On the contrary, improving quality necessarily makes an improvement of other system features, like productivity and efficiency. Moreover, quality is not only an economic factor. Team members must be proud of their work because it improves team self-esteem and effectiveness."
"It is easy to order to developers “Do this”, or “Do that”, but it does not work. Unavoidably, you ask less than what could be achieved or, more likely, more than that can be accomplished."
Wednesday, February 22, 2006
Boost
For a little while I've had this idea to create an open source library for utilities used for test driving. It seems that I'm not alone in this and recently the Boost library was made available. You can download the JAR (boost/boost) from the latest build.
For an even more eXtreme view, ContractualJ. Includes: all constructors are declared private and throw java.lang.UnsupportedOperationException, unless they are implicit constructors of anonymous classes and all contracts (interfaces) declare one (and only one) operation, unless they are composite interfaces, in which case, they make an effort to approach "Perfect Symbiosis of Contractual Operations" (to be defined). The only reference I found via Google was "How many bad ideas at once?" - an uninteresting post with some interesting discussion.
For an even more eXtreme view, ContractualJ. Includes: all constructors are declared private and throw java.lang.UnsupportedOperationException, unless they are implicit constructors of anonymous classes and all contracts (interfaces) declare one (and only one) operation, unless they are composite interfaces, in which case, they make an effort to approach "Perfect Symbiosis of Contractual Operations" (to be defined). The only reference I found via Google was "How many bad ideas at once?" - an uninteresting post with some interesting discussion.
Saturday, January 21, 2006
Mocking Correctly
A really great posting, "Best and Worst Practices for Mock Objects" lists a number of best practices for mocking.
A few more occurred to me:
The previous post in the series, "Why and When to Use Mock Objects" lists what makes a good unit test including: being atomic, order independent and isolated, intention revealing, easy to setup (a unit test code smell is a lot of setup code) and runs fast.
There also looks like a really interesting site, Test Automation Patterns. It lists test code smells including: test code duplication is bad, obscure tests, and data sensitivity. Also, a list of fixture strategies: standard, fresh and shared.
- "Be careful about mocking or stubbing any interface that is outside your own codebase. If you don’t truly understand the semantics and proper usage of an interface you don’t have any business mocking that interface in a unit test. My best advice is to create your own interface to wrap the interaction with the external API classes."
- "My advice is to just test the data access code against the actual database with integration tests. For the most part I think testing persistence code without the database is a complete waste of time."
- "I’ve worked with some people before that felt that there should never be more than 1-2 mock objects involved in any single unit test. I wouldn’t make a hard and fast rule on the limit, but anything more than 2 or 3 should probably make you question the design...Minimizing the number of mock objects necessary for any given unit test is a very effective way of keeping the Cyclomatic Complexity of your classes below an acceptable level."
- "Ideally you only want to mock the dependencies of the class being tested, not the dependencies of the dependencies. From hurtful experience, deviating from this practice will create unit test code that is very tightly coupled to the internal implementation of a class’s dependencies."
A few more occurred to me:
- Use as many patterns and idioms in your unit tests that you do in regular code, like testing exceptions and fixtures. This can be a great way to reduce the drudgery of testing bean objects for instance (not that I in anyway condone the use of bean objects).
- Allow reuse of commonly used objects between tests.
- The length and complexity of a unit tests is an indication of the complexity of the underlying object - once a test reaches a certain length/complexity it's time to refactor the object being tested.
- Duplication in tests is just as bad as duplication in the code being tested.
- No code goes into production just for the sake of testing.
- Use reflection to gain access to internal object state. This is related to the previous point as a way to avoid artifacts of testing in production code. Other ideas include a good equals method, package level access and getter methods - but these leave code that may only exist for testing. And the last two are also a good way to break encapsulation.
- Something that is easy to test is not always good design. For instance, having a fixture or utility code that makes bean objects easy to test drive shouldn't dictate using bean objects for everything.
The previous post in the series, "Why and When to Use Mock Objects" lists what makes a good unit test including: being atomic, order independent and isolated, intention revealing, easy to setup (a unit test code smell is a lot of setup code) and runs fast.
There also looks like a really interesting site, Test Automation Patterns. It lists test code smells including: test code duplication is bad, obscure tests, and data sensitivity. Also, a list of fixture strategies: standard, fresh and shared.
Subscribe to:
Posts (Atom)