Random testing

From Wikipedia, the free encyclopedia
Jump to: navigation, search

Random testing is a black-box software testing technique where programs are tested by generating random, independent inputs. Results of the output are compared against software specifications to verify that the test output is pass or fail.[1] In case of absence of specifications the exceptions of the language are used which means if an exception arises during test execution then it means there is a fault in the program.

Overview[edit]

Consider the following C++ function:

int myAbs(int x) {
    if (x>0) { 
        return x;
    }
    else {
        return x; // bug: should be '-x'
    }
}

Now the random tests for this function could be {123, 36, -35, 48, 0}. Only the value '-35' triggers the bug. If there is no reference implementation to check the result, the bug still could be noticed. However, an assertion could be added to check the results, like:

void testAbs(int n) {
    for (int i=0; i<n; i++) {
        int x = getRandomInput();
        int result = myAbs(x);
        assert(result>=0);
    }
}

The reference implementation is sometimes available, e.g. when implementing a simple algorithm in a much more complex way for better performance. For example, to test implementation of Schönhage–Strassen algorithm algorithm, standard "*" operation on integers can be used:

int getRandomInput() {
    . . .
}
 
void testFastMultiplication(int n) {
    for (int i=0; i<n; i++) {
        long x = getRandomInput();
        long y = getRandomInput();
        long result = fastMultiplication(x, y);
        assert(x*y==result);
    }
}

While this example is limited to simple types (for which a simple random generator can be used), tools targeting object-oriented languages typically explore the program to test and find generators (constructors or methods returning objects of that type) and call them using random inputs (either themselves generated the same way or generated using a pseudo-random generator if possible). Such approaches then maintain a pool of randomly generated objects and use a probability for either reusing a generated object or creating a new one.[2]

On randomness[edit]

According to the seminal paper on random testing by D. Hamlet

[..] the technical, mathematical meaning of "random testing" refers to an explicit lack of "system" in the choice of test data, so that there is no correlation among different tests.[1]

Strengths and weaknesses[edit]

Random testing is typically praised for the following strengths:

  • It is cheap to use: it does not need to be smart about the program under test.
  • It does not have any bias: unlike manual testing, it does not overlook bugs because there is misplaced trust in some code.
  • It is quick to find bug candidates: it typically takes a couple of minutes to perform a testing session.
  • If software is properly specified: it finds real bugs.

The following weaknesses are typically pointed out by detractors:

  • It only finds basic bugs (f.ex. Null pointer dereferencing).
  • It is only as precise as the specification and specifications are typically imprecise.
  • It compares poorly with other techniques to find bugs (f.ex. static analysis).

Types of random testing[edit]

With respect to the input[edit]

  • Random input sequence generation (i.e. a sequence of method calls)
  • Random sequence of data inputs (sometimes called stochastic testing) - f.ex. a random sequence of method calls
  • Random data selection from existing database

Guided vs. unguided[edit]

  • undirected random test generation - with no heuristics to guide its search
  • directed random test generation - f.ex. "feedback-directed random test generation"[3] or "adaptive random testing" [4]

Implementations[edit]

Some tools implementing random testing:

  • QuickCheck - a famous test tool, originally developed for Haskell but ported to many other languages, that generates random sequences of API calls based on a model and verifies system properties that should hold true after each run. Check this QuviQ QuickCheck flyer for a quick overview.
  • Randoop - generates sequences of methods and constructor invocations for the classes under test and creates JUnit tests from these
  • Simulant - a Clojure tool that runs simulations of various agents (f.ex. users with different behavioral profiles) based on a statistical model of their behavior, recording all the actions and results into a database for later exploration and verification
  • AutoTest - a tool integrated to EiffelStudio testing automatically Eiffel code with contracts based on the eponymous research prototype.[2]
  • York Extensible Testing Infrastructure (YETI) - a language agnostic tool which targets various programming languages (Java, JML, CoFoJa, .NET, C, Kermeta).

Critique[edit]

Random testing has only a specialized niche in practice, mostly because an effective oracle is seldom available, but also because of difficulties with the operational profile and with generation of pseudorandom input values.[1]

An Oracle is an instrument for verifying whether the outcomes match the program specification or not. An operation profile is knowledge about usage patterns of the program and thus which parts are more important.

For programming languages and platforms which have contracts (for example Eiffel. .NET or various extensions of Java like JML, CoFoJa...) contracts act as natural oracles and the approach has been applied successfully.[2] In particular, random testing finds more bugs than manual inspections or user reports (albeit different ones).[5]

See also[edit]

References[edit]

  1. ^ a b c Richard Hamlet (1994). "Random Testing". In John J. Marciniak. Encyclopedia of Software Engineering (1 ed.). John Wiley and Sons. ISBN 0471540021. Retrieved 16 June 2013. 
  2. ^ a b c http://se.inf.ethz.ch/research/autotest/
  3. ^ Pacheco, Carlos; Shuvendu K. Lahiri; Michael D. Ernst; Thomas Ball (May 2007). "Feedback-directed random test generation". ICSE '07: Proceedings of the 29th International Conference on Software Engineering (IEEE Computer Society): 75–84. ISSN 0270-5257. 
  4. ^ Chen, T.Y.; H. Leung; I.K. Mak (2005). "Adaptive Random Testing". Advances in Computer Science - ASIAN 2004. Higher-Level Decision Making (Lecture Notes in Computer Science Volume 3321): 320–329. 
  5. ^ Ilinca Ciupa; Alexander Pretschner; Manuel Oriol; Andreas Leitner; Bertrand Meyer (2009). "On the number and nature of faults found by random testing". Software Testing, Verification and Reliability (John Wiley and Sons). 

External links[edit]