Concrete Logo
Hamburger button

Testes usando JS

  • Blog
  • 17 de Outubro de 2012
Share

Se você pretende fazer testes em Javascript e nunca fez, sugiro começar vendo as seguintes apresentações:

 
Pretendo compartilhar aqui o que ando estudando no livro Secrets of JavaScript Ninja.

Na verdade meu objetivo é voltar a estudar o Node.js e retomar o ponto em que parei há 2 anos atrás. O Node.js (ou o cancer, como alguns amigos costumam chamar e não vou explicar aqui o por quê desta piada interna), não é tudo o que eu (ou talvez também o Emerson Macedo que ministra cursos de Node.js) pensava que fosse mas é muito melhor do que muitos pensam.

Os links abaixo são mais dedicados a testes com o Node.js:

 

Notas do estudo do livro Secrets of JavaScript Ninja

Tudo que escrevo abaixo saiu do livro citado e entendam como anotados do meu estudo.

    Debugar seu código

    O modo mais simples de mostrar o que está acontecendo é incluir alguns console.log no meio do seu código. O Node.js também suporta o console.log.

    E também funciona no firebug ou no devtools do Chrome, que para alguns talvez seja melhor do que o firebug (recomendo muito ver Devtools could do that?.

    No livro o John Resig melhorou um tiquinho criando uma função de log que funciona também nos browsers. É esta aí embaixo que usa o alert se console.log não for suportado:

    [sourcecode language=”javascript”]
    // Listing 2.1: A simple logging statement that works in all browsers.

    function log() {
    try {
    console.log.apply( console, arguments );
    } catch(e) {
    try {
    opera.postError.apply( opera, arguments );
    } catch(e){
    alert( Array.prototype.join.call( arguments, " " ) );
    }
    }
    }[/sourcecode]

    Se você quiser uma versão que realmente funcione em todos os browsers visite Complete cross-browser console.log()

    Testando assim você terá a sensação de como era programar nos anos 70 com os programas lotados de “passei por aqui”… 😉

    Nah, este negócio já era. Todo mundo testa usando asserts (bem, nem todo mundo, existem os BDDers mas este papo fica para outro choppe).

     

    xUnit x BDD

    Quem vem do mundo xUnit talvez esteja mais acostumado com asserts (oks, equals, sames, etc.) do que com describes e expects.

    Além do QUnit linkado quando falei nos asserts, ainda há o YUI 3 Test, framework do Yahoo bem do jeitão xUnit.

    Neste post vou falar só dos asserts do mundo xUnit.

     

    Funçao assert

    Uma function assert para funcionar em um browser:
    [sourcecode language=”javascript”]
    // Listing 2.4: Implementação simples de um assertion
    function assert( value, desc ) {
    var li = document.createElement("li");
    li.className = value ? "pass" : "fail";
    li.appendChild( document.createTextNode( desc ) );
    document.getElementById("results").appendChild( li );
    }[/sourcecode]

     
    Um exemplo de uso poderia ser:
    [sourcecode language=”html”]
    <!– Listing 2.5: Uma implementação de grupo de testes. –>

    <html>
    <head>
    <title>Test Suite</title>
    <script>
    (function(){
    var results;

    this.assert = function assert( value, desc ) {
    var li = document.createElement("li");
    li.className = value ? "pass" : "fail";
    li.appendChild( document.createTextNode( desc ) );
    results.appendChild( li );
    if ( !value ) {
    li.parentNode.parentNode.className = "fail";
    }
    return li;
    };

    this.test = function test(name, fn) {
    results = document.getElementById("results");
    results = assert( true, name ).appendChild(
    document.createElement("ul") );
    fn();
    };
    })();

    window.onload = function(){
    test("A test.", function(){
    assert( true, "First assertion completed" );
    assert( true, "Second assertion completed" );
    assert( true, "Third assertion completed" );
    });

    test("Another test.", function(){
    assert( true, "First test completed" );
    assert( false, "Second test failed" );
    assert( true, "Third assertion completed" );
    });

    test("A third test.", function(){
    assert( null, "fail" );
    assert( 5, "pass" )
    });
    };
    </script>
    <style>
    #results li.pass { color: green; }
    #results li.fail { color: red; }
    </style>
    </head>
    <body>
    <ul id="results"></ul>
    </body>
    [/sourcecode]

    Ops, achou um pouco diferente? É que agora foi incluída uma variável results para fazer testes em grupo.

    Mudar isto para o Node.js é bem facinho. Vou deixar isto para quando escrever exclusivamente sobre o node.

     

    Testando assincronicidades

    Exemplo: testar requisições AJAX ou animações.

    Passos para que cada grupo de teste possa ser executado assincronamente:

      1. Agrupar operações de mesma assincronicidade;
      2. Colocar cada grupo de teste em uma fila para ser executado depois do término do grupo anterior.

    Exemplo:
    [sourcecode language=”html”]
    <!– Listing 2.6: Uma suite simples de testes assíncronos. –>

    <html>
    <head>
    <title>Test Suite</title>
    <script>
    (function(){
    var queue = [], paused = false, results;

    this.test = function(name, fn){
    queue.push(function(){
    results = document.getElementById("results");
    results = assert( true, name ).appendChild(
    document.createElement("ul") );
    fn();
    });
    runTest();
    };

    this.pause = function(){
    paused = true;
    };

    this.resume = function(){
    paused = false;
    setTimeout(runTest, 1);
    };

    function runTest(){
    if ( !paused && queue.length ) {
    queue.shift()();
    if ( !paused ) {
    resume();
    }
    }
    }

    this.assert = function assert( value, desc ) {
    var li = document.createElement("li");
    li.className = value ? "pass" : "fail";
    li.appendChild( document.createTextNode( desc ) );
    results.appendChild( li );
    if ( !value ) {
    li.parentNode.parentNode.className = "fail";
    }
    return li;
    };
    })();

    window.onload = function(){
    test("Async Test #1", function(){
    pause();
    setTimeout(function(){
    assert( true, "First test completed" );
    resume();
    }, 1000);
    });

    test("Async Test #2", function(){
    pause();
    setTimeout(function(){
    assert( true, "Second test completed" );
    resume();
    }, 1000);
    });
    };
    </script>
    <style>
    #results li.pass { color: green; }
    #results li.fail { color: red; }
    </style>
    </head>
    <body>
    <ul id="results"></ul>
    </body>
    [/sourcecode]

 
Para entender melhor os códigos aqui listados, sugiro fortemente comprar o livro em Secrets of the JavaScript Ninja

 
É isso, este post na verdade não tem nada de original. É mesmo como se fosse anotações de estudo. Mas compartilho aqui para saber como o pessoal está fazendo e de quais outras fontes estão bebendo.

 
Futuramente falaremos aqui especificamente do Node.js e tomara possamos contar com a ajuda do time da Concrete que no momento está desenvolvendo uma aplicação com ele. Viu Alexandre Cardoso?