Thursday, 25 April 2013

Time to start thinking, stupid......


Sometimes it feels like the world doesn't want to think any more. We make decisions for the sake of expediency, gaining satisfaction that there is a tick in the box, sometimes knowing that wrong tick has been placed in the wrong box. The person still asking 'Why' or saying 'Is there another way' in the corner at the end of a long meeting is seen as an inconvenience, blocking progress at best and plain annoying in the worst case.

As a tester, I often find myself at the heart of this deficit of thinking. Teams built with the wrong competencies for the job at hand, products sabotaged by blind fire decision making, compromises made to fit restraints which are beyond aspirational. So what can I, a lowly tester, do about this? I can change my behaviour, mind-set and make sure testing has a voice, that’s what I can do.

First, acknowledge and embrace your own stupidity. Ever felt like asking a stupid question but then stopped yourself and walked out of the room with no idea what happened? Stop doing that. Your confusion is most likely shared and you've just missed an opportunity to expose it. By not asking, you are even stupider when you leave the room than when you entered.

Second, stop being so accepting. Ever with your project team while decisions are made which made you think 'Really? We are going to do that?' Stayed quiet did you? Thought so. Stop doing that. Do not always retreat into your 'I'm only here as an information giver' persona. Testing is valuable, give it the respect it deserves and every so often apply a little thought to what testing gives to the functionality.

Third, talk to your tests.  Serious. Ask them why they need to exist. Ask them if they intend to be around for a while or will expire as soon as they have been executed. Ask them if they prove one thing, lots of things, or nothing at all. Ask who else cares about them. Look at them as group and ask if they are a balanced set of tests, or are they skewed in favour of a particular aspect of the functionality.

Fourth, remember the vision. It’s fairly common practice for projects/products to define a vision. This may put usability or aesthetics to the forefront, perhaps performance and scalability. It’s also pretty common to lose sight of this vision. So if usability is key then ask how does this functionality meet the vision and how does my testing approach show this goal has been met. To put it more succinctly, make sure you are testing the right product before testing it right.

Now that you are a stupid, annoying product visionary who speaks to test artifacts, you are ready to start being part of the solution rather than the problem. Like most habits, little and often is key. Learn short, sharp techniques for teasing out the real issue. 5 Why's for beginners, 6 Thinking Hats, the mighty 'Huh? Really? So?', why not have some fun. Its 5 minutes of your life, spent with your brain engaged. What’s the worst that could happen?

There are many testers out there, but not very many thinking testers. I've seen the phrase 'zombie tester' used recently, so unless you want to be a shambling, undead mess of a tester, it's time to get your thinking cap on. Eating the brains of others will not make you smarter.

Monday, 15 April 2013

Lets compromise....

Compromise. That word doesn't sit well with me, its not a natural state of mind. The further I progress in my testing career I find it around every corner:

'Lets compromise on quality to hit the date.'
'Lets compromise on testing depth so we can increase our coverage.'
'Lets just do a smoke test, it'll be fine.'


I often think that compromising in testing is seen as the grown up thing to do:

'Its your product buddy, I'm just an information giver. Go or no go, no skin off my nose. I'm just a tester.'


Its also a little naive in a way. The customer says:

'Yes lets cut down the testing so I have my stuff when I want it.'

When they actually mean:

'Yes lets cut down the testing so I have my stuff when I want it. Oh and make sure it works perfectly too.'


