tag:blogger.com,1999:blog-72202814414853434072024-02-19T14:31:59.214+11:00If life were a game...About stuff I like and you should like moreAnonymoushttp://www.blogger.com/profile/06445330508811625525noreply@blogger.comBlogger53125tag:blogger.com,1999:blog-7220281441485343407.post-19757907054722003372018-08-25T22:13:00.002+10:002018-08-25T22:13:39.509+10:00I've started a new blog sitePlease go to <a href="http://team-agile.com/">http://team-agile.com</a> for my latest posts. Thank you!Anonymoushttp://www.blogger.com/profile/06445330508811625525noreply@blogger.com0tag:blogger.com,1999:blog-7220281441485343407.post-17517924973145638562017-08-29T09:58:00.003+10:002017-08-29T09:58:28.836+10:00Coaching is a transferable skillIt's been interesting over the last year for me as I explore where coaching for software teams and coaching for sports people overlaps. This year I got to be coach for a Roller Derby team which is the first time I've called myself a coach for more than a brief workshop. In my day job I'm involved in many activities that have nothing to do with coaching so I rarely call myself an Agile Coach. But to that sports team I am <b>the</b> coach. And while I've been involved with Roller Derby for 5 years I have very little training in coaching sports teams so I started applying all the things I've learned coaching software teams.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBqOEie90GRTj7m4Mdj44STEODL8f4D_e5EZFbt1W6da2Nfuo_Se0GVRVHFj0zko8PiUxklbBiQlKIGda_YLTefzHwqGmNIAJE-n0q0Y9dEzkWoXwxke04UzciFzzMa00p_ENVOLiSdUw/s1600/18268648_10156223182554698_4675401471132370682_n.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="684" data-original-width="684" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBqOEie90GRTj7m4Mdj44STEODL8f4D_e5EZFbt1W6da2Nfuo_Se0GVRVHFj0zko8PiUxklbBiQlKIGda_YLTefzHwqGmNIAJE-n0q0Y9dEzkWoXwxke04UzciFzzMa00p_ENVOLiSdUw/s320/18268648_10156223182554698_4675401471132370682_n.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The Empire - Roller Derby team</td></tr>
</tbody></table>
<br />
<b>We built a manifest of shared goals</b><br />
I can't take all the credit for this one as the team created one before I joined them as coach. But I couldn't be more happy with it as that was one of my first goals. I wanted something that helped defined who we are as a team distinct from other skaters and teams. I also wanted to spell out what our values were to make it clear what my coaching goals should be and should not be. The team wanted to be <i>taken seriously as a competitive team</i>. They also wanted to <i>value the contribution of every team member equally</i>. I've experienced similar goals with software teams that were trying to come out of obscurity or a position where they felt they were not getting respected by the larger organisation.<br />
<br />
<b>We frequently inspected and adapted</b><br />
Often at the end of doing a drill I would bring people together to discuss what was working for them and what wasn't. Experimentation at training is actively encouraged as we try things out as individuals and as a team to see if something new is a better fit. Then after a game we will again talk about what was working and what didn't during the game. What are we doing well that we should do more of? I try to embrace what Woody Zuill calls "Turning up the good" to keep building a positive message rather than focusing too much on our weaknesses. I never called it a retrospective but in my head that's what I was facilitating.<br />
<br />
<b>I would embrace feedback and adjust my own actions</b><br />
Sometimes during a drill an experienced skater would say something to me like "They're not doing X"or "We need to focus on Y to get this right". So I'd take than on board and sometimes use that in our very next drill. It's not a criticism of me or the people they are observing. It's an observation on what we could be doing better so let's do that now!<br />
<br />
<b>I would observe where the team is at to direct what to work on next</b><br />
It can be very tempting to look at the plays top level teams do and ask your team to try and do that. But it's too much too quickly. Where are they at skill wise? What small steps can they make to get a little better? What strengths can they leverage to help them get there? It meant sometimes ignoring feedback from experienced people as they would want people doing the high level skills they have already mastered. But the team as a whole may not be ready for something that advanced and needs to build up towards it.<br />
<br />
<b>Sometimes it's valuable to just practice basics as a team</b><br />
Just like you can use a programming Kata to get a team learning TDD, Pair programming or Mob programming. Going through basic drills as a team helps a group of individuals adjust to being a team. There was only a handful of people that came with the team from last year so for most it was a big adjustment. And I've seen with software teams that even changing one person can have a huge impact on the dynamics within a team. Give them a safe space to explore those new dynamics and figure out how to best make it work.<br />
<br />
<b>Happiness is a leading indicator</b><br />
I never enforced attendance or got angry at people for being late. No one was being paid to be there so I knew it was important to keep things fun and rewarding. But for me it was also an important indicator of where people where at. If someone stopped coming to training I could ask them if anything was wrong offline and see if there was anything within the team I needed to address. If a things dropped back more generally then I could try and find out if there was something in the team or about the training that was putting people off.<br />
<br />
I would definitely recommend any Agile coach try their hand at coaching in a different field. The differences and similarities can help inform how you approach coaching in general. I've also found it useful to talk to other sports people about where these practices overlap. Training an experienced athlete is often asking a series of questions to open their mind to ideas. Much like coaching experienced developers.Anonymoushttp://www.blogger.com/profile/06445330508811625525noreply@blogger.com0tag:blogger.com,1999:blog-7220281441485343407.post-54158522902835433522017-06-06T14:03:00.002+10:002017-06-06T14:04:31.988+10:00What role are your tests serving.We had a discussion at work after watching the excellent <a href="https://www.youtube.com/watch?v=azoucC_fwzw">Kelvin Henney talk about good unit tests</a>. And it helped me clarify the many roles tests play and why people get a habit of complaining about their tests getting in the way. So here is the four categories a test is trying to balance:<br />
<br />
<br />
<ul>
<li>Requirements</li>
<li>Regression</li>
<li>Documentation</li>
<li>Refactoring guide</li>
</ul>
<br />
<br />
Most test today are written as <b>requirements</b>. And this is a huge improvement over the past when we'd write tests later and try and get code coverage. Those 'later' tests are useless. The requirement tests happen for high level acceptance tests and in low level TDD too. Your test defines a behaviour you want. Once your test passes you don't go back to change it at all beyond some obvious cleanups like code duplication. These tests allow rapid development and reliable progress. But they can hinder refactoring, provide poor feedback on failures for regression and may be too implementation focused to be readable.<br />
<br />
And easy correction is to make tests act as good <b>documentation</b>. Unit tests should explain component behaviour to other programmers. Think of it as the <i>examples</i> section in your book that any programmer is going to flip to and read first. Higher level tests can use BDD, tables or other techniques to create highly readable descriptions that can be shared with your product owner or customer. One thing you'll notice if you try and make unit tests act as good documentation is you'll want to avoid the london-style or mockist style test where every secondary object is mocked out. All those mocks heavily hinder the tests being a document as it shifts away from being an example of how the code runs on the product.<br />
<br />
You may think all those requirements focused tests are all you need to cover the <b>regression</b> case. But for good regression tests you want highly informative error messages. I find those get introduced later when you start seeing such failures. That might be when a bug is introduced or a new feature makes old tests inaccurate. That's a good time to go back through those assert statements and make sure they give enough information to know how to correct it. As once corrected those asserts will benefit you ever after. There are also some frameworks that can help like the highly informative asserts from py.test.<br />
<br />
Unit tests are your best guide for <b>refactoring</b>. So you want a complete suite of tests that run <i>very</i> fast. That way you can change a line of code and know within a few seconds if that change is okay. Higher level tests are helpful too in that you could replace an entire component (perhaps something custom with something off-the-shelf) and see everything still works. Can you replace your database with confidence? That's the kind of feedback high level tests can give to help refactoring.<br />
<br />
So a single test <i>can</i> satisfy all four of these needs. But it doesn't need to so it's better to figure out where the focus is for the test you are writing at the time. Some tests might only be there for documentation. It's okay for tests to evolve to help refactoring only when you need that refactoring. But don't assume that once a test is passing that it automatically ticks all these boxes. It's just a check at that point.Anonymoushttp://www.blogger.com/profile/06445330508811625525noreply@blogger.com0tag:blogger.com,1999:blog-7220281441485343407.post-4354731567110819912017-05-25T12:15:00.003+10:002017-05-25T12:18:01.855+10:00When Agile is not common senseIt's been about 8 years since I got my Agile training from <a href="https://wingman-sw.com/">James Grenning</a> and started an Agile Pilot with my team. Right from the start I was super keen and got people practising TDD and Pair Programming even though I didn't really know if that effort would pay off. I just knew we had lots of problems with the old way so I wanted to embrace the new.<br />
<br />
So I'd run my own little sessions with the broader team in Sydney sharing Agile concepts and ideas. Giving us a chance to discuss things and keep learning long after James had left. But often I would present new ideas and a few people in the group would respond "oh of course, that's just common sense". Initially I thought it was great as they were embracing these ideas as valuable even though it was not what we were doing before. But after a while I started to get frustrated because they we're not really listening. If some small part of a concept fit nicely with their "common sense" then they took that on and ignored the rest.<br />
<br />
For example I'd point out that Agile asks us to plan regularly but to never put too much value into any plan. You need to be prepared to throw out your plan from yesterday because you learned something new today. "Oh of course, that's just common sense." But what I'd observe is they didn't re-plan regularly, they would just stick to the old plan unless something was clearly going wrong, and only then would re-plan in an attempt to react. They didn't adopt the new idea as they didn't understand that it's about being proactive. They didn't understand the value in making continuous minor adjustments or even just discussing how their understanding has shifted over time.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivyasid_VrUJUiscor9-yVTIWE5_fTUVdfkdgd9MjWc2Waj3Bhyh1yM1fjXXq2YwXed8FRtgtL8h6JQrjUDn4e2aiZsPisa8b_Ydx-yO6hDkBANdMiDDWcsHQi4hw2oAx5IJRljYOxD8w/s1600/dt_c111126.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="375" data-original-width="1200" height="100" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivyasid_VrUJUiscor9-yVTIWE5_fTUVdfkdgd9MjWc2Waj3Bhyh1yM1fjXXq2YwXed8FRtgtL8h6JQrjUDn4e2aiZsPisa8b_Ydx-yO6hDkBANdMiDDWcsHQi4hw2oAx5IJRljYOxD8w/s320/dt_c111126.gif" width="320" /></a></div>
<br />
<br />
So I did a presentation to them about when Agile is not common sense. Put out the ideas that clearly challenged their old thinking and through that made my case that they allow other ideas to challenge them too. My list has grown over the years and it's still something I refer to when I feel people are being to complacent.<br />
<br />
<b>TDD</b><br />
We all understand the value in having tests. But writing a test before there is any code? Writing a test before we have a clear picture of what we're building? TDD should challenge the way you learned to program.<br />
<br />
<b>Pair Programming</b><br />
Two heads are smarter than one. But we all assume it'll be the same speed as just 1 person so under value the benefits. But in studies we find that, with practice, the speed increases by quite a lot. Most of programming is not typing it's thinking about the problem. The same is true for creating tests in that typing is a very small part of the time spent. With practice we see pairs operate at about 1.8x the speed of an individual while also having 50% fewer bugs.<br />
<br />
<b>Mob Programming</b><br />
See pair programming<br />
<br />
<b>No Estimates</b><br />
Estimates can be a dysfunction. Is someone asking for a completion date or trying to figure out a cost, plan a release or looking for a deadline to enforce. Move the conversation away from estimates as much as possible.<br />
<br />
<b>If something is difficult or error prone then do it more often</b><br />
Teams will often avoid doing a minor release due to headaches in the release process. A good coach will then insist that releases be daily until release issues are resolved. It applies to many areas where we avoid facing issues rather than fixing them.<br />
<br />
<b>Maximise the work not done</b><br />
We want to work on a prioritised list so that we can avoid doing things that have little value. Sure the customer says they want A, B & C but if C will help them immediately then do that and give them the software before working on A & B. You might find out that with C fixed that B drops from being the second most important feature to no longer being required.<br />
<br />
<b>Safe to fail</b><br />
Encourage teams to challenge themselves and occasionally fail. If the team never fails then how do you know they are actually trying to improve? If treat everything as so important you cannot risk failure then you do not allow improvement. So you are not allowing teams to operate at their best when you demand only the best.<br />
<br />
<b>Having a detailed and complete test suite allows quicker changes to your code</b><br />
Many with only a little experience at writing tests would disagree. The tests break in confusing ways. Changes to the software trigger many required changes in the tests. But really that's just changing code with poor tests that are too tightly coupled and fail in bad ways.<br />
<br />
That's my list for now. As an aside it's worth remembering that <i>common sense</i> is cultural and really just wraps up a lot of assumptions we share. I do this contrast more to challenge people's thinking than really seeing a lot of value in something being <i>common sense</i> or not. When we start thinking of something as <i>common sense</i> we assume others know it and that's an unhelpful assumption.Anonymoushttp://www.blogger.com/profile/06445330508811625525noreply@blogger.com0tag:blogger.com,1999:blog-7220281441485343407.post-75593618700715125852017-05-11T16:11:00.002+10:002017-05-11T16:11:31.591+10:00Applying the Toyota KataLast year I got to attend a workshop on the <b>Toyota Kata</b> by <a href="https://hakanforss.wordpress.com/">Hakan Forss</a> and I could immediately see how it could be useful but I didn't have an obvious place to apply it until recently.<br />
<br />
So what is the Toyota Kata? I see it as an alternative to retrospectives. It lets you define a collection of goals and run experiments to see if you can get progress towards that goal. Unlike retrospectives you can define goals that may seem distant (release to customers on every passing commit), may be simply something you want to maintain (have zero bugs in production) or be impossible (have zero wait time in moving a story from backlog to done). Once you've built this collection of measurable goals you decide what you're going to try and your expected outcome (we will to TDD and have 50% less bugs in production). You can define what the period is before you check in again and decide on the next step. But as with anything Agile; shorter is better. You can work it into a normal two week scrum cycle or if improvements are important enough then spend a small time on it every day. Next time you get together you can assess how the experiment(s) did and what you want to try and do next.<br />
<br />
I really like how it's focused on doing small experiments rather than committing yourself to something to <i>fix</i> the problem immediately. Especially for those big issues it frees you up to try anything because you'll know soon if it helped and can try something else. With normal retrospectives it can be hard to get people to conduct experiments.<br />
<br />
So my team recently went from doing 2 week sprints to a Kan-ban style flow of work. I had some concerns that it could lead to a range of problems and wanted it to be a positive change, So we figured out some measurable goals where we wanted improvement and things we to maintain. The improvement ended up being focused around cycle time as I felt sprints encouraged us to get things <i>done</i> because a sprint was ending even though it's an artificial deadline. If a task lasted more than a sprint we were able to quickly see it as an issue. Other measures were around velocity (measured in weeks instead of sprints) and team comfort (do they like the change or would they rather go back).<br />
<br />
So far things have been great. Our cycle time is getting better and everyone is comfortable with the process. It's not a clear winner where people love the new process over the old. And our goals for cycle time seem lofty compared to what we ended up measuring. But it's given us a structure to keep experimenting and keep chipping away at these things. I absolutely would recommend it to anyone facing issues they feel cannot be resolved in a normal retrospective cycle. It can compliment or replace retrospectives as you see fit.Anonymoushttp://www.blogger.com/profile/06445330508811625525noreply@blogger.com0tag:blogger.com,1999:blog-7220281441485343407.post-50088333952895314162017-05-10T11:16:00.002+10:002017-05-10T11:18:00.144+10:00So I've been advised to create a Coaching ManualI'm trying to build up my skills as an Agile Coach. In a way I've been doing this already now for about 8 years. But it's getting a bit more structure and organisation.<br />
<br />
The way I see it learning is part of software development. It always has been. Some people get comfortable with their knowledge and workload and stop learning but that has never been me. When I get too comfortable I start looking for something else to do.<br />
<br />
But my learnings are just a jumble in my brain. Sometimes it impresses me as I can pull out a name, a quote or apply a process to something specific. And sometimes it lets me down so I have to revisit and revise like I'm doing right now. I'm listening to Esther Derby talk about her Six Rules of Change and writing this at the same time. Not something I recommend but I just want a refresher as I've studied it before. I'll probably grab the slides later and use it as part of a mini-presentation. Sorry you just ran into my jumble.<br />
<br />
What I'm trying to say is it's time to organise that jumble into something written. And the best place I can think of to write it is here. So I'll try and every week regurgitate something out of my head and into words. Usually it'll be referencing someone else smarter than me rather than anything terribly unique. But that's okay as it'll form a nice reference I can go back to for myself.Anonymoushttp://www.blogger.com/profile/06445330508811625525noreply@blogger.com0tag:blogger.com,1999:blog-7220281441485343407.post-48111908548234537112017-01-05T09:03:00.000+11:002017-01-05T09:03:08.089+11:00Things I’ve learned from running lean coffee and why you should organise one too<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">I’ve been running a 30 minute lean coffee session in my workplace every two weeks for 18 months now. Our first meeting for this year is tomorrow. I started the sessions when a bunch of people from work went to the Agile Australia conference and we wanted people to keep sharing ideas and other learnings. Now I invite any software developer in the building so my invite list has grown to 99 people but I typically only get about 10.</span></div>
<b id="docs-internal-guid-c48c7fa2-6b81-4ecf-4eeb-721727960603" style="font-weight: normal;"><br /></b>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">How lean coffee works: A few people from work got to take part in one at Agile Australia but I missed it myself. So I just got online and read everything at </span><a href="http://leancoffee.org/" style="text-decoration: none;"><span style="background-color: transparent; color: #1155cc; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">http://leancoffee.org/</span></a><span style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> I grabbed a bunch of index cards and texters and was ready to go.</span></div>
<b style="font-weight: normal;"><br /></b>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">I feel it’s super important to my company as it’s the only time people from all the software development teams can meet each other and discuss things. It’s helping break down walls between teams and helping ensure learnings can spread to other teams quicker.</span></div>
<br />
<ul style="margin-bottom: 0pt; margin-top: 0pt;">
<li dir="ltr" style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: disc; text-decoration: none; vertical-align: baseline;"><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Location matters. I started off in the building’s cafe but it would get too noisy when the coffee grinder is going. So we moved to another table in the entryway. I like that we’re highly visible but also in a casual environment. I find meeting rooms too formal. I also like that there are lots of tables so I can split the group up on demand.</span></div>
</li>
<li dir="ltr" style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: disc; text-decoration: none; vertical-align: baseline;"><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">I setup up one table for the discussion and if that table gets full I ask someone with experience to help run that table and move to a new one. I try and split like this once we hit 8 people. Timing of topics is done on a phone so anyone can do it and once someone has come a couple of times they know the routine and can run a table that has already been setup.</span></div>
</li>
<li dir="ltr" style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: disc; text-decoration: none; vertical-align: baseline;"><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">I am always prepared to throw in a topic to get things started. I especially like light hearted subjects. Last time my card was “How would Santa write software?”. This is extra useful when I’m going to leave a table to setup the next one.</span></div>
</li>
<li dir="ltr" style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: disc; text-decoration: none; vertical-align: baseline;"><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Be a good host and facilitate the discussion. If you see someone get cut off ask what they were going to say at a later moment.</span></div>
</li>
<li dir="ltr" style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: disc; text-decoration: none; vertical-align: baseline;"><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Take notes. You never know when you’re going to learn something. But also you might get useful feedback for the lean coffee at unexpected moments. Who else should I invite? What’s a good topic for next time? Do we need to change the location? The time?</span></div>
</li>
<li dir="ltr" style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: disc; text-decoration: none; vertical-align: baseline;"><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">I run mine for 30 minutes as it’s pretty hard to get people to leave their desk when I’m not supplying lunch. But at 30 minutes we are lucky if we can get through 4 topics. You could do it an hour but I think the energy and attention would quickly drop after that. Also I host mine in the morning as I find it easier to get people to make time just before their standup meetings.</span></div>
</li>
<li dir="ltr" style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: disc; text-decoration: none; vertical-align: baseline;"><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">I only get a few people attending. And that’s okay but I try and push to get people from different teams coming. It’s all about sharing information and if it’s only a couple of teams then there is a huge part of the company we’re not hearing from.</span></div>
</li>
<li dir="ltr" style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: disc; text-decoration: none; vertical-align: baseline;"><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Encourage people to bring coffee and tea. I like the casual feel it helps add.</span></div>
</li>
<li dir="ltr" style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: disc; text-decoration: none; vertical-align: baseline;"><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">I use index cards instead of post its. I find it works better on a flat table and means I’m less likely to have a texter bleed through and mark the table.</span></div>
</li>
</ul>
Anonymoushttp://www.blogger.com/profile/06445330508811625525noreply@blogger.com0tag:blogger.com,1999:blog-7220281441485343407.post-16213845058097452962015-08-14T14:19:00.004+10:002015-08-14T14:23:15.814+10:00Can Programmers Test?I spend a lot of time working closely with programmers on the software testing process. Much of my career mission is to get more people embracing techniques like Test Driven Development. As I push more and more of the testing demands onto the developers I sometimes run into people who say they need a tester for "independent testing".<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvvBj0mJgvMrxuesaSMasPQXk29ySDeWNeDlct1gN_rSZS9ofskSkMswrHPeMs1KK-ZHNXZzdTZUMAZHatxP7d1z-OK4PhhcH3-8n2D9jZXpfHx9zHvaDYxmgAQeHOkaUiLjH8a-m6JYQ/s1600/29de6692-2fc6-4d4f-8420-d33b1a02abc3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="236" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvvBj0mJgvMrxuesaSMasPQXk29ySDeWNeDlct1gN_rSZS9ofskSkMswrHPeMs1KK-ZHNXZzdTZUMAZHatxP7d1z-OK4PhhcH3-8n2D9jZXpfHx9zHvaDYxmgAQeHOkaUiLjH8a-m6JYQ/s400/29de6692-2fc6-4d4f-8420-d33b1a02abc3.png" width="400" /></a></div>
<br />
<br />
It's a concept I'm familiar with from early days in my career. A tester can look at the system and requirements with fresh eyes and find all those cases the programmer didn't consider. If the programmer does all the testing they'll be too tempted to just test the cases they know the code is handling and not discover any new areas where bugs may be hiding. The problem I have with this idea is I never was that type of programmer.<br />
<br />
As a programmer if I didn't test something it was purely out of laziness and arrogance. I'm a big supporter of Larry Wall's <span style="background-color: white;">three great virtues of a programmer. A lazy programmer will do their best to eliminate bugs as early as possible to save time. But if the programmer knows someone else will spend a lot of time looking for bugs then why should he bother? Just chuck it to the test team as soon as possible for all that information. It takes either removing that test team or a higher level of discipline to break that pattern. The independent tester is not catching bugs the programmer would not have found himself. They're spending a lot of time documenting bugs the programmer couldn't be bothered finding himself.</span><br />
<span style="background-color: white;"><br /></span>
<span style="background-color: white;">The comparison I like to make is a writer and an editor. As a writer you need to stay focused and complete your work before you get to thinking about editing. Then you edit it. You edit it multiple times constantly revising your work until you think it's fantastic. Only at that point do you hand it over to a professional editor. I'd like to see programmers all do the same thing. You can do testing. You should do testing. You should test until you feel there are no bugs left to find. Then hand it to a tester and maybe they'll find one or two things.</span><br />
<span style="background-color: white;"><br /></span>
<span style="background-color: white;">Testers are not all that independent anyway. They're reading the same requirements as the programmer. They're under similar deadlines and goals to get the product out the door. Any argument that says a programmer would avoid testing something could just as equally be applied to a tester. The reality is it doesn't happen because we're professionals and understand the need for a quality product. There's no reason the demand for quality should be solely the responsibility of the tester.</span><br />
<span style="background-color: white;"><br /></span>
<span style="background-color: white;">What is required to get programmers more testing is education. They're not often taught about testing methods or the kind of data that makes for good tests. That alone would add great value to the tests they can quickly perform before handing over a product. But there also needs to be a shift away from the thinking that a programmers time is too valuable to perform testing. If the programmer finds the errors they can quickly fix them before moving onto their next task. The longer it takes before the bug is found the longer it takes for a fix to apply as the programmer has to open up old code, go through any required reviews again, and finally get the fix out for re-testing.</span><br />
<span style="background-color: white;"><br /></span>
<span style="background-color: white;">So I strongly believe programmers can and should test. But how do I get that message across to everyone?</span>Anonymoushttp://www.blogger.com/profile/06445330508811625525noreply@blogger.com0tag:blogger.com,1999:blog-7220281441485343407.post-68669087295263759512015-08-03T14:52:00.000+10:002015-08-03T14:52:41.425+10:00How to Write Code Fast<h1 dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 10pt;">
<span style="font-family: 'Trebuchet MS'; font-size: 17.3333333333333px; line-height: 1.38; white-space: pre-wrap;">Start with a clean slate with simple goals</span></h1>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 10pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Starting from scratch is such a rarely privilege in professional programming. We get to do it all the time when we’re learning and trying things out. In our early years getting stuck and stumbled on the most trivial challenges. And later being proud of the frameworks and architectures we can build in days (sometimes hours).</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 10pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">But there is rarely any money to be made in building something from scratch. There is no value in doing something trivial because it likely has already been done a thousand times before. So we need to add something to existing code. Maybe it’s something we already developed ourselves or something we bought. If we’re lucky the existing code is modular enough that the new feature can feel like starting with a clean slate and give us that burst of speed.</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 10pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">So you will often hear the cries from programmers that are working with that monolithic and aging code; “please, please let us rewrite this code from scratch”. I’ve made this cry a few times in my career. Sworn to make it fast enough to reduce the cost. Promising to fix all those bugs that we now endure. Brazen enough to believe there will be no new bugs introduced this time that cannot be plucked out. We lie so much. We lie to ourselves and to the company. We lie because the pain of that old code is so real and so present.</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 10pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">The reality is that recreating something from scratch often takes just as long as the original did. Which may be years. Is in a race to catch the original is still being patched and enhanced in use. And the switch is still horribly painful as you have spent so long writing code before it’s put into real use and only then you find a bunch more issues. So you blow the budget, often reintroduce many of the same bugs as before, sometimes a few new ones and now hate the new code so much you cry “please, please let us rewrite this code from scratch!”</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 10pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">So if we’re lucky we get to work on something simple from scratch. No wonder people work for startups for stock options as payment. Or if there is an existing modular system it can feel like working from scratch. So we see such frameworks are massively popular in your language of choice. But that speed may not last.</span></div>
<h2 dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 10pt;">
<span style="background-color: transparent; color: black; font-family: 'Trebuchet MS'; font-size: 17.333333333333332px; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Start with high quality code with simple goals</span></h2>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 10pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">A system that is highly modular can feel like working from scratch. It can do this by actually splitting any operation into a collection of lots of smaller applications. The unix operating system is built on this principle. No single program does much at all. But they all implement the same basic method of handling input and output. That allows us to pipe data into and out of any combination of these programs to perform increasingly more complex tasks. There is no motivation to write a new text sort program because one already exists. There is no motivation to write a new text sort function because it is so easy to call the existing program.</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 10pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">But additionally the code can be very well understood and structured in a way that it is easy to change or extend. When an existing code base creates a high confidence on the outcome of any change the programmers are free to change it in any way they wish. So that existing code becomes a nice launch pad to very quickly create a new variation or addition. It may not feel like working from scratch because you may be changing code rather than writing new files. But it allows small changes to be quickly released, tested and reviewed. So progress kicks off at a blistering speed.</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 10pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">But each change may bring with it some technical debt. Create a new link between two modules that were previously unaware of each other and you have quickly created a nice new feature. But you’ve also created a dependency that is not obvious. Now all the tests need to be aware that one affects the other. Any new changes to either module needs to be intimately aware of this relationship that got hacked in. Further features and changes create a complex web of relationships. It starts to lose that feeling of simplicity and confidence. Then the bugs creep in. The bugs you’re afraid to fix because it might break something else way over there.</span></div>
<h2 dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 10pt;">
<span style="background-color: transparent; color: black; font-family: 'Trebuchet MS'; font-size: 17.333333333333332px; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Pile up technical debt (aka make a mess)</span></h2>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 10pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">But the customer hasn’t noticed that bug yet. They just want features. It’s the new features that make money. It’s the new functionality that will fight off the competition. As long as the system holds up and functions right now there’s no time free to fight the bugs. Nevermind clean up the code and make it more modular. We want to go fast right?</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 10pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">I like the analogy of the application being like a restaurant. You can present a very nice front area with great service and a wonderful menu to the customers and make a lot of money. Little do they know the mess being made in the kitchen as the chefs franticly create meals. If the customers saw the mess, the pests and the rotting smell back in the kitchen they would never eat here. None them have gotten sick… yet.</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 10pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">You quickly get lots of features out and the customers love the product. Sure there’s a few bugs but they’ll endure it for all the value the application is giving them. But the demand for features doesn’t slow down. Each new feature is harder to do and risks introducing bugs as fragile code is pushed beyond its original function. Outside of the programming team there are murmurings. What happened to this fast pace the programmers used to manage? How did a good team become so bad?</span></div>
<h2 dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 10pt;">
<span style="background-color: transparent; color: black; font-family: 'Trebuchet MS'; font-size: 17.333333333333332px; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Keep it clean and lean</span></h2>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 10pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">So what’s left? It’s not financially beneficial to start from scratch. Even if we start from a base of quality it’s easy to lose our way and lose that base. What allows us to go fast and stay fast? Is technical debt as inevitable as entropy. Would the second law of programming read: The sum of technical debt in software increases as the code is changed and added to?</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 10pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Robert C. Martin says, “The only way to go fast is to go well”. While there are plenty of other opportunities to write code fast many of them do not last. The lasting methods embrace the key practices of eXtreme Programming (XP). Pair programming, Test-Driven Development, Design Improvement, Continuous Integration and Collective Code Ownership. These are technical practices and may not mean much to customers or project managers. There are many people in a successful business that won’t be looking at the code quality. So the responsibility lies with the programmers as only they are reading and writing code each day.</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 10pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Pair programming is easy to roll out but often resisted. Many programmers learned the complex world of computing as the complex world of social interaction seemed too daunting. But code reviews afterwards are a weak substitute. By then it’s far too easy to say the design is locked in now and too hard to fix. Code reviewers understanding of the solution in place is limited while pairs discover the solutions together and weigh up the options each can bring before progressing. There are many studies with good methodologies that show pair programming can dramatically reduce the number of bugs in the final product. If you care about quality the question should be; why are you </span><span style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">not</span><span style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> doing pair programming already? And now many are taking it even future with mob programming getting a whole team mind share.</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 10pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Test-Driven Development (TDD) drives you towards a testable solution. Highly tested code is code that brings high confidence in making changes. High confidence in making changes means even late changes are easy and welcome. High confidence in making changes gives you that launch pad to make changes quickly and get results quickly. But you only get that launch pad if you were doing TDD all along. An ideal time to have started writing these tests was ten years ago. But you can settle with starting today. In the long run TDD will make you faster for a very small cost in time (10-20% according to studies). I would argue the cost is even less for complex tasks as it gets you writing code while you’re still figuring out the full solution. And now you can add to it in so many other ways with acceptance testing, behaviour driven development and more.</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 10pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Design Improvement is a recognition that the system you’re building now many not be the same system you’re building in three months. The requirements will change and evolve and so too should the design. With the high knowledge of code we have thanks to pair programming and the high confidence in making changes thanks to TDD we are free to make changes that improve the overall design after the implementation. You can change the entire architecture of your code base piece by piece to eventually end up somewhere closer to the product you have now and not the one you intended six months ago.</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 10pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Continuous Integration is to help recognise problems early and fix them early. If someone introduces a bug there is a big red flashing marker to stop work until it’s fixed. Much like you would expect on a factory production line when an issue introduced is noticed. The line is stopped and the problem is resolved immediately. And why stop there? You can get continuous releases going for rapid feedback from all your customers.</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 10pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">And finally Collective Code Ownership is critical to keeping any team of developers working fast. If your database expert is sick for a month you cannot afford to have all production slow down. If a reports system was developed by someone who since left the company how do you explain to the customer why further additions are coming so slowly? Pair programming goes a long way to resolving this but so does the TDD and design improvements. Keeping the system simple and one that the whole team intimately understands. If a developer sees a line of code they want to fix they should feel confident in fixing it, on the spot, without consulting anyone beyond the pair they are working with.</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 10pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Too often Agile is rolled out without these core XP practices and while teams are releasing in regular cycles release speed is slow. Many just accept the slow buggy releases as inevitable in software development much like they did with the waterfall code of the 90s. So great is the possibilities of going fast and there is so little to lose. Asking people to put higher quality into the code and their development team should not be considered a cost. And thanks to that quality you can write code faster.</span></div>
<h3 dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 8pt;">
<span style="background-color: transparent; color: #666666; font-family: 'Trebuchet MS'; font-size: 16px; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">References:</span></h3>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 10pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">The Costs and Benefits of Pair Programming. A Cockburn & L Williams.</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 10pt; margin-top: 0pt;">
<a href="http://dsc.ufcg.edu.br/~jacques/cursos/map/recursos/XPSardinia.pdf" style="text-decoration: none;"><span style="background-color: transparent; color: #1155cc; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">http://dsc.ufcg.edu.br/~jacques/cursos/map/recursos/XPSardinia.pdf</span></a></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 10pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">On the Effectiveness of Unit Test Automation at Microsoft. L Williams , G Kudrjavets & N Nagappan.</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 10pt; margin-top: 0pt;">
<a href="http://collaboration.csc.ncsu.edu/laurie/Papers/Unit_testing_cameraReady.pdf" style="text-decoration: none;"><span style="background-color: transparent; color: #1155cc; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">http://collaboration.csc.ncsu.edu/laurie/Papers/Unit_testing_cameraReady.pdf</span></a></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 10pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Implications of Test-Driven Development A Pilot Study. R Kaufmann & D Janzen.</span></div>
<span id="docs-internal-guid-dff0741e-f1e6-89da-9edf-4d1834dc0508"><a href="http://digitalcommons.calpoly.edu/cgi/viewcontent.cgi?article=1038&context=csse_fac" style="text-decoration: none;"><span style="color: #1155cc; font-family: Arial; font-size: 14.6666666666667px; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">http://digitalcommons.calpoly.edu/cgi/viewcontent.cgi?article=1038&context=csse_fac</span></a></span>Anonymoushttp://www.blogger.com/profile/06445330508811625525noreply@blogger.com0tag:blogger.com,1999:blog-7220281441485343407.post-6955885464618960822012-12-04T14:45:00.001+11:002012-12-04T14:46:38.429+11:00What to test when testing Javascript<span style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;">Part two in the series </span><b style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;">Test Driven Development with Javascript.</b><br />
<b style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;"><br /></b>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJdzW_P9tViInDgnuh933r4prWueFbFR9mDCIkQHbwgEcvH07x-NxWLf5snfXx8u2ctluPLtfIxoC_i1JsDRDUmuyC9QFoAduc6ARd1pDHiWLTiO7SzOabnvNrYOue6-lrLGa6YAUgqsU/s1600/Testing_bulletproof_vest_1923.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="260" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJdzW_P9tViInDgnuh933r4prWueFbFR9mDCIkQHbwgEcvH07x-NxWLf5snfXx8u2ctluPLtfIxoC_i1JsDRDUmuyC9QFoAduc6ARd1pDHiWLTiO7SzOabnvNrYOue6-lrLGa6YAUgqsU/s320/Testing_bulletproof_vest_1923.jpg" width="320" /></a></div>
<b style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;"><br /></b>
<br style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;" />
<span style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;">By now you've probably read and heard a lot warning you off testing through the UI and testing the user interface generally. Those still holds true for Javascript so you may be wondering if there is anything left to test. Time for some code!</span><br />
<br style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;" />
<b style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;">Not very testable code</b><br />
<br style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;" />
<span style="font-family: Courier New, Courier, monospace;"><span style="background-color: white; font-size: 13px; line-height: 18px;">function validate() {</span><br style="background-color: white; font-size: 13px; line-height: 18px;" /><span style="background-color: white; font-size: 13px; line-height: 18px;"> if(document.simple_form.name.value == "" ||</span><br style="background-color: white; font-size: 13px; line-height: 18px;" /><span style="background-color: white; font-size: 13px; line-height: 18px;"> document.simple_form.email.value == "")</span><br style="background-color: white; font-size: 13px; line-height: 18px;" /><span style="background-color: white; font-size: 13px; line-height: 18px;"> {</span><br style="background-color: white; font-size: 13px; line-height: 18px;" /><span style="background-color: white; font-size: 13px; line-height: 18px;"> alert("Please fill out all fields before clicking submit!");</span><br style="background-color: white; font-size: 13px; line-height: 18px;" /><span style="background-color: white; font-size: 13px; line-height: 18px;"> return false;</span><br style="background-color: white; font-size: 13px; line-height: 18px;" /><span style="background-color: white; font-size: 13px; line-height: 18px;"> }</span><br style="background-color: white; font-size: 13px; line-height: 18px;" /><span style="background-color: white; font-size: 13px; line-height: 18px;">}</span></span><br />
<br style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;" />
<span style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;">In this there is some logic that is not directly tied to the UI. So there is something we can test. But it’ll need a bit of a rework to make it testable</span><br />
<br style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;" />
<span style="font-family: Courier New, Courier, monospace;"><span style="background-color: white; font-size: 13px; line-height: 18px;">function isFormValid(formElement) {</span><br style="background-color: white; font-size: 13px; line-height: 18px;" /><span style="background-color: white; font-size: 13px; line-height: 18px;"> return (formElement.name.value != "" && formElement.email.value != "");</span><br style="background-color: white; font-size: 13px; line-height: 18px;" /><span style="background-color: white; font-size: 13px; line-height: 18px;">}</span><br style="background-color: white; font-size: 13px; line-height: 18px;" /><br style="background-color: white; font-size: 13px; line-height: 18px;" /><span style="background-color: white; font-size: 13px; line-height: 18px;">function validate() {</span><br style="background-color: white; font-size: 13px; line-height: 18px;" /><span style="background-color: white; font-size: 13px; line-height: 18px;"> if (!isFormValid(document.simple_form)) {</span><br style="background-color: white; font-size: 13px; line-height: 18px;" /><span style="background-color: white; font-size: 13px; line-height: 18px;"> alert("Please fill out all fields before clicking submit!");</span><br style="background-color: white; font-size: 13px; line-height: 18px;" /><span style="background-color: white; font-size: 13px; line-height: 18px;"> return false;</span><br style="background-color: white; font-size: 13px; line-height: 18px;" /><span style="background-color: white; font-size: 13px; line-height: 18px;"> }</span><br style="background-color: white; font-size: 13px; line-height: 18px;" /><span style="background-color: white; font-size: 13px; line-height: 18px;">}</span></span><br />
<br style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;" />
<span style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;">Now we have a testable function isFormValid. It’s an example of separating the logic from the UI and the DOM interaction. There is still a DOM element being used but that’s fine as it is easy to create or perhaps mock in writing the test.</span><br />
<br style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;" />
<b style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;">Code not worth testing</b><br />
<br style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;" />
<span style="font-family: Courier New, Courier, monospace;"><span style="background-color: white; font-size: 13px; line-height: 18px;">$(‘.button).click(function() {</span><br style="background-color: white; font-size: 13px; line-height: 18px;" /><span style="background-color: white; font-size: 13px; line-height: 18px;"> $(‘#my_quote’).css(‘background-color’, ‘red’);</span><br style="background-color: white; font-size: 13px; line-height: 18px;" /><span style="background-color: white; font-size: 13px; line-height: 18px;">}</span></span><br />
<br style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;" />
<span style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;">This code is still testable despite using some jquery magic. It’s easy to mock out jquery or fake events and DOM enough to test it. </span><b style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;">Do not test this code</b><span style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;">. There is no real logic in there and it’s heavily tied to the UI interaction. This may mean a lot of the Javascript you’re writing does not have tests and that’s okay. Interactions like this are still best tested manually and if they fail in a harmful way will be obvious to anyone using the system. Logic errors however can be much harder to spot through manual testing.</span><br />
<br style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;" />
<b style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;">Testable closures</b><br />
<br style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;" />
<span style="font-family: Courier New, Courier, monospace;"><span style="background-color: white; font-size: 13px; line-height: 18px;">function passwordCheckClosure(password) {</span><br style="background-color: white; font-size: 13px; line-height: 18px;" /><span style="background-color: white; font-size: 13px; line-height: 18px;"> return function(comparePassword) {</span><br style="background-color: white; font-size: 13px; line-height: 18px;" /><span style="background-color: white; font-size: 13px; line-height: 18px;"> return comparePassword === password;</span><br style="background-color: white; font-size: 13px; line-height: 18px;" /><span style="background-color: white; font-size: 13px; line-height: 18px;"> }</span><br style="background-color: white; font-size: 13px; line-height: 18px;" /><span style="background-color: white; font-size: 13px; line-height: 18px;">}</span></span><br />
<br style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;" />
<span style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;">I love closures and closures like this are still really easy to test. Just as I would still expect you to create private methods and properties when doing TDD in C++ or Java. In Javascript I would still expect you to write closures to help build your code into clear abstract interfaces. But as with private methods and constructors you need to avoid hiding everything in closures.</span><br />
<br style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;" />
<b style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;">Untestable closures</b><br />
<br style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;" />
<span style="font-family: Courier New, Courier, monospace;"><span style="background-color: white; font-size: 13px; line-height: 18px;">function validate() {</span><br style="background-color: white; font-size: 13px; line-height: 18px;" /><span style="background-color: white; font-size: 13px; line-height: 18px;"> function isFormValid(formElement) {</span><br style="background-color: white; font-size: 13px; line-height: 18px;" /><span style="background-color: white; font-size: 13px; line-height: 18px;"> return (formElement.name.value != "" &&</span><br style="background-color: white; font-size: 13px; line-height: 18px;" /><span style="background-color: white; font-size: 13px; line-height: 18px;"> formElement.email.value != "");</span><br style="background-color: white; font-size: 13px; line-height: 18px;" /><span style="background-color: white; font-size: 13px; line-height: 18px;"> }</span><br style="background-color: white; font-size: 13px; line-height: 18px;" /><br style="background-color: white; font-size: 13px; line-height: 18px;" /><span style="background-color: white; font-size: 13px; line-height: 18px;"> if (!isFormValid(document.simple_form)) {</span><br style="background-color: white; font-size: 13px; line-height: 18px;" /><span style="background-color: white; font-size: 13px; line-height: 18px;"> alert("Please fill out all fields before clicking submit!");</span><br style="background-color: white; font-size: 13px; line-height: 18px;" /><span style="background-color: white; font-size: 13px; line-height: 18px;"> return false;</span><br style="background-color: white; font-size: 13px; line-height: 18px;" /><span style="background-color: white; font-size: 13px; line-height: 18px;"> }</span><br style="background-color: white; font-size: 13px; line-height: 18px;" /><span style="background-color: white; font-size: 13px; line-height: 18px;">}</span></span><br />
<br style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;" />
<span style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;">This is just a slight variation on our form valid check above. But now we cannot access isFormValid to test it separate to the validate method as a whole.</span><br />
<br style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;" />
<b style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;"> Dependency injection with a closure</b><br />
<br style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;" />
<span style="font-family: Courier New, Courier, monospace;"><span style="background-color: white; font-size: 13px; line-height: 18px;">// formElenment - jquery reference to the form object</span><br style="background-color: white; font-size: 13px; line-height: 18px;" /><span style="background-color: white; font-size: 13px; line-height: 18px;">// alertMethod - alert on the browser. something else for console or tests</span><br style="background-color: white; font-size: 13px; line-height: 18px;" /><span style="background-color: white; font-size: 13px; line-height: 18px;">function attachFormValidator(formElement, alertMethod) {</span><br style="background-color: white; font-size: 13px; line-height: 18px;" /><span style="background-color: white; font-size: 13px; line-height: 18px;"> function isFormValid() {</span><br style="background-color: white; font-size: 13px; line-height: 18px;" /><span style="background-color: white; font-size: 13px; line-height: 18px;"> return (formElement.find(‘#name’).val() != "" &&</span><br style="background-color: white; font-size: 13px; line-height: 18px;" /><span style="background-color: white; font-size: 13px; line-height: 18px;"> formElement.find(‘#email’).val() != "");</span><br style="background-color: white; font-size: 13px; line-height: 18px;" /><span style="background-color: white; font-size: 13px; line-height: 18px;"> }</span><br style="background-color: white; font-size: 13px; line-height: 18px;" /><span style="background-color: white; font-size: 13px; line-height: 18px;"> formElement.submit(function(e) {</span><br style="background-color: white; font-size: 13px; line-height: 18px;" /><span style="background-color: white; font-size: 13px; line-height: 18px;"> if (!isFormValid()) {</span><br style="background-color: white; font-size: 13px; line-height: 18px;" /><span style="background-color: white; font-size: 13px; line-height: 18px;"> alert("Please fill out all fields before clicking submit!");</span><br style="background-color: white; font-size: 13px; line-height: 18px;" /><span style="background-color: white; font-size: 13px; line-height: 18px;"> e.preventDefault();</span><br style="background-color: white; font-size: 13px; line-height: 18px;" /><span style="background-color: white; font-size: 13px; line-height: 18px;"> }</span><br style="background-color: white; font-size: 13px; line-height: 18px;" /><span style="background-color: white; font-size: 13px; line-height: 18px;"> }</span><br style="background-color: white; font-size: 13px; line-height: 18px;" /><span style="background-color: white; font-size: 13px; line-height: 18px;"> );</span><br style="background-color: white; font-size: 13px; line-height: 18px;" /><span style="background-color: white; font-size: 13px; line-height: 18px;">}</span></span><br />
<br style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;" />
<span style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;">This may seem harder to test. We've introduced expections that we’re using jquery and put everything within a function that does not return anything. But it’s actually very testable since we can easily mock out all the objects that we send in and trigger and test those actions through those mocks. Because objects are cheap and easy to construct that means it’s cheap and easy to mock things out.</span><br />
<br style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;" />
<b style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;">Next time</b><br />
<span style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;">Running tests with Jasmine and your web browser</span><br />
<span style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;"><br /></span>
<i style="font-family: arial, sans-serif; font-size: small; line-height: 18px;">This is part of a series I'm writing for <a href="https://plus.google.com/u/0/b/104017139996657183972/104017139996657183972/posts">Agile+ on Google+</a> so you can follow as I post them there</i>Anonymoushttp://www.blogger.com/profile/06445330508811625525noreply@blogger.com0tag:blogger.com,1999:blog-7220281441485343407.post-17124883195515555562012-11-26T20:06:00.000+11:002012-11-26T20:06:41.431+11:00Test Driven Development with Javascript<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRbt7F_aeuqGz5nhK1Kk-G9jTuXNdPR3SKFhW-mVCxqvhN7ECHeM17fQzXY21N8C3UGcc6rfRMU74AVuqS7sivI4gEap5qTiu1u8ODtjgCVR2wuc-i1etQqPYxbQ8t7qFOWLveY1X3d64/s1600/topgear+tshirt.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="265" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRbt7F_aeuqGz5nhK1Kk-G9jTuXNdPR3SKFhW-mVCxqvhN7ECHeM17fQzXY21N8C3UGcc6rfRMU74AVuqS7sivI4gEap5qTiu1u8ODtjgCVR2wuc-i1etQqPYxbQ8t7qFOWLveY1X3d64/s320/topgear+tshirt.jpg" width="320" /></a></div>
<b><br style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;" /></b>
<span style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;">I've had a few opportunities to put my TDD skills to use in this brave new frontier. So I wanted to share what I've learned, what pitfalls to avoid and where the low hanging fruit is.</span><br />
<br style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;" />
<b style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;">Why use TDD in Javascript?</b><br />
<span style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;">We've reached a point where few people can develop an application without there being a web interface included. And now it's not enough to build a website with a few forms and buttons it has to be a "web application" with the detailed user interface and responsiveness we would expect of a desktop application. Javascript is serious business. Clients are not going to compliment you on your stable and fully tested backend if the UI is painful.</span><br />
<br style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;" />
<b style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;">When should you <i>not</i> use TDD in Javascript?</b><br />
<span style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;">Javascript has a strange distinction. It is the most widely used programming language in the world. It is also the most disliked programming language in the world. It can be hard to get programmers to </span><i style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;">learn</i><span style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;"> Javascript before they dive into writing Javascript. So you cannot expect unit tests in that environment. It may be that your programmers are just copying the latest jquery plugins and performing wonders while writing very little Javascript If there’s very little Javascript being written then there’s no point trying to automate the testing.</span><br />
<br style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;" />
<b style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;">Okay. So do I test in Selenium or Watir?</b><br />
<span style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;">Wait just a minute now! Those are not unit testing frameworks. They can be great for integration testing to see the behaviour with the DOM and a backend. But TDD requires unit tests that are fast to write and fast to run. I’m going to use Jasmine but there’s lots of other unit test frameworks to pick from and I’ll walk through the ways to run it on a console, through a browser and distributed through many browsers.</span><br />
<br style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;" />
<b style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;">Next time</b><br />
<span style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;">Writing testable javascript and what not to test</span><br />
<span style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;"><br /></span>
<span style="font-family: arial, sans-serif; font-size: x-small;"><span style="line-height: 18px;"><i>This is part of a series I'm writing for <a href="https://plus.google.com/u/0/b/104017139996657183972/104017139996657183972/posts">Agile+ on Google+</a> so you can follow as I post them there</i></span></span>Anonymoushttp://www.blogger.com/profile/06445330508811625525noreply@blogger.com0tag:blogger.com,1999:blog-7220281441485343407.post-40530407077278201942012-09-12T17:08:00.000+10:002012-09-12T17:08:42.938+10:00Place to discuss Agile topicsI haven't been completely idle. Appart from my rambings on <a href="http://twitter.com/gd_twit">twitter</a> and <a href="http://plus.google.com/108784265735983376859/posts">google+</a> I've also been making regular posts to a new facebook group on <a href="http://www.facebook.com/agilemanifesto">Agile Software Development</a>.
<br/>
I will return to talk about RestScriptFixture, fun with NodeJS and are games (like movies) out of new ideas?Anonymoushttp://www.blogger.com/profile/06445330508811625525noreply@blogger.com0tag:blogger.com,1999:blog-7220281441485343407.post-54449901122882647582012-05-25T21:10:00.001+10:002012-05-25T21:10:21.938+10:00RestFixtureSo most of the tests I'm writing now in Fitnesse are using <a href="https://github.com/smartrics/RestFixture">RestFixture</a>. Being able to do all this black box style testing has helped me get a lot of tests up and running without having to change the existing code base. Now I've taken a step future with <a href="https://github.com/gdunn/RestFixture">my own little fork</a> so I can use scenarios and build nice BDD style scripts. But first I want to give me own quick guide to using RestFixture<br />
<br />
<b>Step 1: Installing</b><br />
You can dive straight in by grabbing the latest jar files for RestFixture here <a href="https://github.com/smartrics/RestFixture/downloads">https://github.com/smartrics/RestFixture/downloads</a><br />
If you know what you're doing can get the nodep version to work nicely along side other libraries you may be including in Fitnesse. But I grabbed the 'full' version and unzipped it into a RestFixture folder alongside my FitNesseRoot folder.<br />
<b>Step 2: Write your first test</b><br />
I took advantage of the built in Fitnesse api as a basic test and wrote a page called RestFixture with the following contents<br />
<pre>
!define TEST_SYSTEM {slim}
!path RestFixture/lib/*.jar
!path RestFixture/RestFixture.jar
!define expectedReturnHeaders {Content-Length : [\d]+
Content-Type : text/xml }
|!-Table:smartrics.rest.fitnesse.fixture.RestFixture-! | http://localhost:8080|
|GET|/RestFixture?rss|200| ${expectedReturnHeaders} |//title[text()='RestFixture']|
</pre>
If that runs and passes then congratulations! You've got a working RestFixture install!
<b>Step 3: Profit!</b><br/><br/><br/>
<b>Pitfall 1: &</b><br/>
Stuff like /loadpreferences?session=9999&user=admin&module=config would fail and I was scratching my head. Now any good RESTful api designer will tell you that's a stupid url to be using and they'd be write. But it's someone's old mistake and I can either tell them how stupid they are or appreciate the fact it works and move on trying to get everything that's broken working too.<br/>
Why did this fail? Well because Fitnesse was turning my & into &amp; and messing up the url with nothing to parse it back. Solution: Surround the url with !- -! to stop Fitnesse doing any parsing on it and it'll work just fine.<br/>
<b>Pitfall 2: json + xpath</b><br/>
I was trying to figure out how to handle json that didn't confirm nicely to use xpath commands. Unless your json is wrapped in something like {node: stuff} then the xpath stuff just doesn't work. Something I will try and fix at some point. So i used a lot of the javascript parsing in there to access the jsonbody variable that would work just fine. So I got lots of things like this:<br/>
<pre>/* javascript */ jsonbody == false;</pre>
or this
<pre>
/* javascript */
var match = null;
for (var i=0; i != jsonbody.length && match == null; ++i) {
var node = jsonbody[i].map;
if (node.name == 'Bob') {
match = node;
}
}
match != null;
</pre>
or use the let ... js statements like this
<pre>response.jsonbody[4].block.name</pre>
<b>Pitfall 3: Posting form like data</b><br/>
It's documented in later versions but not in 2.0 beta that you can use set body with url encoded data to behave like posted form data. Very handy. Although I'm still trying to figure out how this can work if combined with a file upload.Anonymoushttp://www.blogger.com/profile/06445330508811625525noreply@blogger.com3tag:blogger.com,1999:blog-7220281441485343407.post-68581258327451892982012-05-16T11:53:00.000+10:002012-05-16T16:17:15.990+10:00JDBC FixtureI created this class so I can run basic database commands from within Fitnesse. Dropping SQL into a Fitnesse page not recommended but it can still be a useful tool for a few reasons:
<ol>
<li>It is reusable so you can drop it into lots of tests without making new classes all the time</li>
<li>It's a good bridging tool in trying to get developers using fitnesse who are not used to creating an abstraction layer for their tests</li>
<li>It's handy to combine with RestFixture when you need to adjust or validate the data but cannot do it through a rest command</li>
</ol>
But again it's not recommended. Better to create a new fixture with a function like
<pre>public void createNewUser(String name, String password)</pre>
<br/>
<br/>
Here is what running the JDBCFixture looks like in the fitnesse
<pre style="word-wrap: normal; font-size: 65%; background-color: #EEE;">
!path lib/*.jar
!|import |
|com.warmage.util.fixtures|
!|script|DBQueryFixture|mydatabase |user |pass |
|check |statement |UPDATE users SET city='New York' WHERE name='Big Joe'|1 |
!|script|DBQueryFixture|mydatabase |user |pass |
|query |SELECT * FROM users WHERE name='Big Joe' |
|show |get row |0 |and column|name |
|check |get row |0 |and column|city|New York|
</pre>
So it's pretty straight forward. If you're already familiar with script tables you'll know how you can drop switch between check and show for when you just want to see the result vs when you want to validate it. There are probably lots of statements you'll want to run without looking at the number returned (number of rows modified or -1 if there is an error). My fixuture is hard coded to use a local postgres database (and the postgres jdbc jar is in my lib folder). But it's easy enough to change that for your own version
<pre style="word-wrap: normal; font-size: 65%; background-color: #EEE;">
package com.warmage.util.fixtures;
import java.util.ArrayList;
import java.util.List;
import java.sql.*;
import static util.ListUtility.list;
public class DBQueryFixture {
// constants
final private String baseUrl = "jdbc:postgresql://localhost:5432/";
/**
* Constructor for script table
*
* @param database - Database name
* @param dbUser - User to use
* @param dbPassword - Password to use
*/
public DBQueryFixture(String database, String dbUser, String dbPassword) {
try {
jdbcConnection = DriverManager.getConnection(baseUrl + database, dbUser, dbPassword);
} catch (SQLException e) {
System.out.println("Error connecting to the database");
}
}
public int statement(String query) {
try {
Statement st = jdbcConnection.createStatement();
return st.executeUpdate(query);
}
catch (SQLException e){
System.out.println("Error executing statement");
}
return -1;
}
public void query(String query) {
try {
Statement st = jdbcConnection.createStatement(
ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
results = st.executeQuery(query);
}
catch (SQLException e){
System.out.println("Error executing query");
}
}
public String getCell(String column) {
if (results != null) {
try {
return results.getString(column);
}
catch (SQLException e){
System.out.println("Error fetching cell for column " + column);
}
}
return "null";
}
public String getRowAndColumn(int row, String column) {
if (results != null && row >= 0) {
try {
// Iterate to the right row
results.beforeFirst();
boolean resultsValid = true;
while(resultsValid && 0 <= row) {
resultsValid = results.next();
row--;
}
if (resultsValid) {
return getCell(column);
} else {
System.out.println("Error row count too big");
}
}
catch (SQLException e){
System.out.println("Error moving through rows");
}
}
return "null";
}
private Connection jdbcConnection;
private ResultSet results = null;
}
</pre>Anonymoushttp://www.blogger.com/profile/06445330508811625525noreply@blogger.com1tag:blogger.com,1999:blog-7220281441485343407.post-53182192154108253462012-05-13T19:14:00.000+10:002012-05-13T19:14:34.551+10:00Skipping over fitnesse tutorialI was thinking of writing a short bit on writing tests in <a href="http://fitnesse.org/">Fitnesse</a>. But instead I'm going to recommend the tutorials by Brett L. Schuchert http://schuchert.wikispaces.com/FitNesse.Tutorials as they skip straight into using SLIM. The guides on fitnesse.org (and with the install) are good but explain everything with FIT first before racing though what is different with SLIM. That's just the nature of how Fitnesse was developed but it's worth skipping straight to SLIM as it has less requirements and can be more flexable.Anonymoushttp://www.blogger.com/profile/06445330508811625525noreply@blogger.com0tag:blogger.com,1999:blog-7220281441485343407.post-2410282995191150362012-05-12T18:12:00.000+10:002012-05-12T18:13:37.303+10:00Setting up Fitnesse on Ubuntu in 7 stepsSome pretty basic steps but just to make sure it's here for everyone to see. Setting up fitnesse and running the jar is easy enough. Just go to http://fitnesse.org/ and get started and do it on your desktop just to see it in action. But for me that wasn't good enough I wanted it to run as service on ubuntu.
<br/><br/>
I stole a few tricks from how ubuntu runs jenkins and setup fitnesse a similar way.
<br/>
</br/><strong>1. Create a user and group for fitnesse</strong> (optional)<br/>
I didn't do this because I wanted tomcat, jenkins and fitnesse all running as the same user. Call it laziness to avoid any permissions classing but it doesn't change the process that you need to create or choose what user you're going to make it run as. Don't make it run as your user or root!<br/>
</br/><strong>2. Download the jar file and place it in /usr/share/fitnesse </strong><br/>
Make the folder too of course. It can belong to root as long as the fitnesse user has read access<br/>
</br/><strong>3. Create the folder to run in at /var/lib/fitnesse </strong><br/>
Fitnesse user needs write permissions here so may as well make it the owner. This is where FitNesseRoot is going to end up and also where you're going to want any libraries and classes it can include. I found fitnesse isn't very good at using absolute paths when doing includes and also doesn't handle spaces. Something to look out for!<br/>
</br/><strong>4. Create the folder to store fitnesse logs /var/log/fitnesse </strong><br/>
Make sure the fitnesse user can write
</br/><strong>5. Create the below file as /etc/init/fitnesse.conf</strong></br/>
<pre>
description "fitnesse: Fitnesse acceptance testing framework"
author "geoff@warmage.com"
start on (local-filesystems and net-device-up IFACE!=lo)
stop on runlevel [!2345]
env USER="fitnesse"
env GROUP="fitnesse"
env FITNESSE_LOG="/var/log/fitnesse"
env FITNESSE_ROOT="/var/lib/fitnesse"
env HTTP_PORT=8081
env JAVA_OPTS=""
env JAVA_HOME="/usr/lib/jvm/default-java"
#limit nofile 8192 8192
pre-start script
test -f $FITNESSE_ROOT/fitnesse.jar || { stop ; exit 0; }
end script
script
FITNESSE_ARGS="-p $HTTP_PORT -l $FITNESSE_LOG"
exec daemon --name=fitnesse --inherit --chdir=$FITNESSE_ROOT \
--output=$FITNESSE_LOG/fitnesse-output.log --user=$USER \
-- $JAVA_HOME/bin/java $JAVA_OPTS -jar fitnesse.jar $FITNESSE_ARGS
end script
</pre>
</br/><strong>6. Link from /etc/init.d/fitnesse to /lib/init/upstart-job</strong></br/>
<pre>sudo ln -s /lib/init/upstart-job /etc/init.d/fitnesse</pre>
Make sure it's executable<br/>
<pre>sudo chmod +x /etc/init.d/fitnesse</pre>
nearly there now<br/>
</br/><strong>7. Setup run levels for fitnesse to run with</strong></br/>
I used <em>sudo sysv-rc-conf -P</em> to see the run levels and turned on 2, 3, 4 & 5. Could probably have dropped 2 but whatever, that's what most use. There seems to be lots of other ways to do this but this is what I did.<br/>
<br/>
<strong>That's it!</strong> I'm probably forgetting something and I'm sure there's better ways to do some of the steps. There's lots of guides out there if you search 'ubuntu daemon' but knowing the quirks of fitnesse (spaces in folder names? where do you want files?) is still relevant.Anonymoushttp://www.blogger.com/profile/06445330508811625525noreply@blogger.com0tag:blogger.com,1999:blog-7220281441485343407.post-51529705494454387492012-05-03T19:58:00.001+10:002012-05-03T19:58:51.261+10:00FitnesseAnyone who has worked with me in the last 3 years knows I have a programmer crush on <a href="https://twitter.com/#!/unclebobmartin">Uncle Bob</a> and I got most of my initial training on Agile development from <a href="https://twitter.com/#!/jwgrenning">James Grenning</a>. So it was just a matter of time until I started using <a href="http://fitnesse.org/">Fitnesse</a>. Now fitnesse (and fit originally) is an interesting tool to try and get acceptance tests <strong>OUT</strong> of code. After all why should programmers (or programmer-ish testers) be the only ones to write, read and review these tests? Acceptance testing is about making sure you deliver what the customer wanted so shouldn't the customer and other management people be reading them too? So fitnesse meets them in a middle ground. A wiki.
<br/><br/>
A wiki is a good place to go because you can get a manager or customer to read a wiki. You can, with a bit of a push, even get them to start contributing to a wiki. Good luck trying to get them using <a href="http://jmeter.apache.org/">jmeter</a> or read what you created in <a href="http://cukes.info/">cucumber</a>! Those are great tools but they don't scratch the itch that fitnesse was written for.
<br/><br/>
So I've been writing fixtures and playing around with scenarios and scripts. But what has me really excited is combining all that with <a href="https://github.com/smartrics/RestFixture/">RestFixture</a>. I'm currently dealing with a lot of java code with all the front end piped through a RESTful service. It's a pretty common way to develop any distributed service these days and works pretty well. So I've been able to build up detailed tests that push all kinds of scenarios through the rest api without touching any UI code. And I've been able to condense it down to user stories that read like English so I can get the business analysts types to read and review them. With a bit of training I might even get them writing the first drafts of new areas to test.
<br/><br/>
But it hasn't been without challenges. So I want to document exactly what I've done and the kind of tests I'm able to now write. More post will come later but first I need to clean up my fork of RestFixture so I can get my changes accepted back into the original!Anonymoushttp://www.blogger.com/profile/06445330508811625525noreply@blogger.com0tag:blogger.com,1999:blog-7220281441485343407.post-79604352947646963952012-03-17T08:02:00.000+11:002012-03-17T08:02:44.624+11:00Test value is in running themHave you seen a build flag that states "no tests". What's the point building code without running all your tests? What's the harm in running them one last time? Tests are there to be run. A LOT! Settings that allow you to run tests every time you save a file in your IDE help ensure your unit tests are fast and passing all the time. Unit tests are there to catch you when you break something unexpected. You may think your fixing a bug with a date-time object but maybe that fix breaks something else down the line. The tests are there to tell you. If you never run your tests then why bother having them? Why not just delete them all?
<br />
<br />
When should tests be run?<br />
<br />
<ul>
<li>As often as possible. Especially fast unit tests</li>
<li>Every time you build</li>
<li>Before committing changes to production code to version control</li>
<li>Before
committing changes to test code to version control</li>
<li>After committing code to version control (via Continuous Integration)</li>
</ul>Anonymoushttp://www.blogger.com/profile/06445330508811625525noreply@blogger.com0tag:blogger.com,1999:blog-7220281441485343407.post-26176365062969161962012-02-25T17:06:00.000+11:002012-02-25T17:11:32.460+11:00Bad Programmer HabitsDo you do any of these? Do you see these habits in others. Clean code is when you look at code and think "of course you would do it that way". It's simple, elegant, and straight forward. Once you look at it you can't think of a better way to do it. It seems 'obvious' but only with the power of hindsight. But it's not something you'll get much of from these programmers<br />
<ul>
<li><b>The Hoarder</b> - "I’ll add/leave this function because it may come in useful" litters your code with commented code and unused functions that rot and bloat your code</li>
<li><b>Over-Complicator</b> - "I've built an xml like nested config value loader to read in my three values instead of using a constant" yeah thanks. And when it turns out to have a bug we'll spend weeks trying to figure out how it all works and why you wasted company time (and money) writing it.</li>
<li><b>Rewriter</b> - "This 3D library doesn't <i>quite</i> fit my needs. I think I'll write my own and call it DirectY" and you waste weeks on it, it turns out buggy, has very little hardware support but by the time we find out the entire company is building on it and feels committed to keeping it.</li>
<li><b>Obscurer</b> - "CMiscValues init function runs ReadStream to setup the CoreFactory" this is not abstract this is waffle</li>
<li><b>The Secret Recipe</b> - "Oh it crashed because you have to call unloadAllSettings before you let the class run the deconstructor. But make sure you call close first" so basically no one can use your code without mysterious and random crashes. Thanks for your contribution.</li>
</ul>Anonymoushttp://www.blogger.com/profile/06445330508811625525noreply@blogger.com0tag:blogger.com,1999:blog-7220281441485343407.post-3023107008652266682012-02-21T20:10:00.000+11:002012-02-21T20:10:12.627+11:00Grumpy programmersHave you ever had to work with that guy. The one who hates going to meetings. Ridicules the other developers. Sits by themselves rarely talking with anyone while "working". Sometimes they swear a lot, sometimes they often show up late to work and often they have little interest in showing someone else how their code works.<br />
<br />
Have I been that guy? Honestly I can't say for sure I never have been. My programming idol Uncle Bob admits to being that guy once in his book <a href="http://www.amazon.com/Clean-Coder-Conduct-Professional-Programmers/dp/0137081073/ref=sr_1_1?ie=UTF8&qid=1329815157&sr=8-1">Clean Coder</a>.<br />
<br />
There's a lot of old stereotypes around programming and computers in general. I've been told once to put up with a grumpy programmer on the promise he would work twice as fast as any other (if not faster). Turned out he was pretty clever but he wasn't any faster than the average for the team. And when he got really grumpy he got sloppy and produced some of the worst programming I've ever seen. So I've since resolved to never endure such behaviour and that any anti-social behaviour is potentially a problem.<br />
<br />
A lot of programming issues are resolved through communication. Don't be the grumpy programmer. Don't ever think it's worth just "enduring" one.Anonymoushttp://www.blogger.com/profile/06445330508811625525noreply@blogger.com0tag:blogger.com,1999:blog-7220281441485343407.post-5589395505747108922012-02-09T22:16:00.002+11:002012-02-09T22:16:51.930+11:00TDD is good for you. But it's a hard habit to form<p>I've been thinking a lot about TDD, agile training and the long term behaviour of teams after such training. I've met far more programmers who have had training in TDD than I know programmers who practice TDD. And I've heard all the excuses</p>
<ul>
<li>You can't do TDD with this language</li>
<li>You can't do TDD with this framework</li>
<li>You can't do TDD with this database</li>
<li>You can't do TDD with this hardware</li>
<li>You can't do TDD with this schedule</li>
</ul>
<p>All bullshit, believe me. I may have said some of those myself once</p>
<p>But once you get past all that you get programmers who will give you a lucid agreement that TDD is good and they should use it more. You train them and show them how it's done as well as push past the issues above.</p>
<p>And then they don't use it.</p>
<p>But why? They agreed it's a good idea and they should do more. We solved all the serious issues that were stopping them from trying. Why wont they even try and put it into their routine?</p>
<p>Routine. That's part of the problem. They still follow the old patterns all programmers learn. "I need to make something to do X. Not sure how to do it"... write write write "still not there"... write write write "okay it works. oh wait! I forgot to write any tests"</p>
<p>I want to delete that programmer's code and make him write it again. Seriously! You're so focused on writing code you forget how important it's function, adaptability and readability is. And the tools that help you get there are tests. Yes you solved X but I can't test it, can't easily change it and can't easily extend it. At least if I deleted his/her files that programmer would get some more practice at TDD.</p>
<p>Practice. That's part of it too. Do your TDD homework! Spend each working day after training with "what can I apply TDD to today?" Consider it incidental exercise to help improve your TDD muscles.</p>
<p>Is learning TDD like learning an exercise routine? Making part of it your daily routine. Setting achievable goals. Measuring your progress. And talk to others for encouragement and support. And if you get really stuck call in a personal trainer!</p>Anonymoushttp://www.blogger.com/profile/06445330508811625525noreply@blogger.com0tag:blogger.com,1999:blog-7220281441485343407.post-80212938377562518632011-12-23T21:47:00.000+11:002011-12-23T21:47:16.897+11:00You are NOT Agile if there's no Test Driven DevelopmentYes <b>YOU</b>. Company, team, manager or programmer.<br/>
<br/>
You tried to tell me your job requires "Proven track record in delivering features in agile environment". You listed in your linked in profile that you have "Extensive experience with Agile projects". You describe your company as "Practising the latest Agile development techniques".<br/>
<br/>
Bullshit!<br/>
<br/>
If you're not doing Test Driven Development you're not agile. You're not Scrum. You're not XP. You're not Kanban. You'd be lucky to be classified as LEAN.<br/>
<br/>
Okay so TDD didn't make it into the <a href="http://agilemanifesto.org/">Manifesto</a> and maybe it should have. But all the ideas that built towards that manifesto included TDD as a key part of how programming should be done. You can argue about being 80% agile or that an agile technique for one company shouldn't be identical to the next. Fine! But you damn well better have TDD front and centre of that plan!<br/>
<br/>
Why is it so important? Because agile development isn't about changing management practises. It's about changing ALL your practises and that programmers are the most important part in developing software. Let me say that again because I think a lot of companies like to ignore it. <b>Programmers are the most important part in developing software.</b> If your programmers are doing the same thing <i>before </i>agile as they are <i>after</i> except for a few meetings they go to then nothing of substance has really changed.<br/>
<br/>
So quit the bullshit. I don't care if you're not doing any agile techniques. Or if you like to call your regular meeting a "scrum" or a "standup". Just don't tell me you ARE practising agile and wonder why my jaw drops when you say "oh we sometimes write a few tests but we never to test driven development".Anonymoushttp://www.blogger.com/profile/06445330508811625525noreply@blogger.com0tag:blogger.com,1999:blog-7220281441485343407.post-12996979086202812682011-11-04T16:01:00.000+11:002012-01-04T09:15:10.681+11:00Zend<p>"But Zend Framework also provides an advanced Model-View-Controller (MVC) implementation that can be used to establish a basic structure for your Zend Framework applications" - <a href="http://framework.zend.com/manual/en/learning.quickstart.intro.html">http://framework.zend.com/manual/en/learning.quickstart.intro.html</a>
</p><p>
What a load of shit. Models are barely more than wrappers for database tables. Which would be okay except they have no connection to the view. And there's no easy way of having a model render out differently with different views. Zend Framework is shit and I wouldn't recommend it to anyone</p>
<p></rant></p>
<p><b>Update</b>: For future reference Zend and most so called MVC web frameworks are actually <a href="http://en.wikipedia.org/wiki/Model_2">Model 2</a>. Zend is a pretty poor job of it but at least that puts it into the right category</p>Anonymoushttp://www.blogger.com/profile/06445330508811625525noreply@blogger.com0tag:blogger.com,1999:blog-7220281441485343407.post-69678469954474862812011-10-28T11:47:00.001+11:002011-10-28T11:48:54.341+11:00Everyone will have access to the internet in less than 10 years<p>I'm making the call now. In 5-10 years everyone who wants access to the internet will have it. Already we're seeing tablets win over people who previously thought computers too complex to use and maintain. Cheap smart-phones are selling like hotcakes across Africa. Investment in mobile networks in the developing world has been very high for over a decade as it struggles to keep up with demand.</p>
<p>We've often talked about the internet being a tool for democracy. I'm not sure we ever really believed it until protests started across the arab world. But now that there are seemingly pointless protests across the world following the #occupy tags it seems the world is never going to be quite the same. Now protests (violent or otherwise) can be spawned by a hashtag with very little basis beyond that. Still not sure how I feel about that.</p>Anonymoushttp://www.blogger.com/profile/06445330508811625525noreply@blogger.com0tag:blogger.com,1999:blog-7220281441485343407.post-44473211551233454902011-09-19T11:01:00.000+10:002011-09-19T11:01:10.585+10:00Games and Gamers can make the world a better place<a href="http://www.abc.net.au/news/2011-09-19/online-gamers-crack-enzyme-puzzle/2905314">Gamers crack the enzyme puzzle</a>Anonymoushttp://www.blogger.com/profile/06445330508811625525noreply@blogger.com0