What is testing and debugging?

Testing is the process of running a program to try and ascertain whether or not it works as intended. Debugging is the process of trying to fix a program that you already know does not work as intended.

How to design problems in ways that make them easier to test and debug?

The key to doing this is break- ing the program up into separate components that can be implemented, tested, and debugged independently of other components.

6.1 Testing

What is the most important thing to say about testing?

The most important thing to say about testing is that its purpose is to show that bugs exist, not to show that a program is bug-free. To quote Edsger Dijkstra, “Program testing can be used to show the presence of bugs, but never to show their absence!”39 Or, as Albert Einstein reputedly said, “No amount of experi- mentation can ever prove me right; a single experiment can prove me wrong.”

What is the key to testing?

The key to testing is finding a collection of inputs, called a test suite, that has a high likelihood of revealing bugs, yet does not take too long to run. The key to doing this is partitioning the space of all possible inputs into subsets that provide equivalent information about the correctness of the program, and then con- structing a test suite that contains at least one input from each partition. (Usually, constructing such a test suite is not actually possible. Think of this as an unachievable ideal.)

How to partition the set of possible inputs?

A partition of a set divides that set into a collection of subsets such that each element of the original set belongs to exactly one of the subsets. If one tested the implementation on at least one value from each of these subsets, there would be reasonable probability (but no guarantee) of exposing a bug if one exists.

For most programs, finding a good partitioning of the inputs is far easier said than done. Typically, people rely on heuristics1 based on exploring different paths through some combination of the code and the specifications. Heuristics based on exploring paths through the code fall into a class called glass-box testing. Heuristics based on exploring paths through the specification fall into a class called black-box testing.

What are the positive features of the independence of black-box testing?

  1. It reduces the likelihood of generating test suites that exhib- it mistakes that are correlated with mistakes in the code.
  2. It is robust with respect to implementation changes.

What boundary condition should be tested?

When looking at lists, this often means looking at the empty list, a list with exactly one element, and a list con- taining lists. When dealing with numbers, it typically means looking at very small and very large values as well as “typical” values.

For sqrt, for example, it might make sense to try values of x and epsilon similar to those in here:

X Epsilon
0.0 0.0001
25.0 0.0001
0.5 0.0001
2.0 0.0001
2.0 1.0/2.0**64
1.0/2.0**64 1.0/2.0**64
2.0**64.0 1.0/2.0**64
1.0/2.0**64 2.0**64.0
2.0**64.0 2.0**64.0

Another important boundary condition to think about is aliasing. Consider, for example, the code

def copy(L1, L2):
    """ Assumes L1, L2 are lists
        Mutates L2 to be a copy of L1"""
    while len(L2) > 0: #remove all elements from L2
        L2.pop() #remove last element of L2
    for e in L1: #append L1's elements to initially empty L2
        L2.append(e)
        
L = [1, 2, 3]
copy(L, L)
print(L)

If any of these tests fail, something needs to be fixed. Where do those “something” lie?

Perhaps there is a bug in the code that needs to be fixed, or perhaps the specification needs to be changed so that it is easier to meet. It might, for example, be unreasonable to expect to find an approximation of a square root when epsilon is ridiculously small.

Why it is rarely sufficient to do black-box testing?

Without looking at the internal structure of the code, it is impossible to know which test cases are likely to provide new information. Consider the trivial example:

def isPrime(x):
    """ Assumes x is a nonnegative int
        Returns True if x is prime; False otherwise""" 
    if x <= 2:
        return False
    for i in range(2, x):
        if x%i == 0: 
            return False
    return True

  1. heuristics: [Computing] proceeding to a solution by trial and error or by rules that are only loosely defined.

