# Wednesday, September 17, 2008

In the previous post, we implemented the insertion method of a binary heap using Test Driven Development (TDD) and parameterized unit tests (I'll leave the full implementation of the insertion method as an exercise).

In this post, we will take a closer look at the development flow that we used and show how it relates to traditional TDD. For many people, combining TDD and automated test generation makes no sense. I believe this is not true anymore, and this is what this post is about.

Test Driven Development Flow

TDD has a well-defined flow where developers

  1. write a unit test,
  2. run the test and watch it fail,
  3. fix the code,
  4. run the test and watch the test pass. Start again (I'll skip refactoring in this discussion)

During this flow, practitioners also refer to the green state when all tests are passing and red state when some tests are failing. The little picture below depicts this little state machine.

tddstates

A key aspect of this approach is that the design of the API is inferred by writing the 'scenarios', i.e. tests. Therefore, unit tests are a critical building block of the TDD flow.

Note also that xUnit-like test frameworks (pick your favorite framework here) provide the automation tools so that the execution of the test and the investigation of a failure is painless for the programmer.

Test Driven Development Flow With Parameterized Unit Tests

Parameterized unit tests and Pex change the TDD flow while retaining its essence: building the design from tests. Here are the steps, we'll discuss them in detail later on:

  1. Write a parameterized unit test,
  2. Run Pex and watch some generated unit tests fail,
  3. Fix the code,
  4. Run Pex again,
    1. Some previously generated unit tests now pass, at least one new failing unit test get generated (go to 3)
    2. All generated tests are passing, start again (go to 1)

The key difference is the shortcut from step 4 (generating unit tests) to 3 (fix the code), without passing through step 1 (write a new test). This is illustrated by the yellow feedback loop in the diagram below:

 etddcycle

To the risk of repeating myself, let me emphasize some important points here:

  • you still need to write unit tests, it's just that they can have parameters: Pex generates unit tests from parameterized unit tests, by instantiating them. The person who writes the parameterized unit test is you, not the tool!
  • it is still about design: using parameterized unit tests is as much about design as closed (i.e. parameterless) unit tests. In fact, one can argue that parameterized unit tests are way closer to a specification that closed unit tests.
  • it is test first: in case it was not obvious by now :)

The shortcut from 4 to 3

As mentioned above, the main difference in the flow is that jump from running the tool (step 4) to fixing the code (step 3), without writing new tests (step 1). This happens because a parameterized unit tests captures equivalence classes rather than a single scenario like closed unit tests. As a result,

  • you spend more time fixing/implementing the code: the nice thing about the shortcut is that you can spend more time writing the code, rather than writing tests.
  • you can leverage automated white-box testing tools: Pex tries to get the maximum coverage out of your parameterized unit test (note remember that getting coverage also means covering the throwing branches in Assert), using an automated white-box code analysis. Now that you have also those manycore CPUs on your motherboard, you can finally make a good use of them :)

To Pex and not to Pex

An important aspect of parameterized unit tests (and tools like Pex) is that you do not have to drop (completely) your existing habits: in many cases, it is easier to write closed unit tests! In fact, you can always start from a closed unit test and refactor it later. We do not expect users to parameterized unit tests write exclusively (another nice read here), but when you do write them, we expect you'll get much more 'out of your buck'.

In future posts, we'll discuss different ways to write parameterized unit tests: from refactoring existing unit tests to using test patterns.

To be continued...

Next time, we'll go back to the heap and look at implementing the 'remove minimum' method...

