Dans mes posts précédents j’ai commencé à parler des tests unitaires avec NBehave. Si vous êtes curieux vous pouvez y jeter un œil mais cela n’est pas nécessaire pour comprendre cet article. Quoique pour les exemples ça peut servir:

Cette fois ci, je vais reprendre l’exemple précédent et l’utiliser avec SpecFlow. SpecFlow permet d’écrire des scénarios dans les exigences BDD. Le langage utilisé est compatible avec Gherkin qui est un Business Redeable Domain Specific Language. Gherkin est compris par Cucumber qui est un autre outils pour le développement BDD. Ce qui est important ce que nous n’avons pas besoin d’avoir notre propre environnement d’exécution (comme la console NBehave dans l’exemple précédent) mais NUint s’en chargera pour nous.

Note: Avec SpecFlow on ne parle plus de Story mais de Feature (exigence Gherkin).

Passons donc à la pratique.

1. Téléchargez SpecFlow ici et installez-le.

2. Ajoutez une référence vers le TechTalk.SpecFlow.dll dans le projet qui contiendra vos Features (dans le projet de test en l’occurrence).

3. Ajoutez le fichier de feature écrite au format Gherkin. Ce qui est super ce qu’en installant SpecFlow vous disposer maintenant des templates dans Visual Studio pour créer votre feature.

SpecFlow_visualStudio_integration

Une feature avec des scénario par défaut est proposé. Nous allons le changer par le notre. Celui que nous avons utilisé avec NBehave (en renomme juste Story en Feature)

Feature: Handle user log in
    In order to check authentication
    As a user
    I want the system to check if user can log in

Scenario: User logs in

    Given I would like to log in
    When I log in as bdd with a password nbehave without remembering me
    Then I should be redirected to the home page


Scenario: User doesn't log in
    Given I would like to log in
    When I log in as BAD with a password BAD without remembering me
    Then The error message should be shown

 

Comme vous pouvez le constater SpecFlow génère lui même le code qui fait l’intégration de nos tests dans NUnit !

SpecFlow_VisualStudio_Integration2

4. Maintenant nous implémentons notre classe de test. Je l’ai appelé AccountControllerTests2 et par rapport à la classe que nous avons utilisé avec NBehave seulement les choses suivantes changent :

  • L’attribut ActionSteps a été remplacé par l’attribut Binding.
  • Les paramètres sont passés à l’aide de la chaîne "(.*)” et non le caractère $ comme dans l’exemple précédent.

Et (puis) c’est TOUT :)

Voici la classe complète :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
[Binding] 
public class AccountControllerTests2
{
private AccountController controller;
private IFormsAuthenticationService formsService;
private IMembershipService membershipService;
private ActionResult result;
private LogOnModel model;

private void SetUpController()
{
var controllerBuilder = new TestControllerBuilder();

formsService = MockRepository.GenerateStub<IFormsAuthenticationService>();
membershipService = MockRepository.GenerateStub<IMembershipService>();
model = MockRepository.GenerateStub<LogOnModel>();

controller = controllerBuilder.CreateController<AccountController>(new object[] {formsService, membershipService});
}

[Given(@"I would like to log in")]
public void AccesAccountController()
{
SetUpController();
controller.ShouldNotBeNull();
}

[When(@"I log in as (.*) with a password (.*) without remembering me")]
public void LogIn(string username, string password)
{
bool rememberMe = false;

membershipService.Stub(x => x.ValidateUser(username, password)).Return(true);
formsService.Stub(x => x.SignIn(username, rememberMe));

model.UserName = "bdd";
model.Password = "nbehave";

controller.ModelState.IsValid.ShouldBeTrue();

result = controller.LogOn(model, string.Empty);
}

[Then(@"I should be redirected to the home page")]
public void RedirectToHomePage()
{
result.AssertActionRedirect().ToAction<HomeController>(x => x.Index());
}

[Then(@"The error message should be shown")]
public void ShowErrorMessage()
{
controller.ModelState[""].Errors[0].ErrorMessage.ShouldEqual("The user name or password provided is incorrect.");
}
}

 

5. Exécutez vos tests ! C’est super, l’intégration est complète avec NUnit et par conséquent avec ReSahrper.

SpecFlow_ReSharper_OK

Juste pour vous montrer que le test échoue bien lorsque le mot de passe fourni n’est pas bon :

SpecFlow_ReSharper_KO

Conclusion

Avec l’outils comme SpecFlow le développement BDD devient encore plus facile. L’intégration complète avec Visual Studio NUnit et donc ReSharper est importante car on n’a pas besoin d’exécuter des outils externes comme dans le cas de NBehave.

J’espère que SpecFlow va évoluer. Il est prévu entre autres l’intégration avec MSTests.

Sur le site de SpecFlow vous trouverez également une version pour Visual Studio 2010.

UPDATE: On vient de me tweeté que SpecFlow supporte les scénarios écrits en Anglais, Français, Allemand, Hongrois, Hollondais et Suédois. Donc vous n'êtes pas obligé d'utiliser l'anglais

Bons tests et à bientôt :)