Automatiser les tests fonctionnels d'un site web avec WatiN et MbUnit (ou NUnit, ou MsTest)

Automatisation des tests de recette des sites Web avec MbUnit, TestDriven.Net et WatiN

Préambule

J'avais l'habitude d'utiliser Selenium pour tester les sites que nous développons et j'ai récemment découvert WatiN, réécriture pour .NET de WatiR. Je le trouve beaucoup plus facile à mettre en oeuvre. Petite introduction rapide avec TestDriven et MbUnit.

Tutoriel

Commencez par télécharger et installer WatiN. Ensuite, ajoutez à votre solution une bibliothèque de classe et ajoutez MbUnit.Framework et WatiN.Core aux références. (PS: ça marche aussi avec MsTest ou NUnit; cf la doc de WatiN sur les différents cas d'utilisation).


Créez une classe publique pour vos tests, référencez les assemblies qu'on vient d'ajouter et donnez lui l'attribut AppartementState pour éviter les problèmes avec IE qui n'est pas ThreadSafe.

using System.Threading;
using WatiN.Core;
using MbUnit.Framework;

namespace Site.Tests
{
    [TestFixture(ApartmentState = ApartmentState.STA)]
    public class BaseTests
    {
    }
}

Ensuite, ajoutez à votre classe une méthode test comme suit :

[Test]
public void CheckLoginPageRedirectsToHomePage()
{
    IE ie = new IE(@"http://localhost/Authentication.aspx");

    ie.TextField("ctl00_cphContenu_Login1_UserName").TypeText("testuser");
    ie.TextField("ctl00_cphContenu_Login1_Password").TypeText("testpass");

    ie.Button("ctl00_cphContenu_Login1_LoginButton").Click();

    Assert.AreEqual(@"http://localhost/", ie.Url);

    ie.Close();
}

Le code me semble assez transparent : on charge une page dans IE, on trouve un champ texte et on tape du texte dedans, idem pour le mot de passe, puis on clique sur le bouton "login" et on vérifie que l'on a bien été redirigé vers la page d'accueil.

Pour lancer le test il suffit de faire clic-droit | "run tests" dans le corps de la méthode (avec TestDriven.NET ; sinon, utilisez MbUnitGuiRunner).

Le test se déroule dans un IE visible; les éléments manipulés par WatiN apparaissent en jaune au fur et à mesure du déroulement.


Si tout va bien (pensez à changer le login/mot de passe), vous aurez ceci dans la fenêtre "sortie" de Visual Studio :

"1 passed, 0 failed, 0 skipped, took 10,96 seconds."


Ce premier test était extrêmement simple mais il permet de mesurer à quel point il facile d'automatiser des scénarios de recette fonctionnelle pour les sites web.

Vous pouvez de plus combiner cette aisance avec les facilités de MbUnit : Notez l'utilisation de prédicats (Find.ById) et d'expressions régulières pour trouver les contrôles, ainsi que la déconnexion en fin de scénario pour permettre de le répéter pour différentes pages.

[TestFixture(ApartmentState = ApartmentState.STA)]
public class BaseTests
{
    private string membersFile;

    [TestFixtureSetUp]
    public void SetupTestFiles()
    {
        string thisPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
        string basePath = Path.Combine(thisPath, @"..SiteApp_Data");
        membersFile = Path.Combine(basePath, "members.xml");
        if(File.Exists(membersFile))
        File.Move(membersFile, membersFile+".bak");
        File.Copy(Path.Combine(thisPath, "members.xml"), membersFile);
    }

    [TestFixtureTearDown]
    public void CleanupTestFiles()
    {
        if (File.Exists(membersFile + ".bak"))
        {
            if(File.Exists(membersFile))
            File.Delete(membersFile);
            File.Move(membersFile, membersFile + ".bak");
        }
    }

    [RowTest]
    [Row(@"http://localhost/default.aspx")]
    [Row(@"http://localhost/prestations.html")]
    [Row(@"http://localhost/contact.aspx")]
    public void TestLoginFromAnyPage(string firstPage)
    {
        using(IE ie = new IE(firstPage))
        {
            ie.Link(Find.ByText("Accès collaborateurs")).Click();

            Assert.IsTrue(ie.Url.StartsWith("http://localhost/Authentication.aspx"));

            ie.TextField(Find.ById(new Regex(@"(w_)+UserName"))).TypeText("testuser");
            ie.TextField(Find.ById(new Regex(@"(w_)+Password"))).TypeText("testpass");

            ie.Button(Find.ById(new Regex(@"(w_)+LoginButton"))).Click();

            Assert.AreEqual(firstPage, ie.Url);

            ie.Link(Find.ByText("Déconnexion")).Click();
            Assert.AreEqual("Accès collaborateurs",
            ie.Div(Find.ById("acces")).Links[0].Text);
        }
    }

    [Test]
    public void CheckLoginPageRedirectsToHomePage()
    {
        IE ie = new IE("http://localhost/Authentication.aspx");

        ie.TextField("ctl00_cphContenu_Login1_UserName").TypeText("testuser");
        ie.TextField("ctl00_cphContenu_Login1_Password").TypeText("testpass");

        ie.Button("ctl00_cphContenu_Login1_LoginButton").Click();

        Assert.AreEqual("http://localhost/", ie.Url);

        ie.Close();
    }
}

Plus aucune excuse pour passer en prod un site non testé !

Pour finir


L'article au format PDF et le zip des codes exemples sont disponibles sur le site de CLT Services

Ce document intitulé « Automatiser les tests fonctionnels d'un site web avec WatiN et MbUnit (ou NUnit, ou MsTest) » issu de CodeS SourceS (codes-sources.commentcamarche.net) est mis à disposition sous les termes de la licence Creative Commons. Vous pouvez copier, modifier des copies de cette page, dans les conditions fixées par la licence, tant que cette note apparaît clairement.
Rejoignez-nous