James's profileJames McCaffreyBlogLists Tools Help

Blog


    February 27

    JavaScript and Private Class Members

    I was teaching an intermediate level JavaScript class last week and I used an example that many experienced JavaScript coders don't know about, and that is how to create a JavaScript class with private data members. Consider this:
     
    function Book(t,p)
    {
      // public
      this.title = t;
      this.pages = p;
      this.toString = function()
        { return this.title + " # " + this.pages; };
    }
     
    function main()
    {
      var b = new Book("Test Automation",123);
      WScript.Echo(b.toString());
      b.pages = 321;
      WScript.Echo(b.toString());
    }
     
    main();
     
    The output is 'Test Automation # 123' followed by 'Test Automation # 321' as you would expect. Here I have a normal Book class in JavaScript where data members title and pages are public and so can be accessed and manipulated by the calling code in the main() function. Here's how to make the data private:
     
    function Book(t,p)
    {
      // private
      var title = t;
      var pages = p;
     
      // public
      this.getTitle = function() { return title; };
      this.setTitle = function(t) { title = t; };
      this.getPages = function() { return pages; };
      this.setPages = function(p) { pages = p; };
      this.toString = function() { return title + " # " + pages; };
    }
     
    By using the "var" keyword instead of the "this" keyword, title and pages can no longer be accessed or manipulated directly so I code public functions to perform those operations. If now:
     
    var b = new Book();
    b.title = "Software Testing"; // ignored
    b.pages = 111; // ignored
    WScript.Echo(b.toString());
     
    the output is 'undefined # undefined'. However if:
     
    var b = new Book();
    b.setTitle("Software Development");
    b.setPages(222);
    WScript.Echo(b.toString());
     
    the output is Software Development # 222' as you'd expect.
    February 20

    Partial Antirandom Testing

    I wrote a paper this week for the 18th Annual Software Engineering and Data Engineering Conference. The title is, "An Empirical Study of the Effectiveness of Partial Antirandom Testing." Most testers are familiar with random testing where you generate random data and send it to the system under test. In most situations, because here is no explicit expected value or state, the goal of random testing is to try and produce and hang crash, or failure in the SUT. The field of hardware testing came up with the concept of antirandom testing. Antirandom testing is a variant of random testing where a set of test case inputs is generated in such a way that each new test input added to the test set is the test input which is the most different from the test inputs currently in the test set. The concept is best explained by example. Suppose that a system has a parameter which accepts 3-bit values and the test effort wishes to generate a test set which contains four antirandom inputs. The complete input domain is:
     
    0: 000
    1: 001
    2: 010
    3: 011
    4: 100
    5: 101
    6: 110
    7: 111
     
    The initial antirandom test set is empty and value {0,0,0} can be arbitrarily selected from the input domain and added to the test set. The next input to be added to the antirandom test set is the value from the domain space which is most different from the current inputs in the test set. In this case input {1,1,1} is the most different from {0,0,0} using virtually any rational definition of different so the antirandom test set now contains {0,0,0} and {1,1,1}. Similarly, assume that value {0,0,1} is selected from the input domain using the algorithm described below and added to the antirandom test set so the set contains {0,0,0}, {1,1,1}, and {0,0,1}. Any of the remaining five values in the input domain are candidates for the fourth and final member of the test set, however exactly which value is chosen depends upon the difference function used. One obvious candidate function is the Hamming distance. Another possibility is the Cartesian distance; suppose this is used as the difference function. The sum of the Cartesian differences between each candidate and the three current members of the antirandom test set are:
     
    010: sqrt(1) + sqrt(2) + sqrt(2) = 3.82
    011: sqrt(2) + sqrt(1) + sqrt(1) = 3.41
    100: sqrt(1) + sqrt(2) + sqrt(2) = 3.82
    101: sqrt(2) + sqrt(1) + sqrt(1) = 3.41
    110: sqrt(2) + sqrt(1) + sqrt(3) = 4.14
     
    Because {1,1,0} is the most different from the existing members of the antirandom test set, it is added to the test set. The fundamental basis of antirandom testing is the premise that similar inputs will likely yield similar information about the system under test, and therefore random inputs which are as different as possible will yield more information than arbitrary random inputs. The example above points out that pure antirandom test input generation requires a complete enumeration of the entire input domain. This may be possible for certain types of hardware testing with a relatively small input byte size or for software systems with a small input domain. However, pure antirandom testing is rarely possible for complex software systems. Anyway, I came up with an approach I call partial antirandom testing which can be used to test software systems.
     
    February 15

    Partition-Based Pairwise Testing

    I have just finished writing a research paper for the SERP (Software Engineering Research and Practice) sub-conference of the 2009 World Congress in Computer Science, Computer Engineering, and Applied Computing. The paper presents the results of an investigation into the effectiveness of pairwise testing. In the paper I introduce the idea of what I call partition-based pairwise testing. The idea is best explained by example. Suppose you have a method under test named Evaluate(Card c1, Card c2, Card c3, Card c4, Card c5) which accepts representations of five objects which represent playing cards from a normal deck of 52 cards. Pure pairwise testing would treat all 52 cards as possible parameter values for each of the five system parameters. This would lead to an unmanageable number of test case inputs. The idea of partition-based pairwise testing is to divide the parameter values into some form of equivalence classes and then use some boundary values from each class. Suppose we divide the 52 card deck into low (2 through 6), medium (7, 8, 9), and high (10, Jack, Queen, King, Ace) classes, and ignore suit. If we use just the edge values from each class and arbitrarily select clubs as the suit, we get this set of input values:
     
    c1: 2c, 6c, 7c, 9c, Tc, Ac
    c2: 2c, 6c, 7c, 9c, Tc, Ac
    c3: 2c, 6c, 7c, 9c, Tc, Ac
    c4: 2c, 6c, 7c, 9c, Tc, Ac
    c5: 2c, 6c, 7c, 9c, Tc, Ac
     
    Now if we use a pairwise test set generation tool such as PICT, we generate 50 test case inputs:
     
        c1  c2  c3  c4  c5
    ----------------------
    01: 2c  7c  6c  2c  2c
    02: Tc  2c  9c  2c  6c
    03: Ac  Ac  Tc  Tc  9c
     (etc.)
    50: 7c  9c  6c  2c  6c
     
    This test set is much more manageable. Note that because there are many ways to partition an arbitrary set of values, you'd have to create several equivalence classes (for example, partitioning by suits) to get effective test coverage.
     
    February 08

    The Difference between XPath and XQuery

    I have a love-hate relationship with XML. Some things about XML drive me crazy. The differences between XPath, XQuery, and XSLT are examples. XPath 1.0 (the 2.0 version is not widely used yet) was originally intended to provide a way to extract nodes from an XML document. But XPath can also be used to compute values from the contents of an XML document. XPath was originally intended for use with XSLT, which is now used primarily for transforming XML but which was originally intended for use as a way to format XML data. XQuery was originally intended as a kind of SQL for XML data -- that is, a way to extract and compute XML data. But XQuery can also be used to transform XML. In short, XPath, XQuery, and XSLT are examples of what can go wrong when technologies are designed by committee. Here, there are overlapping functionalities which basically only serve to confuse the development community (with regards to best practice and usage issues). Ultimately, the technology community as a whole will decide what works best and either XPath or XQuery will possibly fade away.