tag:blogger.com,1999:blog-5003503280472070512024-03-19T05:25:59.389-07:00CodeHareMrHarehttp://www.blogger.com/profile/07813011371392466114noreply@blogger.comBlogger22125tag:blogger.com,1999:blog-500350328047207051.post-37293053087922794522021-11-04T07:39:00.005-07:002021-11-04T07:41:12.018-07:00Should I adjust story points when work is carried over to the next sprint? NO.<p> <span style="font-family: Arial; font-size: 11pt; white-space: pre-wrap;">Why adjusting story points in carried-over stories is bad practice:</span></p><span id="docs-internal-guid-58a90ced-7fff-faff-67f9-e05c04742d2e"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-position: normal; vertical-align: baseline; white-space: pre-wrap;"><br /></span><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-position: normal; vertical-align: baseline; white-space: pre-wrap;">1) the backlog is a historical record of the work done, and the estimates that were made. Adjusting the story points down makes it look on the record as if the team had underestimated the story</span><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-position: normal; vertical-align: baseline; white-space: pre-wrap;"><br /></span><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-position: normal; vertical-align: baseline; white-space: pre-wrap;"><br /></span><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-position: normal; vertical-align: baseline; white-space: pre-wrap;">2) Velocity is a representation of how much work the team get through on average. By adjusting the story points you are effectively making work disappear. Velocity is an approximate figure, one should never look at velocity within a single sprint as meaningful, it’s the </span><span style="font-family: Arial; font-size: 11pt; font-style: italic; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-position: normal; vertical-align: baseline; white-space: pre-wrap;">average velocity over a number of sprints</span><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-position: normal; vertical-align: baseline; white-space: pre-wrap;"> that gives an indicator of how much work to bring in.</span><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-position: normal; vertical-align: baseline; white-space: pre-wrap;"><br /></span><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-position: normal; vertical-align: baseline; white-space: pre-wrap;"><br /></span><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-position: normal; vertical-align: baseline; white-space: pre-wrap;">3) Story points are a tool for the team to facilitate estimation, nothing more.<br /><br /></span></span><div><span><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-position: normal; vertical-align: baseline; white-space: pre-wrap;">By taking points out of a story you are reducing the apparent average velocity of the team and making the reporting incorrect over time. It may make the burndown chart look better in an individual sprint, but the long term effects on reporting are harmful. The sprint burndown chart is no business of anyone outside the team anyway.</span></span><div><br /></div><div><span><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-position: normal; vertical-align: baseline; white-space: pre-wrap;"><br /></span><a href="https://seilevel.com/requirements/pick-a-side-how-to-handle-sprint-carry-over" style="text-decoration: none;"><span style="color: #1155cc; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-position: normal; text-decoration-skip: none; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">https://seilevel.com/requirements/pick-a-side-how-to-handle-sprint-carry-over</span><span style="color: black; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-position: normal; vertical-align: baseline; white-space: pre-wrap;"><br /></span><span style="color: black; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-position: normal; vertical-align: baseline; white-space: pre-wrap;"><br /></span></a><a href="https://www.mountaingoatsoftware.com/blog/handling-work-left-at-the-end-of-a-sprint" style="text-decoration: none;"><span style="color: #1155cc; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-position: normal; text-decoration-skip: none; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">https://www.mountaingoatsoftware.com/blog/handling-work-left-at-the-end-of-a-sprint</span><span style="color: black; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-position: normal; vertical-align: baseline; white-space: pre-wrap;"><br /></span><span style="color: black; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-position: normal; vertical-align: baseline; white-space: pre-wrap;"><br /></span></a><a href="https://www.jeremyjarrell.com/how-to-handle-stories-that-arent-completed-in-a-single-sprint/" style="text-decoration: none;"><span style="color: #1155cc; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-position: normal; text-decoration-skip: none; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">https://www.jeremyjarrell.com/how-to-handle-stories-that-arent-completed-in-a-single-sprint/</span><span style="color: black; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-position: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><br /></span></a><a href="https://www.jeremyjarrell.com/how-to-handle-stories-that-arent-completed-in-a-single-sprint/"><span style="color: black; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-position: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><br /></span></a></span><div><span><a href="https://www.jeremyjarrell.com/how-to-handle-stories-that-arent-completed-in-a-single-sprint/"><span style="color: black; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-position: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><br /></span></a></span></div></div></div>MrHarehttp://www.blogger.com/profile/07813011371392466114noreply@blogger.com0tag:blogger.com,1999:blog-500350328047207051.post-35480176502306939312020-12-21T06:05:00.005-08:002020-12-24T05:20:15.866-08:00The Agile Testing Paradox - reconciling manual testing with agile methodology<div>There's one difficult question that keeps coming up in scrum teams, and it never seems to go away. How do you complete all the PBIs in a sprint without having devs idle while the last bit of testing is done?</div><div><br /></div><div>Scrum doesn't have any concept of a tester being separate from a dev - there is no separate tester role. This is partly to keep the framework simple, but also partly because (like a lot of software development thinking from the early 21st Century) it has roots in the open source movement where there are no strictly defined roles (beyond arguably the PO). That's a topic for another day, for the moment I'm interested in inefficient sprints, bored devs and frustrated testers.</div><div><br /></div><div>The problem looks like this:</div><div><br /></div><div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgtxNC-Gcq7gYsr-pAgzlUt-UJlBXfamrMEuOIvUXy7wBOIDfk2NfY8IXhp85Rd8uPBMtK5icl5wTV7wK1djcP_ZGwKZMi0encKpt-v_CpV2whg4BWPDnYCNo1aPOUGTASB2NxfqexvcTI/s540/60EF017D-945E-4F0B-B138-050329731CAB_4_5005_c.jpeg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="305" data-original-width="540" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgtxNC-Gcq7gYsr-pAgzlUt-UJlBXfamrMEuOIvUXy7wBOIDfk2NfY8IXhp85Rd8uPBMtK5icl5wTV7wK1djcP_ZGwKZMi0encKpt-v_CpV2whg4BWPDnYCNo1aPOUGTASB2NxfqexvcTI/s320/60EF017D-945E-4F0B-B138-050329731CAB_4_5005_c.jpeg" width="320" /></a></div><br />At the beginning of the sprint, the testers have nothing to do. At the end of the sprint, the devs have nothing to do.</div><br /><div><br /></div><div>There are dozens of suggested solutions to this out there, and they mostly talk about doing lots of little things to improve the situation. Testers can be preparing test cases at the beginning of the sprint, devs can be doing non-testable infrastructure work at the end. There are a couple of good posts dealing with this here:</div><div><br /></div><div><a href="https://pm.stackexchange.com/questions/18019/how-to-organise-manual-testing-in-a-scrum-team">https://pm.stackexchange.com/questions/18019/how-to-organise-manual-testing-in-a-scrum-team</a></div><div><br /></div><div><a href="https://www.linkedin.com/pulse/manual-testing-scrum-hard-impossible-lesley-wallace-csm-sa">https://www.linkedin.com/pulse/manual-testing-scrum-hard-impossible-lesley-wallace-csm-sa</a></div><div><br /></div><div><br /></div><div>That second one caught my eye: 'Manual testing in scrum is hard, but not impossible'. That's a massive alarm bell. Development processes shouldn't be hard, that just discourages people and stops development being fun. If a process is hard, people won't do it, and they certainly won't do it consistently in the future. Eliminate obstacles, don't build a staircase over them.</div><div><br /></div><div>One of the commonest things that's advocated to address this problem is to make your PBIs smaller. While that's worthwhile anyway, and it can help a bit, it still doesn't fix the problem. Even a PBI that takes 3 hours to develop and an hour to test still leaves slack time at each end, and requires a lot of extra effort on the part of the team to break down & refine**.</div><div><br /></div><div>There are a couple of simple ways you can reconcile manual testing with scrum without making it painful, I'm going to talk about two of them:</div><div><br /></div><h4 style="text-align: left;">Simultaneous Testing</h4><div>In theory a PBI follows a linear path like this:</div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3pQSjRJuP-hpzHlqxKhTRvBOFpQx7_R3ffSxo0C717_e9g7FcUrMuuxg5VA2bobwx8KU0KYH2TZ2D6WtnWECOKYIp2UfXtfkoZWCzLneNUmnLUPiCD3jZbyuh4udoaToHNivX2-NlTFY/s960/36604436-82F2-404A-A33C-5313EC90CFFF_4_5005_c.jpeg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="159" data-original-width="960" height="108" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3pQSjRJuP-hpzHlqxKhTRvBOFpQx7_R3ffSxo0C717_e9g7FcUrMuuxg5VA2bobwx8KU0KYH2TZ2D6WtnWECOKYIp2UfXtfkoZWCzLneNUmnLUPiCD3jZbyuh4udoaToHNivX2-NlTFY/w652-h108/36604436-82F2-404A-A33C-5313EC90CFFF_4_5005_c.jpeg" width="652" /></a></div><br /><div>In practice it usually looks a lot more like this:</div><div><br /></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhO5F3FJ4vRn538OW1Z9EN7w4BnaUs5aPZVpLvTypSqHLCtZoec_swGtEcE20rf8HsWnSMSI8B_4EDXgHDuW4A_o5oBcVy77WohsROp7xphhwLge3yyxdIJWfmgL3gf6wZJUOGQR9fm4Jk/s958/7D32F030-92C4-4BBB-8D4C-C8A636A1D42B_4_5005_c.jpeg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="236" data-original-width="958" height="159" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhO5F3FJ4vRn538OW1Z9EN7w4BnaUs5aPZVpLvTypSqHLCtZoec_swGtEcE20rf8HsWnSMSI8B_4EDXgHDuW4A_o5oBcVy77WohsROp7xphhwLge3yyxdIJWfmgL3gf6wZJUOGQR9fm4Jk/w643-h159/7D32F030-92C4-4BBB-8D4C-C8A636A1D42B_4_5005_c.jpeg" width="643" /></a></div><div><br /></div>Code is written, committed, tested and bugs are found. Once that cycle is complete it's merged, and quite frequently more bugs are found (usually when it gets migrated into another environment).<div><div class="separator" style="clear: both; text-align: center;"><br /></div>Each of those transitions from 'Write code' through to 'test' takes time. Tickets move around the Jira board, people look for something ready to work on, and very often a tester won't actually start work on a PBI until it's formally moved into a 'testing' column on the sprint backlog. What might work better is to have the tester picking up in progress work. We talk about 'commit early and often' - what's to stop a tester reading the commit message, working out what can be tinkered with and starting to test it? Yes, it's not finished, but bugs can still be found, and if we're going to have that cycle back and forth between the dev and the tester anyway, why not do it without the overhead.</div><div><br /></div><div>This approach means stopping thinking about PBIs as 'done, then tested' and making the process more iterative and collaborative. But that's exactly what agile is all about - having that 'dev, then test' approach looks a lot like mini waterfall.</div><div><br /></div><h4 style="text-align: left;">Test the increment</h4><div>Testing a PBI against requirements and marking it as 'OK' in sprint has one massive problem - you're still changing the code. We all work hard to make code modular and loosely coupled, but the nature of sprint goals, epics and business requirements means that we're generally working in the same approximate area of code throughout the sprint. So you complete a PBI, the tester signs it off, and 5 minutes later someone commits a change that breaks it. The tester then tests the functionality they've changed, and a regression set that may not test your change, and a broken increment comes out of the end of the sprint.</div><div><br /></div><div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9m8QkkK4L2D3wA4rVm0Nw1vRQxlFKnCqSmKnnMDotQsghG3lbOIcBJAC6DLvdIAfmXSKPc5FBK2I6vAM6m-ZD2YYRDvG3KIilIa0K8Kynl0QOjYB_1ZGEf-hWPpGmYhxMXJvtQ1UiLeI/s959/25E4DDC9-441E-4CC8-BB01-B5E3C692F3C9_1_201_a.jpeg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="393" data-original-width="959" height="256" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9m8QkkK4L2D3wA4rVm0Nw1vRQxlFKnCqSmKnnMDotQsghG3lbOIcBJAC6DLvdIAfmXSKPc5FBK2I6vAM6m-ZD2YYRDvG3KIilIa0K8Kynl0QOjYB_1ZGEf-hWPpGmYhxMXJvtQ1UiLeI/w625-h256/25E4DDC9-441E-4CC8-BB01-B5E3C692F3C9_1_201_a.jpeg" width="625" /></a></div><br /><div class="separator" style="clear: both; text-align: center;"><br /></div></div><div>Testing the increment means separating formal testing from the development process and making it a QA process instead. Normally you're going to want to reflect that in the organisational structure, which helps to make the testers independent again. You can still have strong relationships between testers and devs - that "is it supposed to do this?" conversation still needs to happen.</div><div><br /></div><div>But if the code isn't formally tested, how do we know it's right? Good automated testing skills are part of a devs toolkit, it's as important as writing the code.</div><div><br /></div><div>Testing the change is the developers job. The testers job is validating the <i>product</i>.</div><div><br /></div><div>The big drawback that gets raised to 'testing the increment' is that it slows down fixing of bugs, because the bug doesn't get tested until the sprint after it's fixed. While that's kind of true, sometimes, that increment is also stable so the risk of other bugs being introduced is less, and nothing stops you sidestepping the system for an emergency fix. In any case, very often you find bugs well after a change has been merged anyway.</div><div><br /></div><h4 style="text-align: left;">Conclusion</h4><div>Testing the increment is my preferred approach - I think there are still massive inefficiencies in the simultaneous testing method, and it's probably not enough on it's own to fix the problem. Testing the increment is a significant change in approach, but it separates the workflows and gives you more confidence that the increment is OK.</div><div></div><div><br /></div><div>So if you're running into this problem with slack time in sprints and testing is getting pushed into the last couple of days, it might be worth experimenting with one of these approaches to see if that makes your process smoother.</div><div><br /><br /></div><div><br /></div><div><br /></div><div>** there's also a tension between breaking things down into the smallest components you can, and what actually counts as a user story. It's pretty hard to say 'as a user, I want the small piece of prep work that combined with six other things will enable me to....'.</div><div><br /></div><div><br /></div>MrHarehttp://www.blogger.com/profile/07813011371392466114noreply@blogger.com0tag:blogger.com,1999:blog-500350328047207051.post-61838682033761729722020-12-18T06:45:00.000-08:002020-12-18T06:45:15.406-08:00Error Patterns - mistakes so common they become a pattern<p>What's wrong with this pseudo code?</p><p>"We need to get all entries for a given date, or today if the date isn't specified"</p><p><span style="background-color: #eeeeee;"><span style="font-family: courier;">@controller</span></span></p><p><span style="background-color: #eeeeee;"><span style="font-family: courier;">EntriesDto getEntries(Date searchDate=Date.now()){}</span></span></p><p>I made this mistake a couple of times before it properly sank in, and I just ran into it again. If you're still looking at it thinking "nope, can't see a problem", it's the assumption that the consumer and the api are in the same locale. This will work a lot of the time, but around midnight on certain days in certain months the result could be a day earlier than you expect, as daylight saving switches over.</p><p>Another daylight saving error I've run into more than once is:</p><p>"if we consistently use UTC we don't need to worry about daylight saving".</p><p>It's better, but you still do need to think about it. Because although you might be using UTC consistently you can be certain your end user isn't. Somewhere around there will have to be some conversion. I usually try to do that conversion at the view, because obviously, but where you're using some variant of <span style="background-color: #eeeeee; font-family: courier;">Date.now()</span><span style="background-color: white;"><span style="font-family: courier;"> </span><span style="font-family: inherit;">in end user client side code (e.g. browser) you're going to run into problems, because the client machine will have a locale setting convenient for the user.</span></span></p><p><span style="background-color: white;"><span style="font-family: inherit;">I couldn't see that this class of error has a name, so I'm referring to them as 'Error Patterns', code errors that happen repeatedly in a consistent way.</span></span></p><p><br /></p>MrHarehttp://www.blogger.com/profile/07813011371392466114noreply@blogger.com0tag:blogger.com,1999:blog-500350328047207051.post-86976449012028676322017-05-13T06:44:00.000-07:002017-05-13T06:44:20.203-07:00Getting into the software development businessA couple of weeks back I spent the day at the <a href="https://herd.careers/events/leeds-digital-job-fair-3-0-2/">Leeds Digital Job Fair</a>. I've been doing a lot of recruitment for the last few months, and been fortunate enough to find a few good developers to join our dev teams.<br />
<br />
Hardly a month goes by when I don't get asked "( I | a friend | a colleague ) wants to move into software development from (some totally unrelated field), how should ( I | they ) go about it?". This post aims to consolidate my answers to that question.<br /><br />Everything that follows is my own opinion. But bear in mind, I (and other devs like me) am the one who decides whether you get an interview or not based on your training & experience.<br />
<br />
First of all, be realistic. Yes, there are jobs out there paying big money for good developers. They require experience - lots of experience. You really aren't going to get a 50k GBP job (2017 Northern England rates) based on no experience and a boot camp course.<br />
<br />
Speaking of boot camps, there are lots of companies out there doing introductory software development courses of very varied cost and quality. I saw one charging 6k for a syllabus that made no sense to me, and another at half that price that was much more coherent. RESIST THE SALESPEOPLE! Make an informed decision - I'm guessing if you want to get into dev then you're maybe in a lower paid job, so you can't afford to throw money away.<br />
<br />
Here's my list of most important pointers:<br />
<br />
1. If you regard learning new things as a chore, forget it altogether. You cannot function as a developer without learning new things all the time. If you don't enjoy that, you will hate it.<br />
<br />
2. Experience is everything, and you don't have any. So get some: write websites for yourself, friends, clubs, local charities. Look at getting involved in open source projects, maybe do some documentation for them if your coding isn't good enough to contribute code.<br />
<br />
3. Don't try and learn everything at once, pick a coherent direction and follow it. I've seen courses promising to teach 'full stack'. IMO learning to be a full stack developer takes time and experience.<br />
<br />Coherent directions might be:<br />
<ul>
<li>Java</li>
<li>Javascript, Node.js, Catalyst</li>
<li>PHP </li>
<li>Python</li>
<li>C# and Visual Studio</li>
<li>some other language and context </li>
</ul>
(Every developer needs to know some HTML/CSS, but unless you're a web designer rather than a developer, those skills alone will not be enough.)<br /><br />4. If you're going to shell out a load of cash on a training course, choose carefully. Ask for advice, assess whether the syllabus looks coherent or will just give you a smattering of widely different topics.<br /><br />5. There is a lot more to it than just being able to write code. Any jobbing developer has a working knowledge of the following<br /><ul>
<li>Libraries and frameworks (jQuery, Catalyst, Spring, Hibernate etc etc etc, depends on what they're working on and in what language)</li>
<li>Unit testing (and writing code that's easy to test)</li>
<li>Agile methodologies (e.g. scrum</li>
<li>Algorithms</li>
<li>Continuous integration and build tools (Jenkins, maven, teamcity..)</li>
</ul>
<br />
If you can talk sensibly about these things in an interview, I'm going to take you more seriously whether you have commercial experience or not. You can get experience of them by downloading and experimenting with open source code.<br /><br />
6. LEARN AN IDE! It doesn't matter much which one, choose whatever is in widespread use for your language/platform. The important thing is to learn about:<br />
<ul>
<li>the debugger - most languages have one, they allow you to pause the code and see what's happening in real time. You won't realise how important that is until you've done it.</li>
<li>code completion - the IDE will give you hints about what to type next, this can save you a lot of time</li>
<li>code navigation - moving around a complex project with hundreds of source files is painfully slow without an IDE, and instantaneous with.</li>
<li>build tools - the IDE normally has build and run tools built in, this will save you time and also help you to learn the build tools.</li>
</ul>
<br />OK, so all that was probably a bit intense and daunting. Here's the lighter side: I've been working in the computer industry now for about 25 years, 15 as a developer. I'm learning new things every day, and having an enormous amount of fun at it. A lot of software development is about financial systems, or ecommerce sites, but software permeates every aspect of life. I've been lucky enough to work in ethically valuable fields for many years, but even before that I contributed to open source projects, including software to make the lives of severely disabled people easier. Writing code can be great fun, and it can be a worthwhile thing to do.<br />
<br />
<br />
<br />
<br />
Good luck :)<br />MrHarehttp://www.blogger.com/profile/07813011371392466114noreply@blogger.com0tag:blogger.com,1999:blog-500350328047207051.post-72230107011582895392016-07-01T02:39:00.000-07:002016-07-01T02:39:47.382-07:00Key programming booksA top 5 of programming or related topics books I've found most useful:<br />
<br />
Pragmatic Programmer<br />
The Mythical Man Month<br />
Perl Testing, a developers notebook<br />
UML in 24 hours<br />
The Design of Everyday Things <br />
<br />
<br />
I'll blog details of each one later, in particular 'The Design of Everyday Things' which isn't an obvious 'programming' related book.MrHarehttp://www.blogger.com/profile/07813011371392466114noreply@blogger.com0tag:blogger.com,1999:blog-500350328047207051.post-79261985349523184252016-06-13T08:47:00.001-07:002016-06-13T08:47:45.144-07:00Dangerous design flaw in wordpressWordpress insists on storing fully qualified URLs all over the place. Especially in the database. This means that if you restore a backup of a wordpress installation onto another machine (a test/dev machine for example), you can unexpectedly end up being switched to the live site at any moment.<br /><br />Add to this the fact that as previously complained about, the whole thing is stored in the database, so you are logging into a dev machine with the same user account as live, and the potential for catastrophe is huge.MrHarehttp://www.blogger.com/profile/07813011371392466114noreply@blogger.com0tag:blogger.com,1999:blog-500350328047207051.post-2034370819486855742016-06-06T03:57:00.001-07:002016-06-06T04:01:54.197-07:00fun with recursive chown and dotfiles<pre style="background: #f0f0f0; border: 1px dashed #cccccc; color: black; font-family: "arial"; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> rm -rf .* </code></pre>
<div class="_1mf _1mj" data-offset-key="a3e2f-0-0" style="direction: ltr; position: relative;">
<span data-offset-key="a3e2f-0-0">removes all hidden subdirectories and their contents, but generates an error and does nothing when it tries to remove '.' and '..'</span></div>
<span data-offset-key="c5par-0-0">I've always just accepted that behaviour without thinking. I now discover that it's the wrong thing to do. I discovered this by doing</span>
<br />
<pre style="background: #f0f0f0; border: 1px dashed #cccccc; color: black; font-family: "arial"; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> chown -R codehare:codehare .* </code></pre>
<span data-offset-key="dutuc-0-0">This has a very unexpected effect. A very bad, very unexpected effect. It chowns everything that matches .* (i.e. hidden directories) in the current directory, <i>then it starts in the parent directory and recurses through all subdirectories of that.
</i>
This is not good news. Especially if you do it as root/sudo. Especially if you do it in a home directory. Especially if you use key based authentication.</span><br />
<span data-offset-key="dutuc-0-0"><br /></span>
<span data-offset-key="dutuc-0-0">Well that was a fun start to the week...</span>
MrHarehttp://www.blogger.com/profile/07813011371392466114noreply@blogger.com0tag:blogger.com,1999:blog-500350328047207051.post-55977727456867196672016-05-10T05:24:00.003-07:002016-05-10T05:24:52.520-07:00Wordpress - yet more 'everything done in live' horror.I've just restored a copy of a wordpress DB from a colleagues dev machine. When I run it up locally none of the resources (CSS etc) are accessible because the base URL is wrong.<br /><br />It turns out that all URLs are absolute, and written into the database. Tools apparently exist to traverse the database changing all these entries.<br /><br />This really is appallingly noddy and unprofessional. It's no wonder web development as a discipline has such a dreadful reputation.MrHarehttp://www.blogger.com/profile/07813011371392466114noreply@blogger.com0tag:blogger.com,1999:blog-500350328047207051.post-80582597786987297072016-05-03T08:25:00.000-07:002016-05-03T08:25:24.826-07:0012 FactorThis is a good set of principles for neatly encapsulated services. In many ways it reads like the SOA special case of the Pragmatic Programmer. This is what SOA promised from the start<br /><br /><a href="http://12factor.net/">http://12factor.net/</a><br />
<br />
<br />MrHarehttp://www.blogger.com/profile/07813011371392466114noreply@blogger.com0tag:blogger.com,1999:blog-500350328047207051.post-2361897061173819692016-04-29T04:19:00.001-07:002016-04-29T04:19:46.903-07:00When writing documentationTip for developers when writing documentation. Normal people (by which I mean non-developers) do not look at 5000 word blocks of solid text and think "yay! Lots of useful information!".<br />
<br />
Diagrams in documentation don't have to convey any illuminating and helpful points. Sometimes they can just be a way of stopping your reader bursting into tears before the halfway point.MrHarehttp://www.blogger.com/profile/07813011371392466114noreply@blogger.com0tag:blogger.com,1999:blog-500350328047207051.post-71033867966341730662016-04-18T04:58:00.002-07:002016-04-18T05:09:24.517-07:00Everything that is wrong with web development is perpetuated by the market leading CMSesAs I've said before, I'm not a web developer. I work for a small software house though, and as a result I end up doing a fair amount of web development. It's an experience that always leaves me wanting to wash. With bleach.<br />
<br />
The last couple of years, focus on virtualization has started to move from the big, heavyweight server virtualization platforms like ESX towards virtualization of services or microservices. This is finally starting to realise the promise of SOA in smaller, non-enterprise environments. Docker can run containers on virtualized platforms like AWS to massively simplify deployment and management.<br />
<br />
But when you start trying to use this in reality you run into the problem of the CMS. Customers want CMSes - they want to pay for us to set up their site, but have the option to do little tweaks and edits themselves. Web development on the smaller scale end, providing simple sites that are updated a couple of times a month for businesses of up to 20 staff or so; and ecommerce sites for marginal 'run from a bedroom' businesses, small shopfronts etc., is totally dominated by 2 CMSes - Wordpress and Joomla*. There's not a lot to choose between them: both backend into MySQL, both are written in PHP, both have a huge estate of plugins.<br />
<br />
The worst problem with web development is that so much of it happens in production. We bemoan 'bedroom programmers' and the amateurish habits of a lot of web developers, but in reality this happens because of the CMS. The CMS stores page content in the database. When you are developing a site for a customer the 'product' you are producing is scattered across template files and database entries. Those database entries are stored on a database engine along with a load of other products. Yes, you can dig them out with database queries, but it's still a mess of jumbled string with no sense of encapsulation. This makes staged deployment impractical**.<br />
<br />
This is why everything happens in production, because it's all but impossible to have proper staging and controlled release. All the amateurish shit that happens in web development logically flows from that one place.<br />
<br />
Is there an answer? Probably. CMSes backending into MySQL are the source of the problem, especially at this level. Serving from files is faster, more reliable, more scale appropriate and makes it possible to use proper versioning tools. It's only inertia and the availability of plugins that keeps us using them. My favoured approach would be something like Grav running in a docker container, and since Grav has a shopping cart it should be straightforword to do.<br />
<br />
Time to do some experimenting.<br />
<br />
<a href="https://getgrav.org/">https://getgrav.org/</a><br />
<br />
<a href="https://gravshoppingcart.com/">https://gravshoppingcart.com/</a><br />
<br />
* Drupal is a bit bigger scale, but suffers from exactly the same problems.<br />
** Yes yes, I know. Vagrant, Ansible, Puppet etc. Very powerful tools that, in this context, do a great job of making up for the design shortcoming that MySQL backed CMSes don't encapsulate properly.<br />
<br />MrHarehttp://www.blogger.com/profile/07813011371392466114noreply@blogger.com0tag:blogger.com,1999:blog-500350328047207051.post-66776610455962234632016-03-15T08:21:00.000-07:002016-03-15T08:27:37.214-07:00Android, invisible files, and folders that look like empty filesUgh.<br />
<br />
That took a long time, a lot of poking, swearing, reading stackoverflow, more poking, more swearing, and finally digging around in an open source file manager to find out how they'd done it.<br />
<br />
So.<br />
<br />
If you create a file on an Android device and attempt to view it with MTP/PTP, and it isn't there, you need to do this:<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(f)));
</code></pre>
<pre style="background-color: white; font-family: 'Courier New'; font-size: 9pt;"><span style="font-family: "times new roman"; font-size: small; white-space: normal;">
</span></pre>
<pre style="background-color: white; font-family: 'Courier New'; font-size: 9pt;"><span style="font-family: "times new roman"; font-size: small; white-space: normal;">That tells the media scanner that it needs to know about this new file.
Cool. Great. Now, don't do this.</span></pre>
<pre style="background-color: white; font-family: 'Courier New'; font-size: 9pt;"><span style="font-family: "times new roman"; font-size: small; white-space: normal;">
</span></pre>
<pre style="background-color: white; font-family: 'Courier New'; font-size: 9pt;"><span style="font-family: "times new roman"; font-size: small; white-space: normal;">
</span></pre>
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>File f = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "MyStuff/");
f.mkdirs();
//THIS! DON'T DO THIS ON A DIRECTORY!
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(f)));
</code></pre>
<pre style="font-family: 'Courier New'; font-size: 9pt;"><span style="font-family: "times new roman"; font-size: small; white-space: normal;">
</span></pre>
<pre style="font-family: 'Courier New'; font-size: 9pt;"><span style="font-family: "times new roman"; font-size: small; white-space: normal;">
</span></pre>
<pre style="font-family: 'Courier New'; font-size: 9pt;"><span style="font-family: "times new roman"; font-size: small; white-space: normal;">Or you'll end up with folders that you can't access from windows via MTP/PTP. They'll look like empty/unknown type files. Just do</span></pre>
<pre style="font-family: 'Courier New'; font-size: 9pt;"><span style="font-family: "times new roman"; font-size: small; white-space: normal;">
</span></pre>
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>File f = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "MyStuff/");
f.mkdirs();
</code></pre>
<pre><span style="font-family: "times new roman";"><span style="white-space: normal;">
</span></span></pre>
<pre><span style="font-family: "times new roman";"><span style="white-space: normal;">and the folder will appear straight away as it should.</span></span></pre>
<pre><span style="font-family: "times new roman";"><span style="white-space: normal;">
</span></span></pre>
<pre><span style="font-family: "times new roman";"><span style="white-space: normal;">
</span></span></pre>
<div style="font-family: 'Courier New'; font-size: 9pt;">
<span style="font-family: "times new roman"; font-size: small; white-space: normal;">
</span></div>
<pre style="font-family: 'Courier New'; font-size: 9pt;"><i>
</i></pre>
MrHarehttp://www.blogger.com/profile/07813011371392466114noreply@blogger.com0tag:blogger.com,1999:blog-500350328047207051.post-46940051006990935522016-01-04T02:14:00.003-08:002016-01-04T02:14:56.558-08:00Reading android sqlite db - quick and hacky wayfrom platform-tools<br />
<br />
<span style="background-color: #eeeeee; color: #222426; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, sans-serif; font-size: 13px; line-height: 16.9px;">adb shell run-as uk.co.myco cat databases/data.db > data.db</span><br />
<span style="background-color: #eeeeee; color: #222426; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, sans-serif; font-size: 13px; line-height: 16.9px;"><br /></span>
<span style="background-color: #eeeeee; color: #222426; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, sans-serif; font-size: 13px; line-height: 16.9px;">then sqlite3 the db file</span>MrHarehttp://www.blogger.com/profile/07813011371392466114noreply@blogger.com0tag:blogger.com,1999:blog-500350328047207051.post-63835926181424396682015-12-03T04:15:00.002-08:002015-12-03T04:15:32.831-08:00PHP 5.3, Drupal 6, SMTP Authentication, AWS and 'Could not connect to SMTP host.'I haven't got to the bottom of exactly why this is happening, but if you're trying to get the following combination working<br />
<br />
<br />
<ul>
<li>Drupal 6</li>
<li>SMTP Authentication 6.x.1.1 with PHPmailer</li>
<li>PHP 5.3</li>
</ul>
<div>
<br /></div>
<div>
and you get the error 'Could not connect to SMTP host', you can fix it as follows:</div>
<div>
<br /></div>
<br />
<div>
// Set other connection settings. // LINE 785</div>
<div>
<div>
$mail->Host = variable_get('smtp_host', '') .';'. variable_get('smtp_hostbackup', '');</div>
<div>
$mail->Port = variable_get('smtp_port', '25');</div>
<div>
$mail->Mailer = 'smtp'; // COMMENT OUT THIS LINE </div>
<div>
<br /></div>
<div>
I suspect from the debug with the $mail->Mailer='smtp' flag it is sending smtp commands in clear, not starting tls.</div>
<div>
<br /></div>
</div>
MrHarehttp://www.blogger.com/profile/07813011371392466114noreply@blogger.com0tag:blogger.com,1999:blog-500350328047207051.post-33086297960944141902015-10-29T06:59:00.000-07:002016-04-26T09:04:03.471-07:00Programming and journalismI was struck recently by the parallels between journalism and programming. I've written a few articles for different publications over the years and learned a bit from the editors of journals about what they wanted the copy to look like. Certain things stuck out as being either similar, or lessons that developers could learn from journalists:<br />
<br />
<h4>
House Style</h4>
<div>
Every publication has it's house style. Tabloid newspapers use short, declarative sentences, limited vocabulary, and lots of emotive language. Academic journals all prefer their text to be in the third person. Orthography varies too, the house style always defines layout, fonts etc.</div>
<div>
<br /></div>
<div>
Similarly, a development team/organisation often has a requirement for the following:<br />
<ul>
<li>bracing style</li>
<li>naming conventions</li>
<li>comments / inline documentation</li>
</ul>
<div>
In environments that lack a house style document, I've sometimes written one up by querying the preferred style with the existing team. It makes code easier to read and more consistent.</div>
</div>
<br />
<h4>
Editorial requirements</h4>
<div>
This is more something that should be, than something that is. Code review often tends to be neglected, mainly because project timescales are often tight. For reasons why <i>that</i> is the case, see Frederick Brooks' "The Mythical Man Month". If you follow Brooks' advice of having one person integrating code, they're effectively doing the job that a publication editor/subeditor does - checking that content is formatted correctly, readable, fits with house style and so on, to make a consistent product.</div>
<div>
<br /></div>
<h4>
Specialisms and research</h4>
<div>
Everyone has their specialities. I specialise in Assistive/Care oriented Technology, identity management, web services and a few other less well defined things. I speak Java, Perl, PHP, Javascript, and to a lesser extent Ruby.</div>
<div>
<br /></div>
<div>
But like a journalist called upon to write outside their speciality with good research disciplines and care a developer can do a decent job outside their immediate speciality, or learn a new one rapidly. The economics correspondent can do a decent job of reporting political stories, and the server developer can make a decent job of web development if needed.</div>
<div>
<br /></div>
<div>
<br /></div>
<h4>
Any others?</h4>
<div>
I'm sure there must be other parallels. I'll update this post if I think of any.</div>
<br />
<br />MrHarehttp://www.blogger.com/profile/07813011371392466114noreply@blogger.com0tag:blogger.com,1999:blog-500350328047207051.post-61644815667911128302015-07-23T03:08:00.000-07:002016-09-04T03:20:02.097-07:00What makes a maintenance programmerI love maintenance programming. This makes me a freak among developers. If you look at the job adverts, they're all full of 'greenfield development', 'the chance to define direction' and similar phrases. Original development is interesting and fun, but there's a lot to be said for the Sherlock Holmes experience of bug fixing someone else's code. You have to put yourself in their position, learn from their coding style how they're likely to have approached a problem, keep track of complex code pathways to remember where you are. It's extremely tiring because the concentration demands are high, but it's a fascinating challenge.<br />
<br />
It's always useful to be good at, and interested in something most other people hate. Anyone got any really ropey legacy applications they want maintaining?<br />MrHarehttp://www.blogger.com/profile/07813011371392466114noreply@blogger.com0tag:blogger.com,1999:blog-500350328047207051.post-23842541966136642902015-06-25T04:22:00.002-07:002015-06-25T04:22:25.641-07:00Eclipse juno, getting rid of mylynThis morning I've done about 60 minutes work. The other 120 minutes was spent watching the 'busy' pointer, waiting for eclipse to do.....something.<br />
<br />
Experience tells me it's something mylyn related. Unfortunately Juno comes with mylyn, and it's not easy to remove.<br /><br />Or is it?<br /><br />Preferences->Java->editor->content assist->advanced.<br /><br />Deselect anything marked 'task oriented', and replace it with the non task-oriented version.<br /><br />Now go into your eclipse plugins folder and remove anything to do with mylyn.<br /><br />Hurray! My IDE works again :-)MrHarehttp://www.blogger.com/profile/07813011371392466114noreply@blogger.com0tag:blogger.com,1999:blog-500350328047207051.post-84445179419266402792015-02-08T10:06:00.002-08:002015-02-08T10:06:56.410-08:00A simple solution to the plague of automated sales callsThe last few years, the problem of automated sales calls, both those that connect you to a salesperson, and lately the much worse ones that play an automated message, has got out of hand. There is a very simple solution - it does require legislation, and a little technical implementation, but it exists:<br />
<div>
<br /></div>
<div>
Step one:</div>
<div>
<br /></div>
<div>
legislate cold calling as an offence, particularly calls with a recorded message. 1000 GBP per offence strikes me as a nice sized penalty. Place the onus on the caller to prove that the recipient has opted in to their mailing list.</div>
<div>
<br /></div>
<div>
"But", I hear you protest, "we have legislation to prosecute cold callers already and it never gets enforced. The caller just withholds their number or provides a bogus one".</div>
<div>
<br /></div>
<div>
That's where step two comes in:<br />
</div>
<div>
introduce an offence - routing a call where caller ID isn't presented. Large penalties on the telecoms companies for failing to provide <b>accurate</b> caller ID information on every call. Domestic subscribers don't see this, but multi-line commercial phone connections include the facility to set up the caller ID. The s<i>ubscriber</i> chooses what caller ID to present to public view. That's why you get calls from "12340 000000" etc.</div>
<div>
<br /></div>
<div>
There are a few possible objections:<br />
<br />
"It's important to allow subscribers to withhold their number to protect their privacy" - ok, so if a domestic subscriber requests to withhold their number, present a separate number that won't connect to them, but is nevertheless registered with their phone company to their name.</div>
<div>
<br /></div>
<div>
"Sometimes we don't have the caller ID information" - the telecoms companies <b>always</b> have an origin of the call - otherwise, how would they know who to bill? It's a fairly trivial software problem to present it. If it's a call coming in from outside their network (like an international call), they can present a number for the telecoms company routing the call. We'd soon get to know who the spammers were, and start blocking them. If XYZ telecom is the origin of 90% of my spam phone calls, I'm going to block it whether any of my friends use it or not, then suggest to them that they move providers.</div>
<div>
<br /></div>
<div>
"It's too technically complex" - not true, see above.<br />
<br />
"It's too expensive" - really not true, see above.<br />
<br />
<br />
<br />
A year or two of that, and we'd soon see an end to<br /><br />"You may be entitled to a refund on your PPI payments....."</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
MrHarehttp://www.blogger.com/profile/07813011371392466114noreply@blogger.com0tag:blogger.com,1999:blog-500350328047207051.post-20376561256443416142014-10-16T07:38:00.001-07:002015-02-08T10:35:28.027-08:00Freeswitch WTF?Freeswitch is apparently 'very NAT friendly'.<br />
<br />
No kidding. I've spent most of today trying to stop it from binding to the outside of the firewall and allowing anyone and everyone to try and authenticate, filling my logfiles with shite.<br />
<br />
-nonat -nonatmap - doesn't appear to work, on windows at least. Nor does any combination of them.<br />
<br />
commenting out every instance of<br />
<br />
<param name="ext-rtp-ip" value="auto-nat"/><br />
<param name="ext-sip-ip" value="auto-nat"/><br />
<br />
doesn't work<br />
<br />
<param name="ext-rtp-ip" value="192.168.255.255"/><br />
<param name="ext-sip-ip" value="192.168.255.255"/><br />
<div>
<br /></div>
<div>
doesn't work.</div>
<div>
<br /></div>
<div>
At the moment, I just want to use this thing internally as a test switch. I'm spending a *lot* of time trying to lock down the default config, instead of debugging my code. This is not good, and inside a private network it should not be necessary.<br />
<br />
Addendum:<br />
<br />
I raised the question (extremely politely) on the freeswitch users mailing list, and got this response from one of the projects senior members:<br />
<span style="background-color: #b6d7a8;"><br />"It has NOTHING at all to do with the ext-sip-ip and ext-rtp-ip settings, If</span><br />
<pre><span style="background-color: #b6d7a8;">you don't want outside access then block it at your nat/firewall."</span></pre>
<pre><span style="background-color: #b6d7a8;">
</span></pre>
<span style="background-color: white;">That's all - no "Hi", no sign off, just that. Rude, aggressive, shouty and unhelpful.<br /><br />I'm using Asterisk now. Ho hum.</span><br />
<pre></pre>
<pre></pre>
</div>
<div>
<br /></div>
<div>
<br /></div>
MrHarehttp://www.blogger.com/profile/07813011371392466114noreply@blogger.com0tag:blogger.com,1999:blog-500350328047207051.post-12846328923930738532014-09-29T02:56:00.000-07:002014-09-29T04:22:02.332-07:00A very short introduction to software testing<b>1. Introduction</b><br />
<br />
This is intended as a very short introduction to testing, for programming novices and beginner developers without a lot of formal training. Skilled developers will find much to criticise here because I've necessarily simplified things a lot, but they're not the target audience.<br />
<br />
<b>2. Why do we test?</b><br />
<br />
We test because bugs are inevitable. Software is complex. Very complex. The number of variables involved in any non-trivial program rapidly becomes impossible to keep a track of, and as soon as you can't conceptualise your entire program mentally throughout it's run cycle, things are going to slip through the cracks.<br />
<br />
We test because we don't want those bugs to cause problems.<br />
<br />
We also test because we don't want bugs to slow the development cycle down: if you do no testing at all, when the code goes for UAT (see 'types of testing'), the user finds shedloads of bugs, writes them up and you fix them. But that takes a lot more time than you finding most of the bugs as you go along. Plus you look like a pillock if your code is really buggy.<br />
<br />
<br />
<b>2. Ways of testing</b><br />
<br />
<b>Basic 'try it through the UI' </b>- assuming your code has a UI, just run through it the way the user would. To make sure you're trying every pathway, you need to produce <b>use cases</b>. These are the different ways in which the program will be used: for example, a typical use case for using a 'user profile edit' component might be:<br />
<br />
Select user<br />
Click edit<br />
Change 1 or more details<br />
Click save<br />
<br />
Don't forget about the 'change your mind' scenarios like:<br />
<br />
Select user<br />
Click edit<br />
Change your mind and click cancel.<br />
<br />
<br />
<b>Automated testing </b>- this is the preferred way of doing things. Most languages have a preferred test framework (jUnit in Java, Test::More in Perl etc). There are advantages and disadvantages to automated testing:<br />
<br />
<b>Pros</b>:<br />
<ul>
<li>you only have to write the test once</li>
<li>changes to code can be easily checked for knock on effects elsewhere</li>
<li>during slow periods in a project, writing tests is a productive use of time</li>
<li>automated tools exist to identify which parts of your code are tested and which aren't</li>
</ul>
<b>Cons</b>:<br />
<br />
<ul>
<li>the test suite is more code to maintain</li>
<li>Writing a test case usually takes longer than testing the UI, when under time pressure it can be easier just to test the UI</li>
<li>Creating and maintaining test data can be a pain - databases usually need to be 'mocked', as do network services, which is extra overhead.</li>
<li>Some thought needs to go into designing your test suite if you don't want to end up with tons of cut and paste code, this takes time.</li>
</ul>
Generally, I find that automated testing results in better, more reliable code and fewer bugs reaching regression testing (see below) but does often take up more time. In a project where the user / project management wants the moon on a stick, yesterday if not sooner, it can be difficult to find time to build proper test suites. This is one of the many reasons why projects run that way tend to result in low quality code (note to project managers - setting short deadlines is <b>not</b> an effective way of getting the most out of a development team. Go read 'The Mythical Man Month'. Do it now).<br />
<br />
<b>3. Types of testing</b><br />
<br />
<b>Smoke </b>- literally 'switch it on, does it catch fire'. Compile the code, run it, see if any exceptions are thrown.<br />
<br />
<b>Unit </b>- testing the component you've been working on.<br />
<br />
<b>Integration </b>- test the integration of the component with the rest of the software suite, make sure that you haven't buggered anything elsewhere in the suite by this set of changes.<br />
<br />
<b>Functional </b>- test the functionality of the program. Specifically, test the functionality you have been working on in this development cycle.<br />
<div>
<br /></div>
<b>Regression </b>- test everything, to make sure that the whole suite works.<br />
<br />
<b>UAT </b>- user acceptance testing: performed by the customer/consumer to ensure that they are satisfied with the product.<br />
<br />
<br />
<b>4. Test Driven Development</b><br />
<b><br /></b>
TDD is a way of producing very high quality code in a mature development environment. Under TDD, the tests are developed <i>first</i>, from the design documentation. The functional code is then written to fulfil the tests. That way, you're absolutely certain that your code matches the design.<br />
<br />
<br />
<b>5. Conclusion</b><br />
<b><br /></b>
Structured formal testing is a vital part of professional development, and testing skills are an integral part of what makes a good developer. Good code testing skills will make a huge difference to the quality of your code.MrHarehttp://www.blogger.com/profile/07813011371392466114noreply@blogger.com0tag:blogger.com,1999:blog-500350328047207051.post-1606949618170332842014-09-16T07:25:00.001-07:002014-09-16T07:25:13.759-07:00Threads and AsyncTasks - a quick noteToday I discovered that very long running network operations completely bugger your android UI thread if run in AsyncTasks, and really need to be pushed out to a proper java thread.<br /><br />Hopefully that will solve the UI crashing during data refresh.MrHarehttp://www.blogger.com/profile/07813011371392466114noreply@blogger.com0tag:blogger.com,1999:blog-500350328047207051.post-38859225857303219992014-07-25T06:00:00.003-07:002014-07-25T06:00:34.304-07:00Xstream and android 4.1.1There seems to be a problem with xstream, and versions of android earlier than 4.3. XML elements bigger than a certain size don't seem to be extracting - all the xml except base64 encoded photos extracts cleanly.<br />
<br />
I don't badly need to solve this problem at the moment, so I'm just recording it here. If I find that I need to solve it, I'll update.MrHarehttp://www.blogger.com/profile/07813011371392466114noreply@blogger.com0