0

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.

4

1 回答 1

2

Pex 总是以默认值开始,就像你描述的那样。这是第一个测试用例。然后 Pex 探索执行路径的所有可能组合。(Fitnex 策略指导 Pex,但这对您的问题并不重要。)默认情况下,每当 Pex 发现增加分支覆盖率的新测试用例时,它都会发出另一个测试用例。Pex 以这种方式渴望,并且不能保证生成的测试套件是最小的,正如您发现的那样。但通常它非常接近。(在内部,Pex 最后还考虑了 (true,true),但没有创建另一个测试用例,因为它不会增加分支覆盖率。)

于 2012-11-05T07:36:34.693 回答