Commit 1a22e557 authored by Ludwig Dickmanns's avatar Ludwig Dickmanns
Browse files

MCDC: Cleanup, Documentation, Ratings

* McdcTestSuiteGenerator: Cleanup, Documentation.
* TestGenerate: Removed unnecessary try/catch.
* testing.ecore: Documented the model.
* TestingModelElementFactory: Documentation.

Issue-Ref: 3476
Issue-Url: https://af3-developer.fortiss.org/issues/3476

Signed-off-by: Ludwig Dickmanns's avatarLudwig Dickmanns <dickmanns@fortiss.org>
parent f8f273f0
random-specification-model.ecore b04f23eef5a265ffed25435e135c0ebd85ef2ac1 GREEN
testing.ecore f3a265b2a8807a7405dd75e718f978c8d59bf951 GREEN
testing.ecore 0d0eb16a34697685d0bd1ac28ed6d589c223f38e YELLOW
......@@ -415,10 +415,21 @@
</eStructuralFeatures>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="McdcTestStep" eSuperTypes="#//TestStep">
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
<details key="documentation" value="Each mcdc test step contains a {@link BoolConst} representing the taken branch (evaluation of the guard) &#xA;and a list of {@link FunctionCall}s (the atoms of the guard), which evaluated to true for this test step.&#xA;For additional information about test steps, see {@link TestStep}."/>
</eAnnotations>
<eStructuralFeatures xsi:type="ecore:EReference" name="trueAtoms" upperBound="-1"
eType="ecore:EClass platform:/resource/org.fortiss.af3.expression/model/expression.ecore#//terms/FunctionCall"/>
eType="ecore:EClass platform:/resource/org.fortiss.af3.expression/model/expression.ecore#//terms/FunctionCall">
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
<details key="documentation" value=" The {@link FunctionCall}s (the atoms of the guard), which evaluated to true for this test step."/>
</eAnnotations>
</eStructuralFeatures>
<eStructuralFeatures xsi:type="ecore:EReference" name="takenBranch" lowerBound="1"
eType="ecore:EClass platform:/resource/org.fortiss.af3.expression/model/expression.ecore#//terms/BoolConst"/>
eType="ecore:EClass platform:/resource/org.fortiss.af3.expression/model/expression.ecore#//terms/BoolConst">
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
<details key="documentation" value="TODO: write documentation (in the model!)"/>
</eAnnotations>
</eStructuralFeatures>
</eClassifiers>
</eSubpackages>
</ecore:EPackage>
MCDCUtils.java 9ddc7e1cb100e88955a6cba7a84c5512c998271a RED
McdcUtils.java 9a94361d7930447363ae633b39c91769d1c1543b YELLOW
McdcTestSuiteGenerator.java 4281291934647d2c2c672db5008af8193d5edf0f RED
McdcTestSuiteGenerator.java 2bd1aad69027fd4fa81c60cce8ebe0415294de2e YELLOW
......@@ -50,7 +50,6 @@ import org.fortiss.af3.project.model.typesystem.IFunction;
import org.fortiss.af3.project.model.typesystem.ITerm;
import org.fortiss.af3.project.model.typesystem.IType;
import org.fortiss.af3.testing.extension.ITestSuiteGenerator;
import org.fortiss.af3.testing.extension.data.TestSuiteGenerationException;
import org.fortiss.af3.testing.model.TestCase;
import org.fortiss.af3.testing.model.TestInput;
import org.fortiss.af3.testing.model.TestOutput;
......@@ -70,30 +69,38 @@ import com.microsoft.z3.Optimize;
import com.microsoft.z3.Status;
/**
* Inputs and outputs of the test case are stored in step one.
* Step two contains the evaluated atoms in TestInputs and the taken branch in TestOutputs.
* *
* Implementation of {@link ITestSuiteGenerator} interface for MCDC test case generator.
*
* @author ludwig dickmanns
*/
public class McdcTestSuiteGenerator implements ITestSuiteGenerator {
/** The {@link TestSuite} in which the generated test cases are stored. */
private TestSuite testSuite;
/** The {@link FormalRequirementMcdc} for the generation of the test cases. */
private FormalRequirementMcdc req;
/** The {@link Component} containing the {@link FormalRequirementMcdc}. */
private Component component;
/** The atoms of the {@link FormalRequirementMcdc#getGuard()}. */
private List<FunctionCall> atoms;
/** The atoms for which MCDC is verified. */
private List<FunctionCall> verifiedAtoms = new ArrayList<FunctionCall>();
/** The independence pairs verifying the atoms. */
private List<Pair<TestCase, TestCase>> independencePairs =
new ArrayList<Pair<TestCase, TestCase>>();
// Atoms verified previous to adding the new test case
/** The atoms verified previous to adding the new test case. */
private int verifiedAtomsBefore;
/** Initially false, true if an advantageous test case was generated. */
private boolean advantageousTCgenerated = false;
/**
* Constructor.
*
* @param initialSuite
*/
/** Constructor. */
public McdcTestSuiteGenerator(TestSuite initialSuite) {
this.testSuite = initialSuite;
this.verifiedAtomsBefore = 0;
......@@ -101,54 +108,49 @@ public class McdcTestSuiteGenerator implements ITestSuiteGenerator {
/** {@inheritDoc} */
@Override
public TestSuite generate(TestSuiteSpecification specification, IProgressMonitor monitor)
throws TestSuiteGenerationException, InterruptedException {
public TestSuite generate(TestSuiteSpecification specification, IProgressMonitor monitor) {
McdcSpecificationPart spec =
pickFirstInstanceOf(McdcSpecificationPart.class, specification.getSpecifications());
this.req = spec.getFormalRequirementMcdc();
this.component = specification.getComponent();
this.testSuite.getInputPorts().addAll(component.getInputPorts());
this.testSuite.getOutputPorts().addAll(component.getOutputPorts());
this.atoms = getAtomsFromGuardMCDC(req.getGuard());
req = spec.getFormalRequirementMcdc();
component = specification.getComponent();
testSuite.getInputPorts().addAll(component.getInputPorts());
testSuite.getOutputPorts().addAll(component.getOutputPorts());
atoms = getAtomsFromGuardMCDC(req.getGuard());
if(this.testSuite.getTestCases().size() > 1) {
if(testSuite.getTestCases().size() > 1) {
checkTestSuite();
}
if(this.testSuite.getTestCases().size() == 0) {
if(testSuite.getTestCases().size() == 0) {
generateAdvantageousTestCase();
}
this.verificationStep();
return this.testSuite;
return testSuite;
}
// Unique cause
private void verificationStep() {
// All atoms are verified
if(atoms.size() == verifiedAtoms.size()) {
System.out.println("Verified!");
return;
}
Context ctx = new Context();
// New test case
Context ctx = new Context();
TestCase newTC = createTestCase(testSuite);
// Unique (?) name
newTC.setName(Integer.toString(newTC.hashCode()));
// Add new test case constraints from the requirement to ctx
Expr reqZ3 = toZ3(newTC.getName(), ctx, req, component);
BoolExpr orClause = ctx.mkFalse();
// Iterate over all of the existing test cases
for(TestCase testCase : testSuite.getTestCases()) {
// createTestCase adds the new test case to the suite
if(testCase.getName() == newTC.getName()) {
continue;
}
// All possibilities for cc for this test case and the new one
// Or clause for the constraints for condition coverage
BoolExpr cc = ctx.mkFalse();
McdcTestStep mcdcTestStep = (McdcTestStep)testCase.getTestSteps().get(0);
BoolConst oldTakenBranchAf3Expr = mcdcTestStep.getTakenBranch();
......@@ -160,6 +162,7 @@ public class McdcTestSuiteGenerator implements ITestSuiteGenerator {
// Only one of the atoms should be different
for(int i = 0; i < atoms.size(); i++) {
// Contains the constraints for the atoms
BoolExpr andClause = ctx.mkTrue();
FunctionCall atom = atoms.get(i);
if(verifiedAtoms.contains(atom)) {
......@@ -214,11 +217,7 @@ public class McdcTestSuiteGenerator implements ITestSuiteGenerator {
verificationStep();
}
/**
* @param ctx
* @param newTestCase
* @param opt
*/
/** Retrieves the values of the z3 solver. */
private void retrieveValues(Context ctx, TestCase newTestCase, Optimize opt) {
Model model = opt.getModel();
......@@ -321,16 +320,16 @@ public class McdcTestSuiteGenerator implements ITestSuiteGenerator {
}
}
/** Generates an advantageous {@link TestCase}. */
private void generateAdvantageousTestCase() {
Context ctx = new Context();
// New test case
TestCase newTC = createTestCase(testSuite);
// Unique (?) name
newTC.setName(Integer.toString(newTC.hashCode()));
// Add new test case constraints from the requirement to ctx
Expr reqZ3 = toZ3(newTC.getName(), ctx, req, component);
IExpressionTerm guard = req.getGuard();
BoolExpr intelligentAssignment = recursiveAssignment(newTC, guard, ctx, true);
BoolExpr advantageousAssignment = recursiveAssignment(newTC, guard, ctx, true);
// Naming of atoms for retrieval
BoolExpr atomsClause = ctx.mkTrue();
......@@ -342,7 +341,7 @@ public class McdcTestSuiteGenerator implements ITestSuiteGenerator {
}
Optimize opt = ctx.mkOptimize();
opt.Add(intelligentAssignment, atomsClause, (BoolExpr)reqZ3);
opt.Add(advantageousAssignment, atomsClause, (BoolExpr)reqZ3);
if(opt.Check() == SATISFIABLE) {
retrieveValues(ctx, newTC, opt);
......@@ -350,10 +349,20 @@ public class McdcTestSuiteGenerator implements ITestSuiteGenerator {
}
/**
* - true and: all terms true
* - true or : all but one term false
* - false and: all but one term true
* - false or : all terms false
* @param testCase
* - the test case which is generated
* @param term
* - the term to be assigned
* @param ctx
* - the z3 Context
* @param shouldEvaluateTo
* - to which boolean value the term should evaluate
* - true and: all terms true
* - true or : all but one term false
* - false and: all but one term true
* - false or : all terms false
* @return
* - a {@link BoolExpr} containing the constraints for an advantageous test case
*/
private BoolExpr recursiveAssignment(TestCase testCase, ITerm term, Context ctx,
boolean shouldEvaluateTo) {
......@@ -409,6 +418,7 @@ public class McdcTestSuiteGenerator implements ITestSuiteGenerator {
return null;
}
/** Checks the test suite for condition coverage. */
private void checkTestSuite() {
EList<TestCase> testCases = testSuite.getTestCases();
for(int i = 0; i < testCases.size() - 1; i++) {
......@@ -459,12 +469,12 @@ public class McdcTestSuiteGenerator implements ITestSuiteGenerator {
}
}
/** Returns atoms. */
/** Returns the atoms. */
public List<FunctionCall> getAtoms() {
return atoms;
}
/** Returns independencePairs. */
/** Returns the independencePairs. */
public List<Pair<TestCase, TestCase>> getIndependencePairs() {
return independencePairs;
}
......
GenerateStateAutomatonUtils.java 81645f6c18da5bcc920f8671da4eeb622f8f69d4 GREEN
StatisticUtils.java d2ea1b26fc14f0b19d18604d330205b8aae3352e GREEN
TestingConstraintUtils.java 7c423db9009862b16a96c05ab7ef9a59d4af6c81 GREEN
TestingModelElementFactory.java 66acd55aeafd698b525dfaae2e343b62584f11fc GREEN
TestingUtils.java e9fa206a3ab1f59b56b242097d4a8cc19935f9d7 GREEN
TestingModelElementFactory.java 80156306f4616c8b5fcf993f9dca3e32153ce392 YELLOW
TestingUtils.java 432c6f56bf94e255e6c065a0d1c0d6c7c1641517 YELLOW
......@@ -357,6 +357,7 @@ public class TestingModelElementFactory {
return null;
}
/** Creates a {@link FormalRequirementMcdc}. */
public static FormalRequirementMcdc createFormalRequirementMcdc(CodeSpecification codeSpec) {
StatementSequence statementSequence = codeSpec.getBody();
if(statementSequence == null || statementSequence.getStatements() == null ||
......
......@@ -56,7 +56,6 @@ import org.fortiss.af3.expression.model.terms.imperative.Assignment;
import org.fortiss.af3.expression.model.terms.imperative.StatementSequence;
import org.fortiss.af3.project.model.typesystem.ITerm;
import org.fortiss.af3.project.model.typesystem.IType;
import org.fortiss.af3.testing.extension.data.TestSuiteGenerationException;
import org.fortiss.af3.testing.mcdc.generator.McdcTestSuiteGenerator;
import org.fortiss.af3.testing.model.TestCase;
import org.fortiss.af3.testing.model.TestInput;
......@@ -156,11 +155,7 @@ public class TestGenerate {
// createTestOutput(testStep2, null, boolConst(true));
McdcTestSuiteGenerator generator = new McdcTestSuiteGenerator(testSuite);
try {
generator.generate(specification, null);
} catch(TestSuiteGenerationException | InterruptedException ex) {
ex.printStackTrace();
}
generator.generate(specification, null);
System.out.println(req);
System.out.println();
......@@ -246,11 +241,7 @@ public class TestGenerate {
mcdcTestStep.setTakenBranch(boolConst(true));
McdcTestSuiteGenerator generator = new McdcTestSuiteGenerator(testSuite);
try {
generator.generate(specification, null);
} catch(TestSuiteGenerationException | InterruptedException ex) {
ex.printStackTrace();
}
generator.generate(specification, null);
System.out.println(req);
System.out.println();
......@@ -346,11 +337,7 @@ public class TestGenerate {
mcdcTestStep.setTakenBranch(boolConst(false));
McdcTestSuiteGenerator generator = new McdcTestSuiteGenerator(testSuite);
try {
generator.generate(specification, null);
} catch(TestSuiteGenerationException | InterruptedException ex) {
ex.printStackTrace();
}
generator.generate(specification, null);
System.out.println(req);
System.out.println();
......@@ -428,11 +415,7 @@ public class TestGenerate {
TestSuite testSuite = createTestSuite("McdcSpecification", specification);
McdcTestSuiteGenerator generator = new McdcTestSuiteGenerator(testSuite);
try {
generator.generate(specification, null);
} catch(TestSuiteGenerationException | InterruptedException e1) {
e1.printStackTrace();
}
generator.generate(specification, null);
printResults(testSuite, generator);
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment