Web,ruby, Ajax ou qualquer outra coisa que me venha a cabeça (com prioridade para esta última)

Mostrar mensagens com a etiqueta Boas Práticas. Mostrar todas as mensagens
Mostrar mensagens com a etiqueta Boas Práticas. Mostrar todas as mensagens

25 abril, 2007

Boas práticas - Ligações externas

Uma excelente fonte de informação sobre o uso de UTF-8 e rails pode encontrar-se em Segurar Entradas em UTF-8 em Rails.

No eigenclass encontra-se um artigo sobre tabelas fracas de chaves, versão corrigida pois havia da parte do autor um falha nos pressupostos quanto ao (momento do) funcionamento do almeida (gargabe colector) e dos finalizadores.

Teste com frequência, verifique os seus pressupostos, codifique com cuidado, leia-a os originais! (cópia descarada do eigenclass)

02 março, 2007

TDD vs BDD - Parte I

Em dezembro escrevi aqui um pequeno artigo sobre BDD - Desenvolvimento Orientado pelo comportamento e TDD - Desenvolvimento Orientado pelo Teste para melhor ilustrar a diferença hoje apresento um exemplo básico de desenvolvimento em TDD.

Os passos a seguir são:

  1. Escrever o teste
  2. Escrever a lógica
  3. Fazer a lógica passar o teste
  4. Refactorizar
  5. A cada refactorização verificar que o teste continua a ser passado
  1. Vamos pois passar ao primeiro passo escrever o teste mais simples possível. Em TDD em ruby a primeira coisa que há a fazer é criar um programa que comece por requisitar os testes unitários:

    
    require 'test/unit'
    

    Para exemplificar iremos criar um Exemplo e portanto iremos criar um teste designado por ExemploTeste:

    
    require 'test/unit'
    
    class ExemploTeste < Test::Unit::TestCase
      def test_initialize
        ex = Exemplo.new
        assert_not_nil(ex)
      end
    end
    

    Corra o programa e veja o que sucede surge um relatório com o número de presunções, falhas e erros com um erro (1 presunção, 0 falhas e 1 erro).

  2. Passemos pois ao passo número 2.

    Criar a classe a testar:

    
    class Exemplo
       def initialize
       end
    end
    
    require 'test/unit'
    
    class ExemploTeste < Test::Unit::TestCase
      def test_initialize
        ex = Exemplo.new
        assert_not_nil(ex)
      end
    end
    

    Se agora corrermos o teste iremos ver que não temos erros. Passámos o teste.

    Se o programa só fizesse isto não servia para nada, por isso, imaginemos que quando um Exemplo é gerado o mesmo gera uma variável com uma string vazia. Ao teste existente acrescentamos um método:

    
    class Exemplo
       def initialize
       end
    end
    
    require 'test/unit'
    
    class ExemploTeste < Test::Unit::TestCase
      def test_initialize
        ex = Exemplo.new
        assert_not_nil(ex)
      end
      def teste_exe
        ex = Exemplo.new
        assert_equal("",ex.exe)
      end
    end
    
  3. Agora corremos novamente o programa teste e vemos que obtemos um erro, pois não existe variável exe na classe a testar. A nossa próxima acção é tratar de a incluir da forma mais simples para passar este teste.

    
    class Exemplo
       attr_reader :exe
       def initialize
       end
    end
    
    require 'test/unit'
    
    class ExemploTeste < Test::Unit::TestCase
      def testar_initialize
        ex = Exemplo.new
        assert_not_nil(ex)
      end
      def testar_exe
        ex = Exemplo.new
        assert_equal("",ex.exe)
      end
    end
    

    Executando novamente o programa vemos que ele passa sem erros mas falha! Porque falta a atribuição inicial de valor a exe. Então tratemos disso

    
    class Exemplo
       attr_reader :exe
       def initialize
         # a arroba denota que é uma variável de instância
         @exe = ""
       end
    end
    
    require 'test/unit'
    
    class ExemploTeste < Test::Unit::TestCase
      def testar_initialize
        ex = Exemplo.new
        assert_not_nil(ex)
      end
      def testar_exe
        ex = Exemplo.new
        assert_equal("",ex.exe)
      end
    end
    

    Agora se correr o programa este passa sem erros nem falhas. O programa evoluíu um pouco. Mas se uma variável não pudesse mudar de valor de pouco servia, vamos pois tentar criar um teste para a mudança do seu valor.

    
    class Exemplo
       attr_reader :exe
       def initialize
         # a arroba denota que é uma variável de instância
         @exe = ""
       end
    end
    
    require 'test/unit'
    
    class ExemploTeste < Test::Unit::TestCase
      def testar_initialize
        ex = Exemplo.new
        assert_not_nil(ex)
      end
      def testar_exe
        ex = Exemplo.new
        assert_equal("",ex.exe)
        ex.exe = "Olá moça!"
        assert_equal("Olá moça!",ex.exe)
      end
    end
    

    Se corrermos o programa ele terá uma falha pois não há forma de mudar o valor. Então tratemos de o fazer.

    
    class Exemplo
       attr_reader :exe
       attr_writer :exe
       def initialize
         # a arroba denota que é uma variável de instância
         @exe = ""
       end
    end
    
    require 'test/unit'
    
    class ExemploTeste < Test::Unit::TestCase
      def testar_initialize
        ex = Exemplo.new
        assert_not_nil(ex)
      end
      def testar_exe
        ex = Exemplo.new
        assert_equal("",ex.exe)
        ex.exe = "Olá moça!"
        assert_equal("Olá moça!",ex.exe)
      end
    end
    
  4. Agora já não temos nem erros nem falhas. Passamos o teste. Então chegou o momento de refactorizarmos a nossa classe Exemplo:

    
    class Exemplo
       attr_accessor :exe
    
       def initialize
         # a arroba denota que é uma variável de instância
         @exe = ""
       end
    end
    class ExemploTeste < Test::Unit::TestCase
      def testar_initialize
        ex = Exemplo.new
        assert_not_nil(ex)
      end
      def testar_exe
        ex = Exemplo.new
        assert_equal("",ex.exe)
        ex.exe = "Olá moça!"
        assert_equal("Olá moça!",ex.exe)
      end
    end
    
  5. Voltamos a correr o teste e podemos comprovar que a nossa refactorização correu bem.