Thing is, I'm not just a tester. I'm a fierce (some would argue too fierce) believer in testing as craft, who leverages business facing, technical, exploratory, automation and performance focused testing to deliver the best service I know how. Whether that is critically assessing a user story (I'm usually the last person asking why) or writing a set of automated acceptance tests which continually add value the word 'compromise' is not at the forefront of my thinking.

Perhaps it's time for me to grow up, but for now, I'll keep fighting what I believe is the good fight.


Sunday, 14 April 2013

The testing marathon...

The world may or may not know that I'll be running the London Marathon next week. During my long hours pounding the streets to be ready for the marathon itself I've reflected on a few ways my training has reflected my testing journey:

Push yourself a little bit further over time - you can only prepare your body for a marathon in one way, and that's very gradually. I believe this can be applied to your mind too, specifically how you develop yourself as a tester. Acknowledge that you will not reinvent yourself overnight, pick a development path and review regularly to check progress and verify you are on the right path.

Find a sustainable pace - a marathon is made more difficult if executed at an ever changing pace. The same can be said for testing. If your testing does not flow, your execution of testing as a craft will not be as effective as it could be. Testing in small chunks, incrementally and continuously is the aim.

Do hard yards - there have been a few times I haven't wanted to train at all. This winter has been awful, a couple of feet of snow drains your enthusiasm. We've all had projects which feel like ten foot high snowdrifts, remember the power of seeing how things should NOT be done is as useful as seeing perfect execution. Use that experience to improve yourself and your craft. Share your frustrations and solutions.

Take time to reflect - When I started training, the furthest I'd run was a half marathon. Now a half marathon is a relatively light jog! Two years ago, even beginning to write code was beyond me. Now I can put together effective technical tests and automation. Often we can think we are never quite good enough, or the team hasn't come far enough down their path, or that new skill I'm learning is beyond me. A quick personal retrospective on a regular basis will work wonders.

Trust your training and step into the unknown - Finally, a marathon is quite a scary thing. It will be one of the hardest challenges of my life. I'm nervous. However, I'm trained and armed with skills and knowledge to help me. I treat my testing journey in a similar way. I have continuously evolving toolkit which helps me face testing challenges with confidence.

So, wish me luck for next week, any sponsorship gratefully accepted, for the fantastic WellChild who do such great work for children in the United Kingdom:

http://www.justgiving.com/wellchild-LM2013

Tuesday, 2 April 2013

Flat file creator in Groovy for SoapUI

Quick code share for creating flat files in SoapUI via Groovy.

I used this to create a linearly increasing file size for an extract, transform and load tool to do some basic load testing.

SoapUI is great for this kind of thing, nice and simple IDE, with the ability to extend to use pretty much any jar you can think of. Enjoy!
 
/*This script will create a new flat file with number of records taken from a test case level property:
* Steps:
* 1.Create the basics for use throughout the file. Primarily dates and account numbers 
* 2.Create the relevant filename
* 3.Create the header
* 4.Create the body of records with amended account numbers
* 5.Add a footer
* 6.Output the lot to a separate file, its size configurable by test case property. 
*/

import java.util.*;
import org.apache.commons.lang.RandomStringUtils;

//Create the static bits to be used
def number_Records = context.expand( '${#testcase#Number_Records}' ).toInteger();
def outputDir = context.expand( '${#testcase#Output Dir}' ).toString();

//What we need to be build the filename
def date = new Date();
String month = date.format('yyyyMM');
String today = date.format('yyyyMMdd');
String headerDate = date.format('ddMMyyyy');
String randomString = (RandomStringUtils.random(7, true, false));

//Create the filename
String filename = month+randomString+today+".src"

//Declare a new file object
File file = new File(outputDir+filename);

//Create the header
String fileHeader = headerDate
file.write(fileHeader);
file.append '\n'

//Build the body of the file
for (int i = 0; i < number_Records; i++){
String newAccountNumber = (RandomStringUtils.randomNumeric(15));
String lineToReproduce = newAccountNumber;
file.append(lineToReproduce);
file.append '\n';
}

//Create the footer
String fileFooter = ""
switch (number_Records.toString().size()){
case '3':
fileFooter += "9999999999999999999900000"+number_Records+" ";
break;
case '4':
fileFooter += "999999999999999999990000"+number_Records+" ";
break;
case '5':
fileFooter += "99999999999999999999000"+number_Records+" ";

break;
case '6':
fileFooter += "9999999999999999999900"+number_Records+" ";
break;
case '7':
fileFooter += "999999999999999999990"+number_Records+" ";
break;
case '8':
fileFooter += "99999999999999999999"+number_Records+" ";
break;
}

file.append(fileFooter);

log.info("File "+outputDir+filename+" created with "+number_Records+" record(s)")