(Pex is a automated structural testing tool from Microsoft Research. More information at http://research.microsoft.com/pex.)

Thursday, September 18, 2008 7:34:02 AM (Pacific Daylight Time, UTC-07:00)
Hi Jonathan,

Thanks for this explanation.

I would love to pick up Pex at our company! I think it would save us from having to write a so many specialized unit tests; replacing them with parameterized tests.

I have some concerns that prevent us from using Pex. Perhaps you could comment on them?

-We're using Visual Studio 2005 still. Pex doesn't work with VS2005, right?
-We use the Pro editions of Visual Studio, not the super-hyped up crazy everything edition. Will Pex still work with the Pro edition of VS?
-We use TestDriven.NET to run our unit tests. Will Pex work with TDD.NET?
-We utilize CruiseControl.NET as our continuous integration server, which runs our unit tests using NUnit test runner. Will this break?

As you can see, we have some reservations about using Pex, even though we clearly see the benefits of parameterized unit tests.

Any thoughts?
Thursday, September 18, 2008 8:51:42 AM (Pacific Daylight Time, UTC-07:00)
Hi Judah, good questions. I will answer the ones I have a clear answer for:

-We're using Visual Studio 2005 still. Pex doesn't work with VS2005, right?

The Pex Visual Studio integration does not work VS2005, that is correct. *However*, the Pex exploration engine (i.e. the command line tool) works for the CLR 2.0 and does not have any dependency on Visual Studio.

-We use the Pro editions of Visual Studio, not the super-hyped up crazy everything edition. Will Pex still work with the Pro edition of VS?

I'm afraid I can't answer this, I'm not making this kind of decision :)

-We use TestDriven.NET to run our unit tests. Will Pex work with TDD.NET?

Pex comes with it's own specialized runner to generate *closed* unit tests. Once the closed unit tests have been generated, they can be run by TD.NET (or Resharper, or MSTest) or any tool that supports running unit tests in Visual Studio.

-We utilize CruiseControl.NET as our continuous integration server, which runs our unit tests using NUnit test runner. Will this break?

We are currently looking at possible ways to integrate Pex in a CI environment. The most obvious solution (for now) is that you generate the closed unit tests on your machine and store them in the source control. At this point, those closed unit tests are simple regular unit and will naturally integration in any existing build process.

Another (nicer) solution would be to run Pex on the build machine, we have not a definitive solution there yet.

The key takeaway here is that the 'final product' of Pex are traditional closed unit tests that are 'understood' by your favorite test framework.
Thursday, September 18, 2008 1:27:20 PM (Pacific Daylight Time, UTC-07:00)
Thanks Jonathan.

I realize that I can use Pex command line. It's funny, even though I use many command line tools throughout the development day, I'm hesitant to use Pex command line. My brain is picturing some luddite with notepad and csc.exe.

How is the experience with Pex command line compared to VS? Is it a pain in the ass compared to VS integration?

Regarding TD.NET, that's interesting. How does that work; the closed tests generated by Pex can use NUnit as the test framework?

For the CI, it's acceptable for us to generate the closed tests on our machines. We'd just have to add the generated files to source control. A bit of a pain, but nothing terrible. It would be brilliant if the CI server ran the closed test generation.
Thursday, September 18, 2008 3:05:36 PM (Pacific Daylight Time, UTC-07:00)
> How is the experience with Pex command line compared to VS? Is it a pain in the ass compared to VS integration?

Of course, it's not as nice and easy as the Visual Studio integration. However, we (the Pex team) use the command line extensively. The command line generates an HTML report that is very detailled and that even contains more features than in VS. In particular, the parameter table is there, there is also code coverage. The command line also default generates a new test project with the generated unit tests.

What you don't get is the test recycling and dynamic insertion that happens in the background, plus being able to right click on any test and run it.

> Regarding TD.NET, that's interesting. How does that work; the closed tests generated by Pex can use NUnit as the test framework?

Pex generates closed unit tests as *source code* for your favorite test framework: MSTest is supported out of the box, but you can download other extensions at http://www.codeplex.com/pex. For each framework, Pex knows which attributes to put etc...

Once the closed unit tests are generated, they will be picked up by your test framework as just another unit test.

> It would be brilliant if the CI server ran the closed test generation.

We are thinking about nice ways to do this. Pex comes with a command line that has a lot of options so you can have the CI execute it during a build. Pex also generate an XML report document that contains the entire 'history' of the run. With those 2 ingredients, it should be possible to create a plugin for your favorite CI tool that (1) executes Pex, (2) groks the xml report, (3) displays the new failure etc...
Friday, October 03, 2008 7:14:06 AM (Pacific Daylight Time, UTC-07:00)
Hi Peli. This is an interesting article -- but I'd like to know what tool you used to draw these images. They look great.

Thanks in advance.
Alex Ellis
Tuesday, October 21, 2008 6:33:04 AM (Pacific Daylight Time, UTC-07:00)
Just that good old PowerPoint 2007 :)
Comments are closed.