Getting started with Expect

Setup

Obvisously, you need to setup the tools. Expect is built for tight integration with Visual Studio 2008 and 2010. Download the installer and run it. You should have everything needed thereafter.

Introduction

With Expect, you write a specification with your natural language in plain text. Expect will parse your specifications and wrap them in unit tests. To run the specifications you will have to provide fixtures. Fixtures are bridges between the text specifications and your system. Fixtures can be methods or classes.

With expect, you write your test as a text specification. The goal is to have text with as few decoration as possible. With Expect, the only thing you really have to remember is that text is hashed with pipe characters : "|", and fixtures are blocks of text, separated by blank lines.

Your first expectations

Expect specifications run through your favorite unit test framework. For now, Expect support MsTest (the default) and NUnit. This getting started will assume you use MsTest. Please have a look at How do I use NUnit framework instead of MsTest ? page if you use NUnit.

In Visual Studio, create a unit test project. Once you have your project, right click on it and choose "Add New Item". Select "Expect Item" and name your specification file, for example "Dummy specification.expect".

Let's write our first specification.

In your ".expect" file write the following :
My grand-mother loves |apple pie| and |vanilla ice-cream|


When you save the file, the custom tool generate an attached ".expect.cs" file. If you open this file, you will see that the framework generate a test class containing a test method with your text hashed by pipes. Expect also generate another ".cs" file called the "container". You could use this container for writing fixtures.

Open Visual Studio Test View (On the Test Menu select Windows/Test View). You should see your test there.
If you run the test, you should get an "inconclusive" result because Expect doesn't know how to resolve your specification. The test result contains informations about what the framework tries to resolve the specification.

Expect is looking for classes or methods that match what you typed. One common way is to use methods. In this case, Expect consider that one token is a description, and the following is a parameter, and so on so forth. Let's see an example...

Open the generated ".cs" file (not the ".expect.cs" one). This file will not be generated again

Add the following to the class
public void MyGrandMotherLovesAnd(string loved1, string loved2)
{
    Assert.Fail("My grand mother doesn't love " + loved1 + " or " + loved2);
}


If you run the unit test again, the test will obviously fail. The result contains details about your error, as usual.

Expect also provide helpers to generate the fixture code. Delete the method "MyGrandMotherLovesAnd" and save the class. Go back to the ".expect" file, right click on the sentence. You should have a menu called "Expect". Click on "Container -> create method". It will generate the same method in the container.

One step further

Let's see something more complicated now.

Replace the content of your expect file with this
My grand-mother loves | a lot of things |
| name       | love level |
| apple pie  | very much  |
| ice-cream  | much       |

#this is a text description that is not considered as executable
But she don't love |spiders|


The line starting by "#" is a description line. The content of lines starting with "#" is not executable.

Right click on the first fixture and select "Fixture -> Create fixture class". Expect generate a class named after the first cell of the first row. The other cells in the first row are considered as parameters for the constructor. In a fixture, you could also override a method called EndRun. This method is called after the last line of the fixture is processed.
With fixture classes, you could define specific format. Expect provide natively some formats.

Delete your fixture class. Right click on the first fixture and select "Fixture -> Create column fixture class". Column fixture is a kind of fixture class provided by the framework. It assume that, except for the first row, all rows has the same number of cells. In other words, it assumes that your fixture is a table of data. If you have a look at the fixture class, you see that you have a property for each column on the table. If a column name end with a "?", Expect will generate a method instead of a property. In this case, the result of the method is compared to what you write on the specification (just like a Assert.AreEquals).

Delete your fixture class again. Right click on the first fixture and select "Container -> Create method with fixture data". This time you have a method generated in the container with an extra parameter called FixtureData. The fixture data contains a list of rows, rows represented as dictionnaries.

As you can see, there are many ways to resolve your spec.

One last concept

So far, we have seen the concept of specifications, fixtures, and container. It's flexible but what if you have to share a few things between specifications ?
In fact you could have "blocs" within an expect file. The main blocs are setup, specification, and teardown. You could have only one setup or teardown bloc in your expect file, but you could have multiple specifications. The setup and teardown blocs are runned for each specification in the file. In fact, Setup and Teardown are wrapped in setup and teardown methods of your unit test framework.
The blocs are declared with "@", and you must provide a name for each bloc.

let's see an example
@setup I will make my init here
I write a content |here| like any expect content

@specification just a first sample
I'm still writing some |content| for the guide

#some free non-executable text
another line to show up

@specification a second one, just for fun
expect rocks !!! isn't it ?



TO BE CONTINUED...

Last edited Aug 6, 2010 at 8:32 PM by gleborgne, version 17

Comments

No comments yet.