I know this is against TDD and I am not going to discuss this :)
MSR just released a new product call Pex, you can also find a video on PDC at http://channel9.msdn.com/pdc2008/TL51/.
Today , I am going to use Pex to write unit tests for my two ugly code.
First, My original code is like
1: public bool RunDemo(string message, int value, DateTime actionTime)
2: {
3:
4: int length = message.Length;
5:
6: if (value > length)
7: {
8: value = 50;
9: }
10: if (value < 100)
11: {
12: for (int i = 0; i < value; i++)
13: {
14: if (actionTime < DateTime.Now)
15: {
16: Console.Write(message);
17: Console.WriteLine();
18: if (value > 100)
19: {
20: Console.WriteLine("To see what will happen");
21: }
22: }
23: }
24: }
25: return true;
26: }
It's basically the ugliest code I had ever written. But how the unit test will go?
The test result will be like
After we take a deeper look, we will find out that the failed unit test case is
1: [TestMethod]
2: [PexRaisedException(typeof(NullReferenceException))]
3: [PexGeneratedBy(typeof(Class1Test))]
4: public void RunDemo03()
5: {
6: bool b;
7: Class1 class1 = new Class1();
8: b = this.RunDemo(class1, (string)null, 2, default(DateTime));
9: }
So we know in out RunDemo code, we need to have a argument safety check first., So I neet to write the code like
1: // <pex>
2: if (string.IsNullOrEmpty(message))
3: return false;
4: // </pex>
The second example is we are trying to write a Fibonacci code like this
1: public int Fibonacci(int n)
2: {
3: return Fibonacci(n - 1) + Fibonacci(n - 2);
4: }
The logic is so simple and we think we are done, but Pex dose not think so.
And we need to fix the code as
1: public int Fibonacci(int n)
2: {
3: if (n==1 || n==0)
4: {
5: return n;
6: }
7: return Fibonacci(n - 1) + Fibonacci(n - 2);
8: }
In this two stupid simple code, we will have a quick snapshot for the Pex tools.
- Also, the Pex has some limitation and we need to know that Pex is code, not a real developer.
Pex assumes that the analyzed program is deterministic. If it is not, Pex will go in cycles until it hits exploration bounds.
- Pex does not handle multithreaded programs.
- Pex does not understand native code, e.g. x86 instructions called through P/Invoke,
- At this time, we only support Pex on the X86, 32-bit .NET framework.
- In principle, Pex can analyze arbitrary .NET programs, written in any .NET language.
However, the VS AddIn and the code generation are only fully implemented for C#.
- Pex injects generic callbacks when rewriting the IL method bodies. This has a side effect that it cannot instrument v1.0 and v1.1 .net module because their metadata models do not support generics.
There is one thing I don't like for the Pex is that Pex code generation will only generate the MsTest project, I hope it can generate a NUnit or MBUnite project in future. (Removed after I read the resource on htp://www.codeplex.com/Pex)
In the coming days, I will introduce the coverage test done by the Pex.