LS0tCnRpdGxlOiAwNiBURVNUSU5HIEFORCBERUJVR0dJTkcKc3VidGl0bGU6IAphdXRob3I6IOabsuaUvwpkYXRlOiAyMDIwLTA1LTI3CnNsdWc6IHRlc3RpbmctYW5kLWRlYnVnZ2luZwp0YWdzOgotIApjYXRlZ29yaWVzOgotIG1pdDYwMDAKLSBJQ1BQIGJvb2tub3Rlcwp0eXBvcmEtcm9vdC11cmw6IC4uLy4uL3N0YXRpYwpzaG93X3RvYzogeWVzCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCiMjIyBXaGF0IGlzIHRlc3RpbmcgYW5kIGRlYnVnZ2luZz8KClRlc3RpbmcgaXMgdGhlIHByb2Nlc3Mgb2YgcnVubmluZyBhIHByb2dyYW0gdG8gdHJ5IGFuZCBhc2NlcnRhaW4gd2hldGhlciBvciBub3QgaXQgd29ya3MgYXMgaW50ZW5kZWQuIERlYnVnZ2luZyBpcyB0aGUgcHJvY2VzcyBvZiB0cnlpbmcgdG8gZml4IGEgcHJvZ3JhbSB0aGF0IHlvdSBhbHJlYWR5IGtub3cgZG9lcyBub3Qgd29yayBhcyBpbnRlbmRlZC4KCiMjIyBIb3cgdG8gZGVzaWduIHByb2JsZW1zIGluIHdheXMgdGhhdCBtYWtlIHRoZW0gZWFzaWVyIHRvIHRlc3QgYW5kIGRlYnVnPwoKVGhlIGtleSB0byBkb2luZyB0aGlzIGlzIGJyZWFrLSBpbmcgdGhlIHByb2dyYW0gdXAgaW50byBzZXBhcmF0ZSBjb21wb25lbnRzIHRoYXQgY2FuIGJlIGltcGxlbWVudGVkLCB0ZXN0ZWQsIGFuZCBkZWJ1Z2dlZCBpbmRlcGVuZGVudGx5IG9mIG90aGVyIGNvbXBvbmVudHMuCgojIyA2LjEgVGVzdGluZwoKIyMjIFdoYXQgaXMgdGhlIG1vc3QgaW1wb3J0YW50IHRoaW5nIHRvIHNheSBhYm91dCB0ZXN0aW5nPwoKVGhlIG1vc3QgaW1wb3J0YW50IHRoaW5nIHRvIHNheSBhYm91dCB0ZXN0aW5nIGlzIHRoYXQgaXRzIHB1cnBvc2UgaXMgdG8gc2hvdyB0aGF0IGJ1Z3MgZXhpc3QsIG5vdCB0byBzaG93IHRoYXQgYSBwcm9ncmFtIGlzIGJ1Zy1mcmVlLiBUbyBxdW90ZSBFZHNnZXIgRGlqa3N0cmEsIOKAnFByb2dyYW0gdGVzdGluZyBjYW4gYmUgdXNlZCB0byBzaG93IHRoZSBwcmVzZW5jZSBvZiBidWdzLCBidXQgbmV2ZXIgdG8gc2hvdyB0aGVpciBhYnNlbmNlIeKAnTM5IE9yLCBhcyBBbGJlcnQgRWluc3RlaW4gcmVwdXRlZGx5IHNhaWQsIOKAnE5vIGFtb3VudCBvZiBleHBlcmktIG1lbnRhdGlvbiBjYW4gZXZlciBwcm92ZSBtZSByaWdodDsgYSBzaW5nbGUgZXhwZXJpbWVudCBjYW4gcHJvdmUgbWUgd3Jvbmcu4oCdCgojIyMgV2hhdCBpcyB0aGUga2V5IHRvIHRlc3Rpbmc/CgpUaGUga2V5IHRvIHRlc3RpbmcgaXMgZmluZGluZyBhIGNvbGxlY3Rpb24gb2YgaW5wdXRzLCBjYWxsZWQgYSAqKnRlc3Qgc3VpdGUqKiwgdGhhdCBoYXMgYSBoaWdoIGxpa2VsaWhvb2Qgb2YgcmV2ZWFsaW5nIGJ1Z3MsIHlldCBkb2VzIG5vdCB0YWtlIHRvbyBsb25nIHRvIHJ1bi4gVGhlIGtleSB0byBkb2luZyB0aGlzIGlzIHBhcnRpdGlvbmluZyB0aGUgc3BhY2Ugb2YgYWxsIHBvc3NpYmxlIGlucHV0cyBpbnRvIHN1YnNldHMgdGhhdCBwcm92aWRlIGVxdWl2YWxlbnQgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGNvcnJlY3RuZXNzIG9mIHRoZSBwcm9ncmFtLCBhbmQgdGhlbiBjb24tIHN0cnVjdGluZyBhIHRlc3Qgc3VpdGUgdGhhdCBjb250YWlucyBhdCBsZWFzdCBvbmUgaW5wdXQgZnJvbSBlYWNoIHBhcnRpdGlvbi4gKFVzdWFsbHksIGNvbnN0cnVjdGluZyBzdWNoIGEgdGVzdCBzdWl0ZSBpcyBub3QgYWN0dWFsbHkgcG9zc2libGUuIFRoaW5rIG9mIHRoaXMgYXMgYW4gdW5hY2hpZXZhYmxlIGlkZWFsLikgCgojIyMgSG93IHRvIHBhcnRpdGlvbiB0aGUgc2V0IG9mIHBvc3NpYmxlIGlucHV0cz8KCkEgKipwYXJ0aXRpb24qKiBvZiBhIHNldCBkaXZpZGVzIHRoYXQgc2V0IGludG8gYSBjb2xsZWN0aW9uIG9mIHN1YnNldHMgc3VjaCB0aGF0IGVhY2ggZWxlbWVudCBvZiB0aGUgb3JpZ2luYWwgc2V0IGJlbG9uZ3MgdG8gZXhhY3RseSBvbmUgb2YgdGhlIHN1YnNldHMuIElmIG9uZSB0ZXN0ZWQgdGhlIGltcGxlbWVudGF0aW9uIG9uIGF0IGxlYXN0IG9uZSB2YWx1ZSBmcm9tIGVhY2ggb2YgdGhlc2Ugc3Vic2V0cywgdGhlcmUgd291bGQgYmUgcmVhc29uYWJsZSBwcm9iYWJpbGl0eSAoYnV0IG5vIGd1YXJhbnRlZSkgb2YgZXhwb3NpbmcgYSBidWcgaWYgb25lIGV4aXN0cy4KCkZvciBtb3N0IHByb2dyYW1zLCBmaW5kaW5nIGEgZ29vZCBwYXJ0aXRpb25pbmcgb2YgdGhlIGlucHV0cyBpcyBmYXIgZWFzaWVyIHNhaWQgdGhhbiBkb25lLiBUeXBpY2FsbHksIHBlb3BsZSByZWx5IG9uIGhldXJpc3RpY3NbXmhldXJpc3RpY3NdIGJhc2VkIG9uIGV4cGxvcmluZyBkaWZmZXJlbnQgcGF0aHMgdGhyb3VnaCBzb21lIGNvbWJpbmF0aW9uIG9mIHRoZSBjb2RlIGFuZCB0aGUgc3BlY2lmaWNhdGlvbnMuIEhldXJpc3RpY3MgYmFzZWQgb24gZXhwbG9yaW5nIHBhdGhzIHRocm91Z2ggdGhlIGNvZGUgZmFsbCBpbnRvIGEgY2xhc3MgY2FsbGVkICoqZ2xhc3MtYm94IHRlc3RpbmcqKi4gSGV1cmlzdGljcyBiYXNlZCBvbiBleHBsb3JpbmcgcGF0aHMgdGhyb3VnaCB0aGUgc3BlY2lmaWNhdGlvbiBmYWxsIGludG8gYSBjbGFzcyBjYWxsZWQgKipibGFjay1ib3ggdGVzdGluZyoqLgoKW15oZXVyaXN0aWNzXTogaGV1cmlzdGljczogW0NvbXB1dGluZ10gcHJvY2VlZGluZyB0byBhIHNvbHV0aW9uIGJ5IHRyaWFsIGFuZCBlcnJvciBvciBieSBydWxlcyB0aGF0IGFyZSBvbmx5IGxvb3NlbHkgZGVmaW5lZC4KCiMjIyBXaGF0IGFyZSB0aGUgcG9zaXRpdmUgZmVhdHVyZXMgb2YgdGhlIGluZGVwZW5kZW5jZSBvZiBibGFjay1ib3ggdGVzdGluZz8KCjEuIEl0IHJlZHVjZXMgdGhlIGxpa2VsaWhvb2Qgb2YgZ2VuZXJhdGluZyB0ZXN0IHN1aXRlcyB0aGF0IGV4aGliLSBpdCBtaXN0YWtlcyB0aGF0IGFyZSBjb3JyZWxhdGVkIHdpdGggbWlzdGFrZXMgaW4gdGhlIGNvZGUuCjEuIEl0IGlzIHJvYnVzdCB3aXRoIHJlc3BlY3QgdG8gaW1wbGVtZW50YXRpb24gY2hhbmdlcy4KCiMjIyBXaGF0IGJvdW5kYXJ5IGNvbmRpdGlvbiBzaG91bGQgYmUgdGVzdGVkPwoKV2hlbiBsb29raW5nIGF0IGxpc3RzLCB0aGlzIG9mdGVuIG1lYW5zIGxvb2tpbmcgYXQgdGhlIGVtcHR5IGxpc3QsIGEgbGlzdCB3aXRoIGV4YWN0bHkgb25lIGVsZW1lbnQsIGFuZCBhIGxpc3QgY29uLSB0YWluaW5nIGxpc3RzLiBXaGVuIGRlYWxpbmcgd2l0aCBudW1iZXJzLCBpdCB0eXBpY2FsbHkgbWVhbnMgbG9va2luZyBhdCB2ZXJ5IHNtYWxsIGFuZCB2ZXJ5IGxhcmdlIHZhbHVlcyBhcyB3ZWxsIGFzIOKAnHR5cGljYWzigJ0gdmFsdWVzLgoKRm9yIHNxcnQsIGZvciBleGFtcGxlLCBpdCBtaWdodCBtYWtlIHNlbnNlIHRvIHRyeSB2YWx1ZXMgb2YgeCBhbmQgZXBzaWxvbiBzaW1pbGFyIHRvIHRob3NlIGluIGhlcmU6Cgp8ICAgICAgWCAgICAgIHwgICBFcHNpbG9uICAgfAp8IDotLS0tLS0tLS06IHwgOi0tLS0tLS0tLTogfAp8ICAgICAwLjAgICAgIHwgICAwLjAwMDEgICAgfAp8ICAgIDI1LjAgICAgIHwgICAwLjAwMDEgICAgfAp8ICAgICAwLjUgICAgIHwgICAwLjAwMDEgICAgfAp8ICAgICAyLjAgICAgIHwgICAwLjAwMDEgICAgfAp8ICAgICAyLjAgICAgIHwgMS4wLzIuMCoqNjQgfAp8IDEuMC8yLjAqKjY0IHwgMS4wLzIuMCoqNjQgfAp8ICAyLjAqKjY0LjAgIHwgMS4wLzIuMCoqNjQgfAp8IDEuMC8yLjAqKjY0IHwgIDIuMCoqNjQuMCAgfAp8ICAyLjAqKjY0LjAgIHwgIDIuMCoqNjQuMCAgfAoKQW5vdGhlciBpbXBvcnRhbnQgYm91bmRhcnkgY29uZGl0aW9uIHRvIHRoaW5rIGFib3V0IGlzIGFsaWFzaW5nLiBDb25zaWRlciwgZm9yIGV4YW1wbGUsIHRoZSBjb2RlCgpgYGB7cHl0aG9ufQpkZWYgY29weShMMSwgTDIpOgogICAgIiIiIEFzc3VtZXMgTDEsIEwyIGFyZSBsaXN0cwogICAgICAgIE11dGF0ZXMgTDIgdG8gYmUgYSBjb3B5IG9mIEwxIiIiCiAgICB3aGlsZSBsZW4oTDIpID4gMDogI3JlbW92ZSBhbGwgZWxlbWVudHMgZnJvbSBMMgogICAgICAgIEwyLnBvcCgpICNyZW1vdmUgbGFzdCBlbGVtZW50IG9mIEwyCiAgICBmb3IgZSBpbiBMMTogI2FwcGVuZCBMMSdzIGVsZW1lbnRzIHRvIGluaXRpYWxseSBlbXB0eSBMMgogICAgICAgIEwyLmFwcGVuZChlKQogICAgICAgIApMID0gWzEsIDIsIDNdCmNvcHkoTCwgTCkKcHJpbnQoTCkKYGBgCgoKIyMjIElmIGFueSBvZiB0aGVzZSB0ZXN0cyBmYWlsLCBzb21ldGhpbmcgbmVlZHMgdG8gYmUgZml4ZWQuIFdoZXJlIGRvIHRob3NlICJzb21ldGhpbmciIGxpZT8KClBlcmhhcHMgdGhlcmUgaXMgYSBidWcgaW4gdGhlIGNvZGUgdGhhdCBuZWVkcyB0byBiZSBmaXhlZCwgb3IgcGVyaGFwcyB0aGUgc3BlY2lmaWNhdGlvbiBuZWVkcyB0byBiZSBjaGFuZ2VkIHNvIHRoYXQgaXQgaXMgZWFzaWVyIHRvIG1lZXQuIEl0IG1pZ2h0LCBmb3IgZXhhbXBsZSwgYmUgdW5yZWFzb25hYmxlIHRvIGV4cGVjdCB0byBmaW5kIGFuIGFwcHJveGltYXRpb24gb2YgYSBzcXVhcmUgcm9vdCB3aGVuIGVwc2lsb24gaXMgcmlkaWN1bG91c2x5IHNtYWxsLgoKIyMjIFdoeSBpdCBpcyByYXJlbHkgc3VmZmljaWVudCB0byBkbyBibGFjay1ib3ggdGVzdGluZz8KCldpdGhvdXQgbG9va2luZyBhdCB0aGUgaW50ZXJuYWwgc3RydWN0dXJlIG9mIHRoZSBjb2RlLCBpdCBpcyBpbXBvc3NpYmxlIHRvIGtub3cgd2hpY2ggdGVzdCBjYXNlcyBhcmUgbGlrZWx5IHRvIHByb3ZpZGUgbmV3IGluZm9ybWF0aW9uLiBDb25zaWRlciB0aGUgdHJpdmlhbCBleGFtcGxlOgoKYGBge3B5dGhvbn0KZGVmIGlzUHJpbWUoeCk6CiAgICAiIiIgQXNzdW1lcyB4IGlzIGEgbm9ubmVnYXRpdmUgaW50CiAgICAgICAgUmV0dXJucyBUcnVlIGlmIHggaXMgcHJpbWU7IEZhbHNlIG90aGVyd2lzZSIiIiAKICAgIGlmIHggPD0gMjoKICAgICAgICByZXR1cm4gRmFsc2UKICAgIGZvciBpIGluIHJhbmdlKDIsIHgpOgogICAgICAgIGlmIHglaSA9PSAwOiAKICAgICAgICAgICAgcmV0dXJuIEZhbHNlCiAgICByZXR1cm4gVHJ1ZQpgYGAKCg==