Upgrade to Pro — share decks privately, control downloads, hide ads and more …

TDC 2015 São Paulo - Clean Code para Testers

TDC 2015 São Paulo - Clean Code para Testers

Palestra apresentada na trilha de Testes do TDC São Paulo 2015, no dia 22/07.

Stefan Teixeira

July 22, 2015
Tweet

More Decks by Stefan Teixeira

Other Decks in Programming

Transcript

  1. Sobre o palestrante Stefan Teixeira • QA Engineer @ M4U

    • Bacharel em Ciência da Computação pela UFRJ • MBA em Garantia de Qualidade de Software pela Escola Politécnica da UFRJ • Mantém um blog técnico sobre testes: stefanteixeira.com.br • Entusiasta de Testes Automatizados, Agile Testing e da cultura DevOps Contatos: • E-mail: [email protected] • Twitter: twitter.com/stefan_teixeira • Facebook: facebook.com/stefan.teixeira • LinkedIn: linkedin.com/in/stefanteixeira • GitHub: github.com/stefanteixeira • SlideShare: slideshare.net/stefanteixeira
  2. “I like my code to be elegant and efficient. Clean

    code does one thing well.” Bjarne Stroustrup, criador do C++
  3. “Clean code always looks like it was written by someone

    who cares.” Michael Feathers, criador do livro “Working Effectively with Legacy Code"
  4. “You know you are working on clean code when each

    routine you read turns out to be pretty much what you expected” Ward Cunningham, criador do Wiki, do Fit e um dos signatários originais do Manifesto Ágil
  5. Use nomes que revelem a intenção! “Se um nome requer

    um comentário, então ele não revela sua intenção." int v1; //valor do produto à vista int v2; //valor total do produto a prazo int v3 = v2 - v1; //diferença entre valores à vista e a prazo int valorAVista; int valorAPrazo; int diferencaEntreValoresAVistaAPrazo;
  6. Use nomes buscáveis! • Evite usar variáveis com apenas uma

    letra ‣ Usar apenas como variáveis de controle (em um “for”, por exemplo) • Evite usar valores “hardcoded" (constantes, strings, etc.) assertEquals(“Cadastrado com sucesso”, cadastroPage.getMensagem()); public static final String MSG_SUCESSO = “Cadastrado com sucesso”; assertEquals( MSG_SUCESSO, cadastroPage.getMessage() );
  7. Nomes de classes e métodos Classes: • Devem conter substantivos

    ou frases nominais • Ex: LoginPage, Usuario, ConnectionFactory, Conta… Métodos: • Devem conter verbos ou frases verbais • Ex: deletarPagina, salvar, incluirUsuario, removerConta
  8. Classes devem ser pequenas! “The first rule of classes is

    that they should be small. The second rule is that they should be smaller than that.” “Se a gente não consegue dar um nome sucinto a uma classe, então provavelmente a classe é grande demais.”
  9. Funções devem ser pequenas! “The first rule of functions is

    that they should be small. The second rule is that they should be smaller than that.”
  10. Use nomes descritivos! “Não tenha medo de dar um nome

    longo a uma função. Um nome longo e descritivo é melhor do que um curto e enigmático. Um nome longo e descritivo é melhor do que um comentário.” //Testa a inclusão de um usuário informando CPF inválido testeIncluirFalha() testeIncluirUsuarioComCPFInvalidoSemSucesso()
  11. Faça apenas uma coisa! public static String renderizarPaginaComSetupsETeardowns(PageData pageData, boolean

    isSuite) throws Exception { if( isTestPage(pageData) ) { incluiSetupsETeardowns(pageData, isSuite); } return pageData.getHtml(); } O método faz apenas uma coisa? 1) Determina se a página é uma página de teste 2) Caso seja, inclui setups e teardowns 3) Renderiza a página em HTML
  12. Faça apenas uma coisa! • Parágrafo PARA: PARA renderizarPaginaComSetupsETeardowns, verificamos

    se a página é uma página de teste e, caso seja, incluímos os setups e teardowns. Em ambos os casos, renderizamos a página em HTML. Observe que todos os passos da função do exemplo estão a um nível de abstração abaixo do seu nome.
  13. E esse método? public static String renderizarPaginaComSetupsETeardowns(PageData pageData, boolean isSuite)

    throws Exception { if( isTestPage(pageData) ) { WikiPage testPage = pageData.getWikiPage(); StringBuffer newPageContent = new StringBuffer(); includeSetupPages(testPage, newPageContent, isSuite); newPageContent.append(pageData.getContent()); includeTeardownPages(testPage, newPageContent, isSuite); pageData.setContent(newPageContent.toString()); } return pageData.getHtml(); } Como ficaria o parágrafo PARA nesse caso?
  14. Como saber se a função faz apenas uma coisa? •

    Veja se é possível extrair outra função com um nome que não seja uma reafirmação da implementação inicial. “Se uma função executa passos que estão a apenas um nível de abstração abaixo do seu nome, então a função faz apenas uma coisa.” “Funções que fazem apenas uma coisa não podem ser divididas em seções."
  15. DRY (Don’t Repeat Yourself) LoginPage.java public HomePage login(String _usuario, String

    _senha) { usuario.sendKeys(_usuario); senha.sendKeys(_senha); loginForm.submit(); return new HomePage(driver); } public LoginPage loginSemSucesso(String _usuario, String_senha) { usuario.sendKeys(_usuario); senha.sendKeys(_senha); loginForm.submit(); wait.until(ExpectedConditions.visibilityOf( mensagemErro )); return this; }
  16. DRY (Don’t Repeat Yourself) LoginPage.java public HomePage login(String _usuario, String

    _senha) { preencherESubmeterForm(_usuario, _senha); return new HomePage(driver); } public LoginPage loginSemSucesso(String _usuario, String _senha) { preencherESubmeterForm(_usuario, _senha); wait.until(ExpectedConditions.visibilityOf( mensagemErro )); return this; } private void preencherESubmeterForm(String _usuario, String _senha) { usuario.sendKeys(_usuario); senha.sendKeys(_senha); loginForm.submit(); }
  17. “Don’t comment bad code - rewrite it.” “The proper use

    of comments is to compensate for our failure to express ourself in code.” “Innacurate comments are far worse than no comments at all. Truth can only be found in one place: the code.”
  18. Comentários BONS • Comentários legais (copyright) • TODOs ‣ Cuidado

    para não encher o código com TODOs • Amplificar importância ‣ Dar ênfase em algo importante que possa passar despercebido
  19. Comentários RUINS • Redundância //Método usado para preencher o form

    de login, passando usuário e senha como parâmetros e submetendo o form em seguida private void preencherESubmeterForm(String _usuario, String _senha) { usuario.sendKeys(_usuario); senha.sendKeys(_senha); loginForm.submit(); }
  20. Comentários RUINS • Comentários obrigatórios /** * @param _usuario Nome

    do usuario * @param _senha Senha do usuario */ public void preencherESubmeterForm(String _usuario, String _senha) { usuario.sendKeys(_usuario); senha.sendKeys(_senha); loginForm.submit(); }
  21. Comentários RUINS • Noise comments (reafirmam o óbvio) /** *

    Retorna o nome * @return o nome */ public String getNome() { return nome; }
  22. Comentários RUINS • Código comentado ‣ Quem encontrar um trecho

    de código comentado não vai ter coragem de deletá- lo. Podem pensar que é algo importante. ‣ Pratique o desapego. Temos ferramentas de controle de versão para isso. :)
  23. • Funções Dependentes ‣ Se uma função chama outra, elas

    devem estar próximas verticalmente, e a função que chama deve estar acima da que é chamada, se possível. ‣ Isso dá a seu código um fluxo natural. • Afinidade Conceitual ‣Quanto maior for a afinidade entre conceitos de funções, menor deve ser a distância vertical entre elas.
  24. • Formatação Vertical ‣ Projetos Java complexos (JUnit, TestNG, Ant,

    Tomcat) não possuem arquivos com mais de 500 linhas • Formatação Horizontal ‣Cuidado com scroll horizontal!
  25. “Having dirty tests is equivalent to, if not worse than,

    having no tests.” “What makes a clean test? Three things. Readability, readability, and readability.” Mantenha seus testes limpos!
  26. “Any fool can write code that a computer can understand.

    Good programmers write code that humans can understand.” - Martin Fowler “Refactoring is an iterative process full of trial and error, inevitably converging on something we feel is worthy of a professional." - "Uncle Bob" Martin