Conference PaperPDF Available

Abstract

Mutation testing is a fault-based testing technique that has been widely studied in the last decades. One reason for the interest of the scientific community in mutation testing is its flexibility. It can be applied to programs at unit and integration testing levels, as well as to software specifications written in a variety of different languages. A fundamental issue to make mutation testing work for a given language or environment is the set of mutant operators used to create the mutants. In this paper a set o mutant operator is proposed for the Java programming language, and more specifically, aiming at exercising aspects of concurrency and synchronization of that language.
MutantOperators for Testing ConcurrentJavaPrograms
arcio Delamaro
Universidade Estadual de Maring´a(UEM)
delamaro@din.uem.br
Mauro Pezz`e
Universit`adegli Studi di Milano
pezze@disco.unimib.it
Auri M. R. Vincenzi
Jos´eCarlos Maldonado
Universidade de ao Paulo (USP)
{jcmaldon,auri}@icmc.sc.usp.br
Abstract
Mutation testing is afault-based testing technique that has been widely studied
in the last decades. One reason for the interest of the scientific communityin mu-
tation testing is its flexibility.It can beapplied to programs at unit and integration
testing levels, as well as to software specifications written in avarietyof different
languages. Afundamental issue to makemutation testing work for agiven language
or environmentis the set of mutantoperators used to create the mutants. In this
paper aset omutantoperator is proposed for the Javaprogramming language, and
more specifically,aiming at exercising aspects of concurrency and synchronization
of that language.
1Introduction
Testing is acrucial activityin the software lifecycle. It is expensiveand time con-
suming. For this reason mucheffort has been spenton developing techniques and
tools to support the testing activity.An importantresult of researchis the defi-
nition techniques and criteria to drivethe generation of test sets that can suitably
exercise aprogram.
Mutation testing is afault based test technique. It uses aset of “rules” called
mutantoperators to create programs slightly differentfrom the program under
test. These programs are called mutants.The goal of mutation testing is the
generation of atest set that distinguishes the behavior of the mutants from the
original program. The ratio of distinguished mutants (also called dead or killed
mutants), over the total number of mutants, measures the adequacy of the test set.
According to the coupling effect hypothesis[14], test cases that distinguish
simple faults injected in the original program to create the mutants should also
beable to reveal faults that can beobtained as acomposition of simple faults.
XV Simpósio Brasileiro de Engenharia de Software
- 272 -
Thus, mutantoperators can beseen as representing common faults usually found
in software.
Mutantoperators depend on the language in whichthe artifact to betested
is described. So far mutation testing has been applied to programs written in
several programming languages, likeFortran [5], C[3] and Java[11]. and to formal
specifications written using Finite State Machines [7], Petri Nets [8], Statecharts [6]
and Estelle [20, 18]. This flexibilityderives from the fact that mutation testing
requires only an executable model that transforms inputs into observable outputs
that can becompare against the results produced bythe mutants.
Mutantoperators are designed referring to the experience of using the target
language and of the most common faults. In the past mutantoperators were de-
signed based experts’ knowledge. Recently,Kim et al. [10] haveproposed the use
of atechnique named “Hazard and OperabilityStudies” (HAZOP) to systemati-
cally derivemutantoperators and they applied it to the Javalanguage. Although
the resulting operators do not significantly differ from past works, the proposed
methodology is an importantstep towards amore rigorous discipline in the creation
of mutantoperators. The technique is based on twomain concepts. It first iden-
tifies in the grammar of the taget language (Javain this case) the points subject
to mutation and then defines the set of mutations these points based on suuitable
“Guide Words”.
In general, acomprehensiveset of mutantoperators, that well cover the struc-
tures of agiven language tends to produce toomanymutants even for small pro-
grams. This problem has been tackled byselecting subsets of mutants according
to differentstrategies [21, 16, 13] likerandomly selecting apercentage of the gen-
erated mutants or choosing asubset of the mutantoperators based on some known
characteristic likecost or tendency to generate equivalentmutants.
The test of concurrentprograms is complicated bythe nondeterminism of their
execution, that in the case of mutation testing, makes it difficult to analyze the
behavior of the mutants. Since aprogram in this context can presentdifferent
correct results, the fact that the behavior of amutantdiffers from the result of the
original program for atest case tdoes not mean that thas revealed the fault in the
mutant. The discrepancy mayresult from the non determinism of the program and
not from the fault seeded in the mutant.
Twodifferentapproaches to apply mutation testing to concurrentprograms have
been proposed in the literature [17, 19]. Both haveADAas their target language and
are presented with more details in the next section. Unfortunately the approaches
do not extend straightforwardly to other languages, suchas Java, that are not
based on the Ada rendezvous model. Apilot study that used apre-existentmutant
operator set confirmed the need of mutantoperators specifically designed for the
Javamodel of concurrency and synchronization [2].
This paper describes part of the work that aims at applying mutation testing to
Javaconcurrentprograms. Herein wedescribethe design of mutantoperators. In
Section 2weoverview previous work on mutation testing for concurrentprograms,
and in particular the work of Silva-Barradas [19] that is closely related to our goals.
In Section 3webriefly explains the mechanisms used for synchronization and con-
currency in Java. In Section 4wepresentthe set of mutantoperators designed
to exercise those mechanisms. The conclusions and ongoing works related to this
paper are presented in Section 5.
XV Simpósio Brasileiro de Engenharia de Software
- 273 -
2Mutation Testing for ConcurrentPrograms
When testing asequential program, one can rely on the fact that there exists only
one correct output for agiven test data. The statements are executed in adeter-
mined order that does not change from one execution to another, if the input is the
same. This is not true for concurrentprograms. The parallel or concurrentexecu-
tion of several (deterministic) processes mayresult in differentoutputs, depending
on the order of execution of the differentprocesses.
This is particularly troublesome for mutation testing. When amutantMis
executed with atest case t,it should bekilled if its behaviour is incorrect, according
to agiven specification. In the case of asequential program this is equivalentto say
that the results of the execution of Mwith tdiffers from the results of the execution
of the original program Pwith t.In the case of concurrentprograms weshould
compare the set of all possible results of Mwith tagainst the set of all possible
results of Pwith tand then consider Mdistinguished if they are not the same.
Unfortunately,in general it is not possible to knowthe set of all possible results
of aconcurrentprogram for agiven input. Offut et al. [17] proposed atechnique
that calculates an approximated set Ω, defined as asubset of all possible results
of P(t). This set is calculated byexecuting P(t)several times. The mutantMis
distinguished if it produces at least one result M(t)/Ω.
Another approach, called “Behavior Mutation Analysis” (BMA), is defined by
Silva-Barradas [19]. Asuitable instrumentation of an ADAprogram Pcan beused
to register the sequence of execution of its tasks. The recorded sequence can beused
to reproduce the same behavior in asubsequentexecution of P(t). Incorporating
this synchronization sequence as part of atest case, it is expected that M(t,s)=
P(t,s), i.e., the result of the execution of the mutantMwith treproducing the same
synchronization sequence should bethe same of the original program. The BMA
technique considers the mutantdistinguished if one of the twoconditions is verified:
1) M(t,s)=P(t,s); or 2) Mcannot reproduce the synchronization sequence s.The
second case mayoccur, for example, if the mutation eliminates astatementthat
when executed adds an eventto the synchronization sequence, e.g., a entry call. In
this case, BMA considers that the mutanthas an incorrect behavior (deadlockor
abnormal termination) and thus should bedistinguished.
In apilot study [2] wetried this approachusing existing operators [4] adapted to
Javaand wecould derivesome importantobservations that are guiding the current
developmentof the technique for the Javalanguage.
Amutantcan bedistinguished byeither producing adifferentoutput or be-
cause it cannot reproduce the same synchronization sequence of the original
program. In general amutantthat can bedistinguished byone reason can-
not bedistinguished bythe other. In afew cases though it is possible to
find mutants that can bedistinguished from the original program both be-
cause producing adifferentoutput for atest case t1and because not able to
reproduce the required synchronization sequence for adifferenttest case t2.
Although in general mutants should bekilled if distinguished in either ways,
for suchmutants it would beuseful to require both cases for killing them, since
the differenttest cases can reveal differentfaults;
The number of equivalentmutants, i.e., mutants that cannot bedistinguished
byeither reasons, is very low. In the pilot study only 2out of the 144 mutants
XV Simpósio Brasileiro de Engenharia de Software
- 274 -
public class myclass {
public synchronized void myMethod()
{
doSomething();
}
public void myOtherMethod()
{
doSomeOtherThing();
}
}
Figure 1: Example of synchronized method
created were equivalents;
It is harder to analyze mutants when concurrency is involved, mainly when it
is necessary to induce certain specific synchronization sequence to distinguish
them. Auseful help in this matter would bethe construction of atool that
could generate differentsynchronization sequences to test the program. We
already knowthat atool is necessary to record the synchronization sequences
of the test cases so they can bereproduced in the mutant. In the ongoing
work of developing suchtool weare studying ways to create valid variants of
an original synchronization sequence. Suchvariants can beuseful for testing
the program and killing the mutants.
The set of mutantoperators, based on the Interface Mutation operators [4],
used in the pilot study is not sufficient. Although wecould not formally eval-
uate the qualityof the test set obtained because no other criterion exists
(in our best knowledge) against whichwecould evaluate it wecould intu-
itively note that some characteristics (either functional and structural) related
to concurrency where not exercised and an existing bug could not berevealed.
In the next section wesummarize the features of the Javalanguage related to
concurrency and synchronization and that conduced to the mutantoperator set
described in Section 4.
3Overview of JavaConcurrency Mechanisms
The basic mechanism for thread synchronization in Javaare synchronized methods
and blocks. Every object in Javahas amonitor associated to it. This monitor is
used to guarantee that only one thread at time has access to the object. Figure 1
shows an example of synchronized method. In aprogram with twoor more threads
sharing an object Xof typemyClass,only one at atime can enter myMethod using
that object. The access to myOtherMethod does not havesuchrestriction. So a
thread T1can execute, for instance, myMethod on object Xconcurrently with thread
T2,executing myOtherThread on the same object X.
If agiven thread T1is executing asynchronized methodon an object Xand
another thread T2tries to enter asynchronized methodon the same object the
XV Simpósio Brasileiro de Engenharia de Software
- 275 -
free monitor free monitor 2
lock monitor lock monitor 2
want lock want lock 2
Monitor
Accessing obj Accessing obj 2
Contation Contation 2
Exc Normal Exc Normal 2
Figure 2: Basic model of 2threads sharing an object
system blocks T2until T1terminates executing the synchronized method. Then T2
can execute, or more precisely,it can compete to get access to the object, since other
threads mayalso havebeen trying to access the same object within asynchronized
method.
When athread T1gains access to asynchronized methodof an object Xwe
saythat T1owns or has locked X’s monitor. Astatic methodcan besynchronized.
In this case entering the methodlocks the monitor associated to the Class object
associated to the class where the methodis defined.
Figure 2shows asimple Petri Net model of twothreads that share an object X.
The places named Exec Normal representthe states of eachthread when they are
executing non synchronized code w.r.t. the object of interest. Athread maywantto
execute asynchronized methodon Xand then it reaches a contention state, where
it will lockthe monitor, if it is available. On succeeding, the token is removed from
the monitor place and is holden until the thread finishes the synchronized method
and releases the monitor.
Synchronized blocks are similar to synchronized methods but protected code is
restricted only to apiece of amethodand the object on whichthe lockis exe-
cuted is explicitly declared. For example, in the code in Figure 3, the thread must
obtain the monitor of myObject before executing doSomeOtherThing,in method
myOtherMethod.
Every object created in the JVM has associated await set whichallows athread
in possess of amonitor to temporarily release that monitor until an eventoccurs.
Class Object defines await methodthat releases the monitor of the object used in
XV Simpósio Brasileiro de Engenharia de Software
- 276 -
public class myclass {
myOtherClass myObject = new myOtherClass();
public synchronized void myMethod()
{
doSomething();
}
public void myOtherMethod()
{
synchronized (myObject)
{
doSomeOtherThing();
}
}
}
Figure 3: Example of synchronized block
the call and insert the currentthread in the object wait set, temporarily blocking
its execution. The definition of methodwait explicitly states that the thread that
calls the wait must beholding the monitor of the object, otherwise an exception is
thrown. Since every class in Javainherits from class Object,every object created
in Javahas amethodwait (declared final in the class Object).
Class Object also declares amethodnotify whichwakes up athread waiting
in await set. When this methodis called on an object Xone of the threads is
randomly removed from the wait set, becoming ready to execute. This does not
mean that it will beexecuted immediately.First because the thread that calls
notify must bein possess of the object monitor, thus the thread removed from
the wait set can execute only after the currentthread releases the lock. Moreover,
even after the currentthread has released the lock, there is no guarantee that that
specific thread will bethe one that acquires the monitor because other threads may
bein contention for the same monitor.
The thread removed from the wait set will resume from the pointimmediately
after the call to wait and its state returns to the same it had at that time, i.e.,
in possess of the monitor and with the same lockcountit had on that monitor.
For example, if it had locked the monitor twice, it reacquires the monitor with lock
countequals two. Figure 4shows the example of twothreads that share an object,
including the call of methodwait.Note that the model becomes significantly more
complex than that shown in Figure 2.
The wait methodhas avariantthat accepts as argumentatimeout value. The
semantics of this call is similar to the one described above, i.e., the thread is inserted
in the wait set until anotify removes it. In addition, if it is not removed byanotify
within the specified timeout, it is removed “by itself”. The notify methodhas a
variantnotifyAll that, when called on object X,removes all the threads from the
wait set of object X.
Other methods in the API complete the resources of the language for concur-
rency.Among them, the methods in the class Thread,responsible for the creation
and managementof new threads.
XV Simpósio Brasileiro de Engenharia de Software
- 277 -
get notify get notify 2
wait wait 2
free monitor free monitor 2
lock monitor lock monitor 2
want lock want lock 2
wait list
wait list 2
Monitor
Accessing obj Accessing obj 2
Contation Contation 2
Exc Normal Exc Normal 2
Figure 4: Model of twothreads sharing an object, including wait sets
4MutantOperators for Java
In this section wepresentaset of mutantoperators designed to exercise the con-
currency and synchronization aspects of Javaprograms. First weidentify the main
structures related to concurrency and then wederivemutantoperators to exercise
suchstructures. One essential aspect taken in consideration is that the practical ap-
plicability on mutation testing heavily depends on the number of mutants generated
bythe approach.
Based on the overview presented in Section 3weidentified four groups of struc-
tures of Javarelated to concurrency:
Monitor lockcode;
Methods related to wait set manipulation that are defined in the Javacore
API;
Use of synchronized methods;
Use of other methods related to synchronization and concurrency.
Eachof these classes are analyzed and mutation operator to exercise them are
proposed in the following sections.
XV Simpósio Brasileiro de Engenharia de Software
- 278 -
synchronized public void append (Element x)
{
while (cont >= buffer.length)
wait();
buffer[nextSpot] = x;
nextSpot = (nextSpot + 1) % buffer.length;
// nextSpot = (nextSpot * 1) % buffer.length; <<== mutation
cont++;
notify();
}
Figure 5: Asynchronized methodand apossible mutant
4.1 Monitor locks
The class of monitor locks include synchronized methods and statements. Amethod
is declared synchronized adding the keyword synchronized in frontof its declara-
tion, for example
synchronized public foo(int k, String s)
{
...
}
The first mutantoperator identified for this construc is the deletion of the key-
word synchronized,turning the methodto “normal”, regardless of the monitor
acquisition. This will require test cases that exercise the concurrentuse of each
synchronized method.
The objectiveof amutation is to create aprogram with behavior that slightly
differs fro the behavior of the original program. In the particular case of synchro-
nized methods, wewantamethodthat when called will produce a differentbehavior
related to the access to ashared object. This could beachieved bymutating any
statementin the body of the method. Wecould use mutantoperators similar to
those previously defined for unit testing [1, 12, 11] to obtain the discrepantbehavior.
For example, the code in Figure 5shows asimple methodthat inserts an element
in acircular shared buffer, used in aproducer-consumer system, and apossible
mutant.
If on one hand this mutantmayhelp to exercise importantfeatures in the pro-
gram, forcing for example atest case that uses abuffer larger than one element,
on the other hand all suchmutants would makethe test impractical. First because
the number of mutants would growto an undesirable level. Second, because these
“fine grained” mutants would change the state of the program in suchawaythat
would makevery hard for the tester to analyze them. In apilot study [2], the
use of Interface Mutation operators [4] confirmed these twoconjectures. To avoid
these problems wedefine only one typeof mutation to beapplied in the body of a
synchronized method, i.e., statementdeletion, as defined in [1].
This operator removes one statementat eachtime. In this waywereduce the
number of mutants and create mutants that are easier to beanalyzed because they
XV Simpósio Brasileiro de Engenharia de Software
- 279 -
representmore significantand understandable changes in the code. Using the def-
inition of Offut and Hayes [15], wehavemutants with alarger syntactic difference
from to the original program and as side effect it is expected also alarger semantic
difference.
Asynchronized statementis defined in [9] as
SynchronizedStatement: synchronized (Expression )Block
The twomutantoperators defined for synchronized methods can beapplied. The
first removes the declaration of the blockas synchronized and the second deletes
astatementinside the block. Wecan also apply operator “movebrace up/down”
as defined byAgrawal et al. [1] to the synchronized block. This operator moves
the closing brace one statement“up” moving the last statementout of the blockor
one statement“down” including in the blockthe first statementdeclared outside.
Wecan apply asimilar operator to the beginning of the block, excluding the first
statementor inserting the immediately previous one. These operators generate only
few mutants (at most four per synchronized block) and are amore subtle version
of the statementdeletion operator. Test cases that distinguish suchmutants might
beuseful to verify the limits that asynchronized statementmust have.
The semantic of asynchronized statementindicates that its synchronization
expression should evaluate to an object, i.e., an instance of java.lang.Object or
one of its subclasses. Toguarantee that the programmer used the correct expression,
i.e., that the synchronization is being done in the rightobject wecan replace the
synchronization expression byother objects accessible in that scope. So wedefine
four mutantoperators:
replace the synchronization expression with alocal variable;
replace the synchronization expression with aformal parameter;
replace the synchronization expression with astatic field; and
replace the synchronization expression with an instance field;
4.2 Wait sets
In this section wepresentthe operators designed to exercise another main feature
of the Javasynchronization mechanism: the wait sets. Basically,the wait sets are
managed bytwotypes of methods: 1) those that ask the system to blockathread
inserting it in await set (wait and timed wait methods); and 2) those that ask the
system to removethreads from await set (notify and notifyAll).
The mutantoperators designed to deal with the use of the wait methods are:
Delete acall to wait.In this case the thread that should beblocked continues
executing. Test cases that kill this kind of mutants showthe relevance of each
wait call. This maybeparticularly importantfor timed wait that mayrequire
very specific test cases to beeffectively used.
Replace a timed wait with anon-timed.
Replace anon-timed wait with atimed.
Incrementand decrementtime in a timed wait.These last three operators
exercise timing aspects of aprogram.
XV Simpósio Brasileiro de Engenharia de Software
- 280 -
For exercising the use of notify methods wedefine:
Delete acall to notify or notifyAll.This operator changes the set of threads
available for execution at agiven pointof the execution. Test cases must be
provided in order to showthat eachof suchcalls is really necessary.
Replace acall to notify with acall to notifyAll.
Replace acall to notifyAll with acall to notify.These twooperators might
beuseful for testing synchronization aspects because test cases that distinguish
them mayrequire the execution of very specific sequences of wait and notify
statements, otherwise difficult to exercise.
4.3 Synchronized methodcalls
The operators in this class aim at exercising the interactions with methods declared
as synchronized as they are amain feature of the Javalanguage, for what concern
synchronization. Note that these operators differ from those defined in Section 4.1
because those are related to the declaration of synchronized methods and the ones
defined here are related to the use of suchmethods, i.e., the invocation of such
methods.
The typeof interactions wewantto exercise here are similar to those exercised
bythe Interface Mutation approach[4]. Interface Mutation defines aset of mutant
operators that focus on the interaction between twounits, e.g., twofunctions in the
Clanguage. Here wewantto specifically exercise the use of synchronized methods,
changing the points where they are invoked. Based on the set of Interface Mutation
operators wedefine the following operators:
Replace arguments with constants. Eachargumentis replaced with constants
defined according to the typeof the argument. For example int arguments
can bereplaced with {0, 1, -1, Integer.MAX VALUE, Integer.MIN VALUE}
where MAX VALUE and MIN VALUE are respectively the largest positive
integer and the smallest negativeinteger as defined bythe JavaAPI. The sets
of required constants for eachtypein the language is shown in Table 1;
Delete the call. If the methodreturns avalue that is used in an expression
then the call is replaced with constants of the typeof the returned value;
Switcharguments of compatible types;
Change methodsignature. Change the methodcall byremoving one of the
arguments or adding anew argument, changing the call to matchthe decla-
ration of another methodwith the same name but with differentsignature, if
suchmethodexists;
Insert arithmetic negation before an argument. Invert the sign of an argument
byinserting an arithmetic negation, if allowed bythe typeof the argument.
If the argumentis an expression, only the whole expression is negated, not
subexpressions;
Insert logical negation before an argument;
Insert bit negation before an argument;
Incrementand decrementan argument;
XV Simpósio Brasileiro de Engenharia de Software
- 281 -
Change target object. Use another type-compatible object to makethe call.
Wecan subdivide this mutation depending on whichobject is used to replace
the original one. So wecan have: 1) replace with local variable; 2) replace
with formal parameter; 3) replace with static field; 4) replace with instance
field.
Table 1: Set of constants for operator “Replace arguments with constants”
TypeConstants
int0, 1, -1, Integer.MIN VALUE, Integer.MAX VALUE
short 0, 1, -1, Short.MIN VALUE, Short.MAX VALUE
byte 0, 1, -1, Byte.MIN VALUE, Byte.MAX VALUE
long 0, 1, -1, Long.MIN VALUE, Long.MAX VALUE
char 1, Character.MIN VALUE, Character.MAX VALUE
boolean true, false
float 0.0, 1.0, -1.0, Float.MIN VALUE, Float.MAX VALUE
double 0.0, 1.0, -1.0, Double.MIN VALUE, Double.MAX VALUE
String ””, null
other objects null
4.4 Other synchronization methods
Other methods that are not part of the “core” mechanisms for synchronization in
Javahavebeen defined in the JavaAPI and are importantfor the implementation of
concurrentprograms. Tothese methods wecan apply the same mutations defined
in the last section, changing their behavior bymutating the calls to them.
The methods weidentify in this class of mutations are: Thread.interrupt,
Thread.join,Thread.sleep,Thread.start and Thread.yeld.
Note that some operators, when applied to specific structures in aprogram can
generate the same mutation, or more precisely,mutants with the same behavior.
This is the case for example of deleting astatementin asynchronized blockand
deleting await call. If the first is applied, the second does not haveto beapplied.
This is not uncommon in the definition of mutantoperators and allows one to use
an incremental approachto choose the mutantoperators.
Muchof the mutantoperator set can beparameterized according to the the
implementor’s or even the tester’s will. For example: the value to add/subtract on
timed wait;the set of constants to use in the replacements described in Section 4.3;
the methods subject to mutation described in Section 4.4.
Table 2summarizes the set of mutantoperators.
5Conclusion and Future Work
This paper discussed the use of mutation testing for concurrentJavaprograms.
Mutation testing has been shown to bean effectivewayof testing software in terms
of fault revealing capacityand it has been widely explored. One advantage of
mutation testing is its flexibilityin the sense that it can beapplied to several scopes,
e.g, unit and integration testing in differentlanguages [17, 4], test of object oriented
XV Simpósio Brasileiro de Engenharia de Software
- 282 -
Table 2: Proposed set of mutantoperators
Operator name Meaning
DelSync Removes the synchronized attribute from amethod
declaration or removes asynchronized statement
DelStat Deletes astatementin asynchronized methodor block
MoveBrace Moves {and }up and down
ReplSyncObject Replaces synchronization object
DelWait Deletes acall to the wait method
ReplWait Replaces acall to atimed wait byacall to anon-timed
wait and vice-versa
IncrDecrWait Incrementand decrementargumentfor timed wait
DelNotify Deletes acall to notify or notifyAll
ReplNotify Replaces acall to notify byacall to notifyAll and
vice-versa.
ReplArg Replaces argumentwith constant
DelSyncCall Deletes acall to asynchronized method
SwitchArg Switcharguments in acall to synchronized method
ReplMeth Uses methodwith same name and other signature
InsNegArg Inserts unary (negation) operators in an argument
ReplTargObjReplaces the object in acall to synchronized method
programs [11] and test of formal specifications using differentlanguages [7, 8, 6, 20].
Toadapt the criterion to these differentscenarios it is necessary to identify the
characteristics one wants to exercise on that specific scopeand to develop mutant
operators for it.
This paper focuses on the definition of mutantoperators to exercise the features
of the Javalanguage related to concurrency and synchronization. Mutantoperators
for other concurrentenvironments havebeen defined [17, 19], but due to the differ-
ences between those environments and the Java environment, new mutantoperators
are required to address concurrency in Java. Apilot study [2] has been conducted
using well knowoperators, not specifically designed to this goal, and confirmed
this necessity.The mutantoperators herein presented tries to cover most of the
concurrency- and synchronization-related features of the Java environmentand still
becost effective, restricting the number of operators and mutants that they can
generate.
The application of mutation testing to concurrentprograms introduces addi-
tional problems. In particular it is necessary to deal with the intrinsic nondeter-
minism derived from concurrency.The execution of aprogram with agiven input
can produce differentcorrect behaviors. This constitutes aproblem in comparing
the results of executing mutants with the results of the original program. Atool
that supports mutation testing in this scenario must provide awayto assure that
twoexecutions of aprogram with the same test case lead to the same behavior.
Currently weare working on developing the tools necessary to experimentthe re-
sults described in this paper. The first tool applies the mutantoperators described
in this paper to automatically generate mutants. The second aims at recording
executions of the original program to execute the same synchronization sequences
XV Simpósio Brasileiro de Engenharia de Software
- 283 -
on its mutants.
6Acknowledgements
The authors would liketo thank CNPq, CAPES and FAPESP for partially sup-
porting this project.
References
[1] H. Agrawal, R. A. DeMillo, R. Hataway,Wm. Hsu, W. Hsu, E. Krauser, R. J.
Martin, A. P.Mathur, and E. H. Spafford. Design of MutantOperators for
CProgramming Language. TechReport SERC-TR41-P,Software Engineering
ResearchCenter, Purdue University,March1989.
[2] M. Delamaro, M. Pezz`e, A. M. R. Vincenzi, and J. C. Maldonado. Ap-
plying Mutation Testing to Multi-threaded JAVA Programs. TechReport,
www.din.uem.br/˜delamaro/papers/relat.ps.gz,2001.
[3] M. E. Delamaro. Proteum: Um Ambiente de Teste Baseado Na Aalise de
Mutantes.Master thesis, SCE-ICMSC-USP,ao Carlos -SP,October 1993.
[4] M. E. Delamaro, J. C. Maldonado, and A. P.Mathur. Interface Mutation: An
Approachfor Integration Testing. IEEE Transactions on SoftwareEngineering,
27(3):228–247, March2001.
[5] R. A. DeMillo and A. J. Offutt. ConstraintBased Automatic Test Data Gener-
ation. IEEE Transactions on SoftwareEngineering,17(9):900–910, September
1991.
[6] S. C. PF. Fabbri. AAn´alise de Mutantes No Contexto de Sistemas Reativos:
Uma Contribui¸ao ParaOEstabelecimento de Estrat´egias de Teste eValida¸ao.
Doctoral dissertation, IFSC -USP,ao Carlos -SP,October 1996.
[7] S. C. P.F. Fabbri, J. C. Maldonado, P.C. Masiero, and M. E. Delamaro.
Mutation Analysis Testing for Finite State Machines. In Proceedings of the 5th
International Symposium on SoftwareReliability Engineering (ISSRE),pages
220–229, Monterey -CA, November 1994.
[8] S. C. P.F. Fabbri, J. C. Maldonado, P.C. Masiero, and M. E. Delamaro.
Mutation Analisys Applied to Validate Specifications Based on Petri Nets. In
Proceeding of the 8th IFIP Conferenceon Formal Descriptions Techniques for
Distribute Systems and Communication Protocols,pages 329–337, Montreal,
October 1995.
[9] J. Gosling, B. Joy,G. Steele, and G. Bracha. Tha Java Language Specification.
JavaSeries. Addison-Wesley,2nd edition, June 2000.
[10] S. Kim, J. A. Clark, and J. McDermid. The Rigorous Generation of Java
Mutation Operators Using HAZOP.In Proceedings of the 12th International
Conferenceon Software&Systems Engineering and their Applications (IC-
SSEA’99),December 1999.
[11] S. Kim, J. A. Clark, and J. McDermid. Class Mutation: Mutation Testing for
Object-Oriented Programs. In Proceedings of the FMES,October 2000.
[12] K. N. King and A. J. Offutt. AFortran Language System for Mutation Based
Software Testing. Software-Practiceand Experience,21(7):685–718, July 1991.
XV Simpósio Brasileiro de Engenharia de Software
- 284 -
[13] A. P.Mathur and W. E. Wong. Evaluation of the Cost of Alternate Muta-
tion Strategies. In Proceedings of the 7th Brazilian Symposium on Software
Engineering,pages 320–335, Rio de Janeiro, RJ, Brazil, October 1993.
[14] A. J. Offutt. Coupling Effect: Fact or Fiction. In Proceedings of the 3rd
Symposium on SoftwareTesting, Analysis, and Verification (ISSTA’89),pages
131–140, Key West, FL, December 1989.
[15] A. J. Offutt and J. H. Hayes. ASemantic Model of Program Faults. In
Proceedings of the International Symposium on SoftwareTesting and Analisys
and Verification (ISSTA’96),San Diego, CA, 1996.
[16] A. J. Offutt, A. Lee, G. Rothermel, R. H. Untch, and C. Zapf. An Experimental
Determination of SufficientMutantOperators. ACM Transactions on Software
Engineering Methodology,5(2):99–118, 1996.
[17] A. J. Offutt, J.M. Voas, and J. Payne. Mutation Operators for ADA. Tech-
nical Report ISSE-TR-96-09, Departmentof ISSE, George Mason University,
Fairfax, VA, March1996.
[18] R. L. Probert and F. Guo. Mutation Testing of Protocols: Principles and Pre-
liminary Experimental Results. In IFIP TC6 ThirdInternational Workshop
on Protocol Test Systems,pages 57–76. North-Holland, 1991.
[19] S. Silva-Barradas. Mutation Analysis of Concurrent Software.Phd thesis,
Departmentof Eletronic and Informatics, Polythecnic of Milan, Milan, Italy,
1997.
[20] S. R. S. Souza, J. C. Maldonado, S. C. P.F. Fabbri, and W. Lopes de Souza.
Mutation Testing Applied to Estelle Specifications. In 33rdHawaii Interna-
cional Conferenceon System Sciences, Mini-Tracks: DistributedSystems Test-
ing,Maui, Hawai, January 2000. (Accepted for publication in aspecial issue
on Distributed Systems Testing of the Software QualityJournal).
[21] A. M. R. Vincenzi, J. C. Maldonado, E. F. Barbosa, and M. E. Delamaro.
Unit and Integration Testing for CPrograms Using Mutation-based Criteria.
Journal of SoftwareTesting, Validation and Reliability,2001. to appear.
XV Simpósio Brasileiro de Engenharia de Software
- 285 -
... Researchers have developed many sets of mutation operators [158,102], targeting a variety of programming languages. For example, Delamaro et al. and Bradbury et al. have proposed di↵erent set of mutation operators for concurrent Java programs [54,28]. My empirical study and analysis shows that some subtle concurrency bugs are not generated by any of these proposed first-order mutation operators. ...
... To measure the testability of concurrent Java programs, Ghosh described mutation based on two mutation operators that remove the keyword synchronized [80]. Long et al. proposed a set of 15 concurrency mutation operators for Java [54]. Later, Bradbury et al. ...
... My empirical study shows that a large portion of existing mutation operators are not e↵ective in generating mutants. For example, several previously proposed mutation operators for concurrent Java, including MSF, MXC, MBR, RCXC, ELPA, EAN, RSTK, RFU, RXO and EELO [54,28], did not generate any mutants in my experiments. Some others, including MXT, RNA, RJS, InsNegArg, and ReplTargObj [54,28], generated very few mutants. ...
Thesis
Full-text available
Cyber-physical systems (CPS) are systems featuring a tight combination of, and coordi- nation between, the system’s computational and physical elements. Cyber-physical systems include systems ranging from critical infrastructure such as a power grid and transportation system to health and biomedical devices. System reliability, i.e., the ability of a system to perform its intended function under a given set of environmental and operational conditions for a given period of time, is a fundamental requirement of cyber-physical systems. An unreliable system often leads to disruption of service, financial cost and even loss of human life. An important and prevalent type of cyber-physical system meets the following criteria: processing large amounts of data; employing software as a system component; running online continuously; having operator-in-the-loop because of human judgment and an ac- countability requirement for safety critical systems. This thesis aims to improve system reliability for this type of cyber-physical system.
... Ghosh [41] designed two mutation operators that remove the keyword synchronized. Delamaro et al. [42] recognized four groups of structures in Java programming language related to concurrency. They also suggested a set of different concurrency mutation operators such as removing a synchronized statement, or deleting a call to the wait method. ...
... This approach selects two first-order mutation operators to modify a synchronized method or block and conducts code changes related to the same synchronized method or block. The two operators are selected among the five first-order mutation operators related to synchronized methods in concurrent Java proposed in [42,43]. At the end, the selected second-order concurrency mutation operators are combined with the first-order mutation operators to construct a smaller set of mutation operators for generating mutants. ...
Article
Full-text available
Higher-order subtle mutants are faults that are hard to detect or kill by the existing test set used for killing all the first-order mutants of the given program. Recently, some techniques have been proposed to construct higher-order subtle concurrency mutants that are not represented by the first-order mutants. To the best of our knowledge, there is no test-input generation technique proposed to kill this type of mutants. This paper proposes a search-based technique for generating a set of test inputs to kill higher-order subtle concurrency mutants. The proposed technique utilizes genetic algorithms in generating the set of test inputs. The performance of the proposed technique is evaluated and compared with that of the random-based test-data generation technique. The obtained results demonstrate the effectiveness of the proposed technique as it outperforms the random technique in terms of the killing ratio for the generated set of subtle concurrency mutants and the size of test suite. In the range of tested set of subtle concurrency mutants, the proposed technique approximately killed 91.4% of all mutants using 79 test cases compared to 82.8% using 128 test cases for the random technique.
... Nesta abordagem são emuladas falhas em componentes de hardware, acelerando a manifestação de erros devidos a tais falhas e assim permitindo observar o comportamento do sistema sob teste. A injeção de falhas emuladas de hardware por software é diferente da injeção de falhas de software, onde é comum a geração de mutantes de código [Delamaro et al. 2001b, Delamaro et al. 2001a] para verificação da cobertura dos procedimentos de teste. A injeção de falhas por software opera principalmente alterando o fluxo de execução para que as rotinas do injetor responsáveis pela emulação das falhas de hardware possam inserir erros na aplicação sob teste durante sua execução. ...
Conference Paper
Injeção de falhas de comunicação visa emular falhas comuns a sistemas baseados em rede para assim observar o comportamento de aplicações em resposta a diferentes condições de falha. Apesar de eficiente, a técnica não é suficiente para validar outras características funcionais importantes de uma aplicação. Para aumentar a cobertura dos testes, injeção de falhas deve ser usada de forma complementar a técnicas convencionais de teste e operar integrada a plataformas de desenvolvimento e teste de sistemas. Visando atender estes requisitos, este trabalho apresenta um injetor de falhas para a avaliação de aplicações distribuídas baseadas em RMI, e sua integração aos frameworks JUnit e ANT.
... A etapa de geração ou injeção de mutantes dentro de uma aplicação também pode ser diferente de acordo com a tecnologia utilizada. Em cada linguagem de programaçãoé possível utilizar operadores de mutação especializados para a tecnologia [Delamaro et al. 2001]. Neste estudo foram utilizados os seguintes operadores de mutação baseados no estudo [Mirshokraie et al. 2015]: 1) Variável local/global: Adição, atualização ou remoção de uma variável; 2) Parâmetro de função: Adição, atualização ou remoção de um parâmetro de função; 3) Condição de laço de repetição: Atualização de uma condição utilizada em laços de repetição; 4) Condição em condicional: Atualização de uma condição utilizada em alguma estrutura condicional; 5) Retorno: Atualização do retorno de uma função; 6) DOM: Operador específico para aplicações web, onde pode ser atualizado algum elemento presente naárvore de elementos presentes no HTML [Raggett et al. 1999]. ...
Conference Paper
A análise estática de código é uma técnica aplicada na etapa de verificação de um software, com o objetivo de identificar defeitos sem a necessidade da execução da aplicação. Atualmente existem diversas ferramentas de análise estática disponíveis no mercado, onde cada uma possui suas particularidades e diferentes escopos de análise. Portanto, escolher a ferramenta correta a ser usada não é uma atividade trivial. Este estudo tem como objetivo comparar duas ferramentas de análise estática de código sendo elas o SonarQube e o PMD, analisando a sua eficácia na identificação de defeitos em um código de software. Com esta finalidade foram criados mutantes a partir de projetos Open Source, que auxiliaram a verificar a eficácia das ferramentas.
... Deng et al. [20] defined mutation operators specific to the characteristics of Android apps, such as the event handler and the activity lifecycle. Previous work also proposed other Java-specific mutation operation sets related to object-oriented programming [34] and concurrency mechanisms [9,17]. ...
Article
Mutation testing injects code changes to check whether tests can detect them. Mutation testing tools use mutation operators that modify program elements such as operators, names, and entire statements. Most existing mutation operators focus on imperative and object-oriented language constructs. However, many current projects use meta-programming through code annotations. In a previous work, we have proposed nine mutation operators for code annotations focused on the Java programming language. In this article, we extend our previous work by mapping the operators to the C# language. Moreover, we enlarge the empirical evaluation. In particular, we mine Java and C# projects that make heavy use of annotations to identify annotation-related faults. We analyzed 200 faults and categorized them as “misuse,” when the developer did not appear to know how to use the code annotations properly, and “wrong annotation parsing” when the developer incorrectly parsed annotation code (by using reflection, for example). Our operators mimic 95% of the 200 mined faults. In particular, three operators can mimic 82% of the faults in Java projects and 84% of the faults in C# projects. In addition, we provide an extended and improved repository hosted on GitHub with the 200 code annotation faults we analyzed. We organize the repository according to the type of errors made by the programmers while dealing with code annotations, and to the mutation operator that can mimic the faults. Last but not least, we also provide a mutation engine, based on these operators, which is publicly available and can be incorporated into existing or new mutation tools. The engine works for Java and C#. As implications for practice, our operators can help developers to improve test suites and parsers of annotated code.
... Mutation testing is a powerful methodology to evaluate the effectiveness of test suites. It was first proposed by Demillo et al. [4] and Hamlet [5], and has gained increasing popularity [19], [27], [82]. Despite its effectiveness, mutation testing has a main limitation, i.e., it is extremely expensive since it needs to execute the test suite on each mutant. ...
Article
Test suites play a key role in ensuring software quality. A good test suite may detect more faults than a poor-quality one. Mutation testing is a powerful methodology for evaluating the fault-detection ability of test suites. In mutation testing, a large number of mutants may be generated and need to be executed against the test suite under evaluation to check how many mutants the test suite is able to detect, as well as the kind of mutants that the current test suite fails to detect. Consequently, although highly effective, mutation testing is widely recognized to be also computationally expensive, inhibiting wider uptake. To alleviate this efficiency concern, we propose Predictive Mutation Testing (PMT): the first approach to predicting mutation testing results without executing mutants. In particular, PMT constructs a classification model, based on a series of features related to mutants and tests, and uses the model to predict whether a mutant would be killed or remain alive without executing it. PMT has been evaluated on 163 real-world projects under two application scenarios (cross-version and cross-project). The experimental results demonstrate that PMT improves the efficiency of mutation testing by up to 151.4X while incurring only a small accuracy loss. It achieves above 0.80 AUC values for the majority of projects, indicating a good tradeoff between the efficiency and effectiveness of predictive mutation testing. Also, PMT is shown to perform well on different tools and tests, be robust in the presence of imbalanced data, and have high predictability (over 60% confidence) when predicting the execution results of the majority of mutants.
... Um dos critérios de teste da técnica baseada em defeitos é o teste de mutação. Este critério utiliza informações sobre os erros típicos que podem ser cometidos no processo de desenvolvimento para derivar casos de teste (Delamaro et al., 2001). Assim, os defeitos típicos de um domínio ou paradigma de desenvolvimento são caracterizados e implementados como operadores de mutação que, durante a atividade de teste, geram versões modificadas do produto em teste, chamados de mutantes. ...
Conference Paper
Full-text available
Concurrent programming became a popular paradigm for software development.Mutation Testing is a criterion based on the most common mistakes that might be madeby software developers. Software architecture stepped in to deal with large and complexsystems. In this area we find reference architecture, which is an architectural pattern thatdescribes all systems in a domain, for example, RefTEST to software testing domain.This paper presents the instantiation of architecture for a mutation testing tool. Thisarchitecture has been instantiated based on the RefTEST reference architecture and as aresult can be observed class diagrams of the test tool.
Conference Paper
Mutation testing is a powerful methodology for evaluating test suite quality. In mutation testing, a large number of mutants are generated and executed against the test suite to check the ratio of killed mutants. Therefore, mutation testing is widely believed to be a computationally expensive technique. To alleviate the efficiency concern of mutation testing, in this paper, we propose predictive mutation testing (PMT), the first approach to predicting mutation testing results without mutant execution. In particular, the proposed approach constructs a classification model based on a series of features related to mutants and tests, and uses the classification model to predict whether a mutant is killed or survived without executing it. PMT has been evaluated on 163 real-world projects under two application scenarios (i.e., cross-version and cross-project). The experimental results demonstrate that PMT improves the efficiency of mutation testing by up to 151.4X while incurring only a small accuracy loss when predicting mutant execution results, indicating a good tradeoff between efficiency and effectiveness of mutation testing.
Article
Full-text available
A novel technique for automatically generating test data is presented. The technique is based on mutation analysis and creates test data that approximate relative adequacy. It is a fault-based technique that uses algebraic constraints to describe test cases designed to find particular types of faults. A set of tools (collectively called Godzilla) that automatically generates constraints and solves them to create test cases for unit and module testing has been implemented. Godzilla has been integrated with the Mothratesting system and has been used as an effective way to generate test data that kill program mutants. The authors present an initial list of constraints and discuss some of the problems that have been solved to develop the complete implementation of the technique.
Conference Paper
Full-text available
Many researchers have pursued the establishment of a low-cost, effective testing and validation strategy at the program level as well as at the specification level. Mutation Testing is an error-based approach, originally introduced for program testing, that provides testers a systematic way to evaluate how good a given test set is. Some studies have also investigated its use to generate test sets. In this article, the application of Mutation Testing for validating Estelle specifications is proposed. A mutant operator set for Estelle - one of the crucial points for effectively applying Mutation Testing - is defined, addressing: the validation of the behavior of the modules, the communication among modules and the architecture of the specification. In this scope, these operators can be taken as a fault model. Considering this context, a strategy for validating Estelle-based specification is proposed and exemplified using the Alternating-bit protocol.
Conference Paper
Amongst the various testing strategies, mutation testing has been empirically found to be the most effective in detecting faults. However, mutation often imposes unacceptable demands on computing and human resources due to the large number of mutants that need to be compiled and executed on one or more test cases. In addition, the tester needs to examine many mutants and analyze these for possible equivalence with the program under test. For these reasons, mutation is generally regarded by the praeticing test engineer as too expensive to use. As one significant component of the cost of mutation is the execution of mutants against test cases, we believe that the cost can be reduced dramatically by reducing the number of mutants that need to be examined. We report the results from a case study designed to investigate two alternatives to reduce the cost of mutation. The alternatives considered are: (1) randomly selected 2% mutation and (2) constrained mutation. We provide experimental data indicating that both alternatives lead to test sets that distinguish a significant number of all mutants and provide high all-uses coverage.
Article
The need for test adequacy criteria is widely recognized. Several criteria have been proposed for the assessment of adequacy of tests at the unit level. However, there remains a lack of criteria for the assessment of the adequacy of tests generated during integration testing. We present a mutation-based interprocedural criterion, named Interface Mutation (IM), suitable for use during integration testing. A case study to evaluate the proposed criterion is reported. In this study, the UNIX sort utility was seeded with errors and Interface Mutation evaluated by measuring the cost of its application and its error revealing effectiveness. Alternative IM criteria using different sets of Interface Mutation operators were also evaluated. While comparing the error revealing effectiveness of these Interface Mutation-based test sets with same size randomly generated test sets we observed that in most cases Interface Mutation-based test sets are superior. The results suggest that Interface Mutation offers a viable test adequacy criteria for use at the integration level.
Article
Mutation testing, originally proposed for unit testing, has been extended to integration testing with the proposition of the Interface Mutation criterion. This paper presents the results of an experiment using two mutation-based testing criteria for unit and integration testing phases: the Mutation Analysis and the Interface Mutation adequacy criteria, respectively. The aim is to investigate how they can be used in a complementary way during the testing activity, establishing an incremental testing strategy comprising the unit and integration testing phases and guidelines on how to obtain a high mutation score with respect to mutation testing with a low cost, in terms of the number of mutants generated. Copyright © 2001 John Wiley & Sons, Ltd.
Conference Paper
Fault-based testing strategies test software by focusing on specific, common types of errors. The coupling effect states that test data sets that detect simple types of faults are sensitive enough to detect more complex types of faults. This paper describes empirical investigations into the coupling effect over a specific domain of software faults. All the results from this investigation support the validity of the coupling effect. The major conclusion from this investigation is that by explicitly testing for simple faults, we are also implicitly testing for more complicated faults. This gives us confidence that fault-based testing is an effective means of testing software.
Conference Paper
Program faults are artifacts that are widely studied, but there are many aspects of faults that we still do not understand. In addition to the simple fact that one important goal during testing is to cause failures and thereby detect faults, a full understanding of the characteristics of faults is crucial to several research areas in testing. These include fault-based testing, testability, mutation testing, and the comparative evaluation of testing strategies. In this workshop paper, we explore the fundamental nature of faults by looking at the differences between a syntactic and semantic characterization of faults. We offer definitions of these characteristics and explore the differentiation. Specifically, we discuss the concept of "size" of program faults --- the measurement of size provides interesting and useful distinctions between the syntactic and semantic characterization of faults. We use the fault size observations to make several predictions about testing and present preliminary data that supports this model. We also use the model to offer explanations about several questions that have intrigued testing researchers.
Conference Paper
Testing is one of the fundamental software development life cycle activities. Considering Reactive Systems such as: metro control, patient hospital monitoring and communication protocols, the testing activity becomes more relevant as errors in these systems can promote severe economical and social losses. The objective of this work is to evaluate the adequacy of applying the Mutation Analysis criterion to validate Petri Net based specifications. A set of mutation operators for Petri Nets, a key point for using Mutation Analysis, as well as the results of applying manually these operators to a Petri Net modeling a level 3 protocol are presented. We also examine the ideas of constrained and randomly selected mutation in this context.
Article
Com o avanço da tecnologia de hardware, a analise de mutantes - um dos criterios de teste baseados em erros - tem sido mais recentemente investigada por diversos pesquisadores e se mostrado um criterio atrativo e factivel para o uso na producao de software. A relevancia e necessidade de ferramentas de teste sao amplamente reconhecidas pela comunidade e esforcos tem sido feitos para o desenvolvimento de ferramentas de apoio a este criterio. Nesta dissertacao sao apresentados os principais aspectos da especificacao e implementacao de um ambiente de teste multilinguagem, denominado proteum (program testing using mutants), que apoia a aplicacao do criterio analise de mutantes para programas em c. Esta ferramenta, alem de caracteristicas comuns a outras ferramentas de teste, procura incorporar algumas caracteristicas proprias como facilidades para a realizacao de experimentos empiricos. A analise de mutantes, bem como os principais trabalhos relacionados com este criterio, sao revistos, procurando fornecer subsidios para a caracterizacao do proteum. Aspectos funcionais da ferramenta sao mostrados, principalmente atraves de um exemplo que ilustra a operacao da ferramenta. A arquitetura e os principais aspectos de implementacao desta ferramenta sao apresentados. Uma avaliacao da ferramenta e feita testando-se alguns programas extraidos da literatura. Dissertação (Mestrado)--Instituto de Ciências Matemáticass de São Carlos, da Universidade de São Paulo.
Conference Paper
Proposes the application of the mutation analysis criterion in the context of specifications based on finite state machines. The main concepts of finite state machines and mutation analysis are briefly introduced. An experiment is reported which manually applies mutation analysis to a finite state machine modeling a Class 0 ISO transport protocol specification, using two test-sequence generator criteria-the W method and the TT (transition tours) method. The results obtained are presented, and evidences are given that the use of mutation analysis is effective in this context. Finally, the lines of evolution of the work presented in this paper are briefly discussed