Elemar DEV

Tecnologia e desenvolvimento

Learning Tests com WatiN

Olá pessoal. Tudo certo?!

Outro dia, falei sobre Learning Tests. A idéia fundamental é “aprender” uma API usando testes unitários para confirmar o aprendizado. Além, temos um registro de como a API funciona e podemos identificar facilmente eventuais mudanças.

No post de hoje, trabalho Learning Tests para WatiN que é uma biblioteca de automação, para testes de UI (principalmente), para .NET.

Minha proposta não é explicar como utilizar WatiN. No lugar disso, escrevo alguns testes que demonstram seu funcionamento.

A melhor forma de não parar é continuar andando em frente.

Criando o projeto e adicionando referências

Como indiquei no post sobre Learning Tests, tudo começa com a criação de um projeto de testes e adição das referências.

Começo meu projeto adicionando referência para NUnit, SharpTestsEx e WatiN.

image

Para o WatiN funcionar, é preciso mudar  o valor da propriedade Embed Interop Types da referência Interop.SHDocVw, de true para false.

image

Se você nunca mexeu com WatiN..

Se você nunca usou WatiN, recomendo que você dedique pouco mais de 2 minutos para ver esse vídeo introdutório.

Todos os exemplos que criei nesse post são adaptados dos exemplos encontrados na documentação oficial.

Primeiro teste

Para ver WatiN funcionar, escrevi um teste simples (semelhante ao que está na home do projeto). Veja:

using System;
using System.Globalization;

using NUnit.Framework;
using SharpTestsEx;

using WatiN.Core;

namespace LearningTests.WatiN
{
    [TestFixture]
    [RequiresSTA]
    public class GettingStarted
    {
        [Test]
        public void SearchForBddOnElemarJrNet()
        {
            using (var browser = new IE("http://elemarjr.net"))
            {
                browser.TextField(Find.ByName("s")).TypeText("BDD");
                browser.Button(Find.ById("searchsubmit")).Click();

                browser.WaitForComplete();

                browser.Html.Contains("terceiros")
                    .Should().Be(true);
            }
        }
    }
}

Algumas observações importantes:

  • WatiN requer STA para funcionar, isso é facilmente obtido via atributo;
  • Utilizei “Ferramentas para Desenvolvedores”, do Internet Explorer, para identificar o nome/id dos elementos da página que desejava trabalhar;
  • Diferente do indicado no site, não utilizei o método ContainsText para ver se a página de resposta possuia determinado texto.

Se você não conhece WatiN, achará interessante como o framework “simula” o usuário.

Segundo teste – utilizando Page Pattern

WatiN oferece alternativas para abstração. Não gosto daquelas buscas de elementos da página direto no teste. Veja a aplicação do “Page Pattern”:

[TestFixture]
[RequiresSTA]
public class GettingStartedUsingPagePattern
{
    [Test]
    public void SearchForBddOnElemarJrNet()
    {
        using (var browser = new IE("http://elemarjr.net"))
        {
            var searchPage = browser.Page<ElemarJRNet>();
            searchPage.SearchCriteria.TypeText("BDD");
            searchPage.SearchButton.Click();

            browser.WaitForComplete();

            browser.Html.Contains("terceiros")
                .Should().Be(true);
        }
    }

    public class ElemarJRNet : Page
    {
        public TextField SearchCriteria
        {
            get { return Document.TextField(Find.ByName("s")); }
        }

        public Button SearchButton
        {
            get { return Document.Button(Find.ById("searchsubmit")); }
        }
    }
}

A utilização dessa abstração facilitaria a “substituição” da página que estamos testando.

Bacana, não?!

Terceiro teste – utilizando Control Pattern

WatiN simula o usuário. O método TypeText dispara todos os eventos relacionados a digitação do usuário, por exemplo.

Se você está utilizando jQuery, pode desejar fazer interações com os componentes chamando métodos apropriados. Para isso, utilizamos outra abstração chamada “Control Pattern”. Veja:

[TestFixture]
[RequiresSTA]
public class GettingStartedUsingControlPattern
{
    [Test]
    public void ChangingValueOfJqueryDatePickerControl()
    {
        using (var browser = new IE("http://jqueryui.com/demos/datepicker/"))
        {
            var datePicker = browser.Control<DatePicker>(
                Find.ById("datepicker")
                );

            var sampleDate = new DateTime(2012, 09, 06);
            datePicker.Date = sampleDate;
            datePicker.Date.Should().Be(sampleDate);
        }
    }
}

public class DatePicker : Control<TextField>
{
    public DateTime? Date
    {
        get
        {
            if (Element.Text == null) return null;

            var date = Eval("{0}('getDate').toUTCString()", ElementReference);

            return DateTime.Parse(
                date.Substring(0, 24),
                CultureInfo.InvariantCulture,
                DateTimeStyles.AssumeUniversal
                );
        }
        set
        {
            var javascriptDate = "null";
            if (value.HasValue)
            {
                var date = value.Value;
                javascriptDate = string.Format("new Date({0}, {1}, {2})", 
                    date.Year, 
                    date.Month - 1, 
                    date.Day);
            }

            CallDatepicker("'setDate', {0}", javascriptDate);
        }
    }

    public string DateFormat
    {
        get { return GetOption("dateFormat"); }
    }

    public bool Enabled
    {
        get
        {
            var isDisabled = CallDatepicker("'isDisabled'");
            return !bool.Parse(isDisabled);
        }
    }

    public string GetOption(string option)
    {
        return CallDatepicker("'option', '{0}'", option);
    }

    private string ElementReference
    {
        get
        {
            return string.Format("window.jQuery({0}).datepicker", 
                Element.GetJavascriptElementReference());
        }
    }

    private string CallDatepicker(string script, params object[] args)
    {
        var theScript = string.Format(script, args);
        return Eval("{0}({1})", ElementReference, theScript);
    }

    private string Eval(string script, params object[] args)
    {
        return Element.DomContainer.Eval(string.Format(script, args));
    }
}

Perceba:

  • Testes passam!
  • Temos exemplos práticos para aprender como a API funciona!
  • Temos formas de verificar mudanças de compatibilidade de novas versões do WatiN (e do Internet Explorer)!

Era isso.

4 comentários em “Learning Tests com WatiN

  1. Eduardo
    15/04/2012

    O unico problema do watin é nao rodar em firefox 4+
    Para testes de ui acho o webdriver melhor

  2. Pingback: Learning Tests com Selenium WebDriver « Elemar DEV

  3. Pingback: BDD na prática – parte 4 – Partindo do TDD « Elemar DEV

  4. Jonas
    19/12/2012

    Olá tem como fazer o watin em windows forms? Eu tenho colocar e da um erro no construtor da classe Form :/

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s

Informação

Publicado às 15/04/2012 por em Post e marcado , , , .

Estatísticas

  • 674,489 hits
%d blogueiros gostam disto: