dspot
dspot copied to clipboard
Add support for assertNotNull
Characteristics
- Reporter: [Assad Montasser, [email protected]]
Description
This is not a bug but an improvement suggestion made by Daniel Le Berre after reviewing the generated code.
https://github.com/STAMP-project/dspot-usecases-output/blob/master/OW2/Sat4j/20181030-1515/dspot-out/org/sat4j/AmplBugSAT107.java
After line 50 ( IConstr o_testNoSolutionExists__5 = solver.addClause(clause);), we can add an assertNotNull test on o_testNoSolutionExists__5 before testing the next Assert.
For instance, thanks to Descartes, we detected that in the BugSAT34 original test, there was not a test on null, and that leaded to correct the test: https://gitlab.ow2.org/sat4j/sat4j/commit/309b935d53606fcba2f4e009da82590c993a857d
What we did manually could be done automatically and kill extreme mutants generated by Descartes.
Steps to reproduce
Properties file
project=.
src=src/main/java/
testSrc=src/test/java/
Command Line / Options
java -jar target/dspot-USED-VERSION-jar-with-dependencies.jar \
-p myPropertiesFile.properties
Other files and URLs
Relationships
Help on issue template
Preview to follow the link or open file .github/ISSUE_DOC.md
Hello @assadOW2
I agree that It would be great to add this kind of assertion.
However, in DSpot, the assertions' generation is based on a java convention:
We consider that observations points are getters on existing objects inside the test. In DSpot, we defined a getter as follow:
- It is a public method
- It does not take any parameter
- It has a return type (non-void)
- It has a name that complies with a java name convention for getter, i.e. starts with
get
,is
,should
,has
.
Why we do that ? Because from our point of view, getters are pures, and thus, we can rely on them to create stable assertions. During the assertions' generation, DSpot can execute multiple times the same method to collect the values, and thus if this method is not pure, DSpot is wasting its time (and we all know that DSpot is taking already to much time) because It won't be able to generate an assertion (considering the value as not deterministic).
I see two way to improve this:
- Instead of generating a observations point on objects, one can imagine that we observe method. In our explain we would end up with
Observation.log(this.system.addClause(new VecInt(new int[] { 1, 2, -3 }));)
instead of
Observation.log(this.system)
- We compute, a priori, the purity of methods and we expand the scope to all of them instead of relying on the convetion explained above.
This is a crucial point for DSpot, thank you very much !
Hi @danglotb
My point was really the following.
The current code generated by DSpot is:
IConstr o_testNoSolutionExists__5 = solver.addClause(clause);
Assert.assertFalse(((OriginalBinaryClause) (o_testNoSolutionExists__5)).isSatisfied());
Assert.assertEquals(0.0, ((double) (((OriginalBinaryClause) (o_testNoSolutionExists__5)).getActivity())), 0.1);
Adding a simple, induced assertion to the current assertions could produce some improvements in terms of mutation score.
IConstr o_testNoSolutionExists__5 = solver.addClause(clause);
Assert.assertNonNull(o_testNoSolutionExists__5); // NEW
Assert.assertFalse(((OriginalBinaryClause) (o_testNoSolutionExists__5)).isSatisfied());
Assert.assertEquals(0.0, ((double) (((OriginalBinaryClause) (o_testNoSolutionExists__5)).getActivity())), 0.1);
That way, you get a failed assertion instead of getting an NPE in the following assertion.
We can add the assertion before any block of instructions using a reference like in the example proposed by @danielleberre.
In the case we find patterns such as:
obj.getAReference().doSomething();
First transform the code:
<Type> obj_reference = obj.getAReference();
obj_reference.doSomething();
and finally:
<Type> obj_reference = obj.getAReference();
assertNonNull(obj_reference);
obj_reference.doSomething();
Hi @danielleberre, @oscarlvp
Okay I get it now.
As described by @oscarlvp, this task can be done easily. Just need to play a little bit with the Spoon's API.
I guess your changes will appear in the eu.stamp_project.dspot.assertgenerator
package and in particular in eu.stamp_project.dspot.assertgenerator.AssertBuilder#buildAssert method.
Yep, looks good to me.
For the record from the plenary meeting: Oscar works on it