I read many papers about pex , I'm focus on the explorations strategies . I understand that the Fitnex strategy is default used but I don't understand how Pex create the first parametrized unit test .
Where I can find this information ?
By sperimental tests I think : - If parameter is "int" start with 0 - If parameter is "bool" start with false - If parameter is an object start with Null
Is it correct ?
Now about Fitnex strategy and solver constraints Z3 I think that it is able to solve only one constrain by iteration , sorry for my little English now I do an example :
Suppose to have the following method :
public void branchOverTests(bool a, bool b)
{
1 if (a)
{
2 Console.WriteLine("B1");
}
else
{
3 Console.WriteLine("B2");
}
4 if (b)
{
5 Console.WriteLine("B3");
}
else
{
6 Console.WriteLine("B4");
}
}
Numbers are lines identify, Pex generate 3 tests :
--- Test 1
branchOverTests(a=false,b=false)
Path: 1F 3T 4F 6T
return target != (ClassMethod)null;
return target != (ClassMethod)null && a == false;
return target != (ClassMethod)null && a == false;
return target != (ClassMethod)null && a == false && b == false;
--- Test 2
branchOverTests(a=false,b=true)
Path: 1F 3T 4T 5T
return target != (ClassMethod)null;
return target != (ClassMethod)null && a == false;
return target != (ClassMethod)null && a == false;
return target != (ClassMethod)null && b != false && a == false;
Note: From Test 1 Flipped last branch:
return target != (ClassMethod)null && a == false && b == false;
-> return target != (ClassMethod)null && b != false && a == false;
=> b = true
--- Test 3
branchOverTests(a=true,b=false)
Path: 1T 2T 4F 6T
return target != (ClassMethod)null;
return target != (ClassMethod)null && a != false;
return target != (ClassMethod)null && a != false;
return target != (ClassMethod)null && a != false && b == false;
Note: From Test 2 Resolve second condition of last branch:
return return target != (ClassMethod)null && b != false && a == false;
-> return target != (ClassMethod)null && a != false && b == false;
=> a = true
=> return target != (ClassMethod)null && a != false;
=> return target != (ClassMethod)null && a != false;
But the most efficient set of parametrized tests is :
branchOverTests(a=false,b=false)
branchOverTests(a=true,b=true)
After Test 1 :
return target != (ClassMethod)null && a == false;
-> return target != (ClassMethod)null && a != false;
=> a = true
=> return target != (ClassMethod)null && a != false && b != false;
=> b = true
Ideal Test 2 :
branchOverTests(a=true,b=true)
Path: 1T 2T 4T 5T
return target != (ClassMethod)null;
return target != (ClassMethod)null && a != false;
return target != (ClassMethod)null && a != false;
return target != (ClassMethod)null && a != false && b != false;
Is That I think correct ?
Thanks best regards.