James's profileJames McCaffreyBlogLists Tools Help

Blog


    November 21

    The Eight Habits of Highly Effective Software Testers

    In many casual conversations with senior level software engineers at Microsoft recently, I have heard the same message repeated over and over: finding really good software testers has always been difficult, but recently finding great testers has become almost impossible. I have also heard this message from Microsoft and Volt recruiters. In particular, I was asked several times last week, "What makes a great software tester?" Microsoft alone consistently has over 400 openings for software testers on a daily basis. Volt has roughly 100 opening for contract testers on any given day. Taking a cue from the title of a well-known management book written by Stephen Covey, "The Seven Habits of Highly Effective People", I decided to sit down and list the characteristics or habits that I'd look for in a great software tester. I put myself in the position of a hiring manager whose product and company depended upon the quality of some hypothetical software system under development. My list ended up having eight attributes, rather than seven as in Covey's book, but I didn't set out with a predetermined number of characteristics in mind. Here is my list of the eight attributes of a great software tester, roughly listed in order of importance although I think all eight are must-have skills.
     
    1. Passion for analysis and testing.
    2. Technical skill.
    3. Raw intellectual ability.
    4. Ability to prioritize and organize.
    5. Ability to adapt and learn.
    6. Ability to work without direct supervision.
    7. Ability to communicate.
    8. Ability to understand business strategy.

    1. Passion for analysis and testing. The key to success in any job is having an honest passion for what you do. Software testing is primarily about analyzing the work of others. A great software tester will get a greater thrill in writing some test automation which exercises a software application than in writing the application itself. This characteristic is often associated with people who have college degrees in a quantitative field other than Computer Science, such as Mathematics or Economics. To a large extent I believe a passion for analysis is primarily an innate, rather than learned, characteristic.
     
    2. Technical skill. A great software tester must have significant coding skills. Testers may not need skills on par with systems developers, but a great tester must have good coding skills in order to understand the system under test, communicate with developers, and write test automation. Most technical skills can be learned through education (formal college or self-taught) or experience. In either case I believe that at least four years of skill acquisition is a necessary prerequisite for a great software tester.
     
    3. Raw intellectual ability. A great software tester has to be smart. And by that I mean he must have exceptionally strong analytical and logical ability. Software development is essentially an exercise in logic, and to operate at a high level in this environment a software tester has to simply be smart. Interestingly, intelligence often correlates well with sense of humor, and vice versa.
     
    4. Ability to prioritize and organize. The ability to prioritize and organize are generic required skills needed for just about any job but these skills are critically important for software testers. Software development and testing is a highly dynamic and fluid activity where the key variables can change weekly, or even daily. The ability to recognize, interpret, and organize around these frequently changing job environment variables is an essential ability in a great software tester.
     
    5. Ability to adapt and learn. The software engineering field is relatively new (compared with most other forms of engineering) and new technologies appear with a speed that would astonish those not familiar with software. For example, the appearance of C# and the .NET Framework in early 2003 completely revolutionized software application development. Great software testers must have an ingrained propensity to be ongoing learners and consistently spend part of every week, and maybe even part of every day, dedicated to upgrading their skill sets. I performed some research a couple years ago that suggested that a software engineer's "skill set half-life" is about 18 months -- meaning that without a significant upgrade in skills, an engineer will be obsolete and not hirable (for leading edge systems development activities) in 36 months.
     
    6. Ability to work without direct supervision. The ability to work effectively without direct supervision is another generic job skill but is a skill that is particularly important for software testers. The requirement for taking independent action -- quickly recognizing a technical or business need related to the software testing effort, and the ability to know what steps to take without the need of managerial approval (and also the ability to know when not to forge ahead without a management OK) are essential skills.
     
    7. Ability to communicate. A great software tester must have strong written and verbal communication skills. A great tester must be able to read and analyze product documentation, write test plans, write clear bug reports, write coherent status reports to management (both formal report and ad hoc e-mail reports), and have the ability to listen critically and speak rationally in person-to-person meetings.
     
    8. Ability to understand business strategy. The characteristics of great software testers I've listed so far are primarily tactical in nature. The final characteristic of a great software tester on my list is the ability to see the larger picture of a company's overall business strategy. The ability to see the big picture enables a great software tester to actively participate at a level higher than just an individual contributor -- instead of merely finding a Priority 2 / Severity 2 bug, a great software tester can identify strategic strengths and weaknesses of a software system that can ultimately lead to a business competitive advantage.
     
    November 18

    Working with XML Data using PowerShell

    In general, the main operations you might want to perform on some arbitrary data in a data store are: parsing specific data out from the store, adding new data to an existing data store, changing existing data in the store, traversing or displaying all the data in the store, and removing specified data in the store. For example, if you are working with SQL these operations correspond to SELECT, INSERT, UPDATE, and DELETE statements. The ability to work with XML data is a fundamental skill for virtually all software development, testing, and management roles. You can take two slightly different approaches when working with XML data using PowerShell. First, PowerShell has an intrinsic [xml] type alias, which, when combined with other intrinsic PowerShell cmdlets give you a PowerShell centric way of working with XML data. Second, because PowerShell can access the .NET Framework, you can take a .NET Framework centric approach. These two approaches are quite similar and you can mix and match approaches too. Let me illustrate with a few examples. In a .NET environment the most common technique used when working with XML is to work via the XmlDocument type. You can think of an XmlDocument object as an in-memory representation of an XML document. Suppose you have this XML document saved as a file named testCases.xml:
     
    <?xml version="1.0" ?>
    <testCases>
     <testCase id="001">
      <input1>3</input1>
      <input2>4</input2>
      <expected>7</expected>
     </testCase>
     <testCase id="002">
      <input1>5</input1>
      <input2>6</input2>
      <expected>11</expected>
     </testCase>
    </testCases>
     
    One way to read this document into memory as an XmlDocument object is:
     
    [xml] $xd = get-content .\testCases.xml
     
    If you issue a $xd.GetType() command you'll see the object $xd has type XmlDocument. An equivalent way to read data into memory is:
     
    [System.Xml.XmlDocument] $xd = get-content .\testCases.xml
     
    I prefer the first approach for a subtle technical reason. In both cases if you issue a $xd | get-member command you will see that PowerShell does expose the underlying methods of the $xd object but does not expose the underlying properties. So, the second approach above is ever so slightly misleading in the sense that the $xd object is not 100% equivalent to the .NET XmlDocument type. In most situations you don't need the underlying XmlDocument properties, but if you do need the XmlDocument properties you can get the full .NET XmlDocument type by using the PsBase property along the lines of:
     
    [xml] $xd = get-content .\testCases.xml
    $xdfull = $xd.psbase
    write-host $xdfull.outerxml
     
    In my examples so far I have used the get-content cmdlet to read XML data into an XmlDocument object. An alternative, more .NET-like approach is:
     
    [xml] $xd = new-object System.Xml.XmlDocument
    $xd.load("C:\SomeDir\testCases.xml")
     
    However, this approach is again mildly misleading because $xd does not have its XML properties exposed. To summarize, when loading XML data into memory as an XmlDocument object, I recommend staying as much as possible with a purely PowerShell-feel approach:
     
    [xml] $xd = get-content .\testCases.xml
     
    Your code is smaller and you don't risk slightly mislead code reviewers because the intrinsic PowerShell [xml] type is not 100% equivalent to the .NET [System.Xml.XmlDocument] type.
     
    November 12

    Model View Controller Design in ASP.NET

    The Model-View-Controller (MVC) design paradigm for Web applications has been around for decades. However, Microsoft is working on a new ASP.NET MVC Framework that will simplify creating Web applications with an MVC architecture. Consider the most common type of Web application -- an application which uses a Web interface to access and manipulate data in some backend SQL database. The simplest way to create a Web application is to put everything (display code, logic code, data access code) all into a single .aspx file. But this approach runs into problems as the complexity of the application increases. So, you can use the ASP.NET code-behind mechanism to put the display code in one file and the logic and data access code in a second file. The MVC architecture takes this separation one step farther by separating coe into three files -- one with just display code (typically an .aspx file), one with data access code (typically a C# library file), and one with logic code (typically a C# script file). Web developers have been doing this since the release of ASP.NET in 2002 and gain the benefits associated with modularization -- easier testing, better reuse, and so on. The only minor problem is that MVC architecture in ASP.NET is currently very loosely defined and Web developers essentially have to design a raw MVC architecture from scratch. Well, Microsoft's upcoming MVC Framework will provide a more formalized approach. Essentially, the MVC Framework will provide a set of server-side methods which can be accessed by placing declarative tags inside ASP.NET code, similar to the way you can place tags like <asp:button> for user controls. All in all, I don't think this MVC Framework is a huge revolution in ASP.NET programming but it will be a nice feature for those Web developers who want to use the MVC approach.
    November 03

    Permutations with PowerShell

    A couple of blog entries ago I described how I created a mico-library of combinatorics functions using Windows PowerShell, Microsoft's new command shell and scripting language. A solid understanding of combinatorics is absolutely essential for software test engineers, and Combinatorics has several sub-areas but the two most common are combinations and permutations. Combinations, which I discussed in the earlier blog entry, are subsets of some initial set of items, where order doesn't matter. For example, for a set of n=3 items { "art", "bob", "cal" }, for a subset size of k=2 there are a total of 3 combination elements:
     
    { "art", "bob" }
    { "art", "cal" }
    { "bob", "cal" }
     
    Permutations are a cousin to combinations. Permutations are essentially a rearrangement of a set of items. For example, for the initial set of names with n=3 listed above, there are a total of 6 permutations:
     
    { "art", "bob", "cal" }
    { "art", "cal", "bob" }
    { "bob", "art", "cal" }
    { "bob", "cal", "art" }
    { "cal", "art", "bob" }
    { "cal", "bob", "art" }
     
    Being able to programmatically manipulate combinations and permutations is a key part of software test automation. Efficiently generating combinatoric elements and indirectly illustrates what I call the SAPES principle of test automation: compared to manual testing automation has superior Speed, Accuracy, Precision, Efficiency, and promotes Skill-building. Anyway, I decided to try and expanded my PowerShell micro-library to include a set of permutation methods. If you look at the screenshot below you'll see I did just that.
    PermutationsWithPowerShellDemo
     
    The source code for the main method of my demonstration script is:
    # permutationsDemo.ps1
    # string permutations with PowerShell
    function main
    {
      write-host "`nbegin permutations with PowerShell demo`n"
      $data = ("ant","bat","cow","dog")
      $n = $data.length
      write-host "Initial data is: ( $data )`n"
     
      constructPermutation $n $data
      write-host (permutationToString)
      $total = Factorial $n
      write-host "`nThere are $total total permutation elements `n"
     
      for ($i = 0; $i -le $total-1; $i++) {
        if ($i -lt 10 ) { write-host " " -nonewline }
        write-host "[$i] " -nonewline
        write-host (permutationToString)
        incrementPermutation
      }
      makePermutation 12
      write-host "`nThe [12] element computed directly is: "
      write-host (permutationToString)
      write-host "`nend permutations with PowerShell demo`n"
    }
     
    I use a method I named constructPermutation to initialize a permutation, a method named incrementPermutation to transform the current permutation element into its lexicographical successor, a method named permutationToString to return an image of the current permutation, and a method named makePermutation which directly creates a particular permutation element. This last method uses a mathematical construct called a factoradic, a term I first published a few years ago. The net result of this whole process is that I am quite certain that PowerShell would make an excellent base technology for a lightweight software test automation certification program.