Question

Say I have MyClass with 100s of fields.

If I use an object of MyClass as an input param, Pex would simply choke trying to generate all possible combinations (mine runs into 1000s of paths even on a simple test)

[PexMethod] void MytestMethod(MyClass param){...}

How can I tell Pex to use only a set of predefined objects of MyClass rather than having it trying to be smart and generate all possible combinations to test?

In other words I want to manually specify a list of possible states for param in the code above and tell Pex to use it

Cheers

Was it helpful?

Solution

If you find that Pex is generating large amounts of irrelevant, redundant, or otherwise unhelpful inputs, you can shape the values that it generates for your parametrized unit tests' input using PexAssume, which will ensure that all generated inputs meet a set of criteria that you provide.

If you were wanting to ensure that arguments came from a predefined collection of values, for instance, you could do something like this:

public void TestSomething(Object a) {
    PexAssume.IsTrue(someCollection.Contains(a));
}

PexAssume has other helper methods as well for more general input pruning, such as IsNotNull, AreNotEqual, etc. What little documentation is out there suggests that there is some collection-specific functionality as well, though if those methods exist, I'm not familiar with them.

Check out the Pex manual for a bit more information.

OTHER TIPS

Pex will not try to generate every possible combination of values. Instead, it analyses your code and tries to cover every branch. So if you have

if (MyObject.Property1 == "something")
{
    ...
}

then it will try to create an object that has Property1 == "something". So limiting the tests to some predefined objects is rather against the 'Pex philosophy'. That said, you may find the following information interesting.

You can provide a Pex factory class. See, for instance, this blog post or this one.

[PexFactoryClass]  
public partial class EmployeeFactory  
{  
  [PexFactoryMethod(typeof(Employee))]  
  public static Employee Create(  
  int i0,  
  string s0,  
  string s1,  
  DateTime dt0,  
  DateTime dt1,  
  uint ui0,  
  Contract c0  
  )  
{  

  Employee e0 = new Employee();  
  e0.EmployeeID = i0;  
  e0.FirstName = s0;  
  e0.LastName = s1;  
  e0.BirthDate = dt0;  
  e0.StartDateContract = dt1;  
  e0.Salary = ui0;  
  e0.TypeContract = c0;  
  return e0;  
}   

}

Pex will then call this factory class (instead of a default factory) using appropriate values it discovers from exploring your code. The factory method allows you to limit the possible parameters and values.

You can also use PexArguments attribute to suggest values, but this will not prevent Pex from trying to generate other values to cover any branches in your code. It just tries the ones you provide first.

[PexArguments(1, "foo")] // try this first
void MyTest(int i, string s) 
{
    ...
}

See here for more information on PexArguments and also search for 'seed values' in the PDF documentation on Parameterized Test Patterns.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top