In control flow based and data flow based testing the focus was on which paths to execute during testing. Mutation testing does not take a path-based approach. Instead it takes the program and creates many mutants of it by making simple changes to the program.
The goal of testing is to make sure that during the course of testing each mutant produces an output different from the output of the original program. In other words the mutation testing criterion does not say that the set of test cases must be such that certain paths are executed instead it requires the set of test cases to be such that they can distinguish between the original program and its mutants.
For a program under test P, mutation testing prepares a set of mutants by applying mutation operators on the text of P. The set of mutation operators depends on the language in which P is written. In general a mutation operator makes a small unit change in the program to produce a mutant.
Example of mutation operators are replace an arithmetic operator with some other arithmetic operator change an array reference (say from A to B) replace a constant with another constant of the same type (e.g. change a constant to 1) change the label for a goto statement and replace a variable by some special value (e.g. an integer or a real variable with 0). Each application of a mutation operator results in one mutant.