Recursos em inglês

11 dezembro, 2006

BDD e outras metodologias de desenvolvimento

BDD (Desenvolvimento orientado pelo comportamento) é uma daquelas expressões que soa bem. Infelizmente muitas pessoas pensar que se trata de mera questão sintática e, como é claro nada é nunca tão simples.

Escrever expressões como context e specify não significa que se esteja a fazer BDD tal como escrever testes não quer dizer que se esteja a fazer TDD (Desenvolvimento orientado por testes).

Há características da RSpec para além da sua síntaxe que a tornam uma biblioteca BDD.

Exprimir intenção

Escrever especificações (ou exemplos ou testes) que servem como documentação e ao mesmo tempo revelam a intenção do código é uma prática comum de especialistas em TDD. A BDD define esta prática como obrigatória. RSpec torna esta prática fácil de seguir (usando context e specify). O ponto é qualquer sintaxe é boa. Pode seguir a mesma prática usando FIT ou JUnit (ou um de entre as dúzias dos seus clones), uma convenção de identificação e uma ferramenta de reporte como a Testdoc pode gerar algo como isto:


A full stack
- should raise an exception on push
- should allow a pop

RSpec também torna mais fácil exprimir a intenção no próprio código usando construções como:



name.should_match /lak/

Novamente esta síntaxe torna mais fácil escrever código que siga a filosofia BDD mas não é por si só BDD.

Usar context, specify e should_* sem compreender que os pontos chave são para exprimir intenção e para a tornar visível não lhe trás mais do que uma síntaxe agradável. BDD é uma técnica, não uma síntaxe.

Objectos Mock

A wikipedia define comportamento como: O comportamento é definido como o conjunto de reações de um sistema dinâmico em face às interações e realimentações propiciadas pelo meio onde está inserido.

Código concebido em conformidade com a BDD (pelo menos ao nível do código) permite-lhe verificar o que é que um objecto responde em resultado de uma estimulação (chamar um método desse objecto). Não se trata de ver os valores retornados desse método. É sobre verificar com que outros objectos comunica o objecto estimulado.

É aqui que entram os objectos mock. Objectos Mock (ligados a objectos com que comunica) diz-lhe isso. Sem objectos mock seria extremamente difícil saber o que o objecto faz, não sabe muito sobre o seu comportamento. Assim o que muita gente usa é teste baseado no estado. Isto também é aceitável, mas não se trata de BDD.

Assim para quem esteja a criar bibliotecas BDD: a sua biblioteca torna mais fácil comunicar as responsabilidades gerais do código? Pode usar a biblioteca para exprimeir comportamento?

Se não, é provável que só tenha creado um clone da RSpec.

07 dezembro, 2005

HTML ou xhtml?

Embora pessoas como eu tenham aprendido HTML (há 10 aninhos) e esteja a aprender (na minha opinião) a usar convenientemente o xhtml, julgo, que para quem se esteja a iniciar agora no desenvolvimento de web pode aprender uma ou outra desde que a aprenda bem.

O xhtml é mais exigente para quem o cria e para quem o gere no dia-a-dia. Exige mais cuidado e quase que diria que só deve ser usado se podermos controlar (de algum modo mesmo que indirecto) a forma como o mesmo é servido a visitantes das nossas páginas.

Caso contrário podemos abrir uma caixa da pandora de problemas.

A curva de aprendizagem do HTML poderá não ser tão grande (mas algo que devemos incutir em quem aprende que aprender bem exige esforço e dedicação), mas devemos quase implorar para que quem esteja a aprender não nos peça que indiquemos exemplos de páginas bem escritas quer em HTML quer em XHTML, salvo honrosas excepções já aqui anteriormente indicadas.

Estou a fazer um estudo sobre o tipo de erros encontrados em sítios portugueses. São muito poucos, aqueles que encontrei escritos de forma não só a validarem com os programas automáticos de validação mais habituais, mas que além disso, na marcação tirem partido da mesma para transmitirem a verdadeira estrutura do respectivo conteúdo.

Voltando à questão inicial usar/aprender/ensinar HTML ou XHTML mas com o cuidado de o fazer bem é o que é importante, tanto quanto julgo.