Eu e o quixadá, mestre do javascript e meu par de hoje, trabalhamos em uma correção de bug visual, e como costumamos trabalhar com desenvolvimento outside-in, chegamos ao dilema de como criar um teste para garantir que a falha existia. A solução encontrada foi inserir asserts dentro do código javascript, tal qual a funcionalidade de asserts do java. O código da função assert ficou parecido com o mostrado abaixo:
function assert(mensagem,valorDesejado,valorRecebido) {
if( valorDesejado != valorRecebido ) {
var html = '<div class="warning">' + mensagem + '</div>';
$('body').append(html);
throw mensagem;
}
}
Em nosso caso, tinhamos que ter a certeza de que após um clique do usuário a barra de rolagem do elemento mantinha-se da mesma forma que anteriormente. Então o código ficou parecido com o mostrado abaixo:
$.get( url, function ( responseHtml ) {
var scrollAnterior = $('#opcoes').scrollTop();
substituiOpcoes( responseHtml );
assert( 'Deveria manter scroll igual', scrollAnterior, $('#opcoes').scrollTop() );
});
No teste de aceitação verificamos então que o texto 'Deveria manter scroll igual' não deveria aparecer. O código do step do cucumber utilizando o watir pode ser visto abaixo:
Then /^a barra de rolagem deveria permanecer na mesma posição$/ do
@browser.text.should_not include('Deveria manter scroll igual')
end
Com o teste pronto e falhando, aí sim corrigimos a função javascript substituiOpcoes(html) de forma a manter o scroll anterior.
Não é uma solução perfeita. Estamos pesquisando uma melhor, como pode ser vista no post Testes de aceitação automáticos para Flash com T-Plan Robot do Anselmo. Mas enquanto isso podemos evitar alguns pontos de falha visuais que costumávamos ter que testar manualmente. Dado que nosso sistema possui 100% de cobertura de testes unitários, somados a 152 cenários de teste de aceitação que abragem 1568 passos, acho que estamos indo por um bom caminho.
Boa ideia, vai ajudar a resolver alguns problemas de teste aqui no time.
ResponderExcluirApenas uma observação: mesmo vc definindo o metodo assert seria mais interessante voce aceitar uma expressao ao inves de 2 parametros. isso torna seu codigo mais transparente e vc facilmente pode reaproveitar o uso desse metodo em varios lugares se for o caso;
def assert ( #expression, "message ) => assert(x > y, "x eh maior que y")