Uncategorized

problem to test finatra 2.0.0.M1

If you trying one of finatra’s example:

https://github.com/twitter/finatra/tree/master/examples

And receive the below message:

[warn]  ::::::::::::::::::::::::::::::::::::::::::::::

[warn]  ::          UNRESOLVED DEPENDENCIES         ::

[warn]  ::::::::::::::::::::::::::::::::::::::::::::::

[warn]  :: com.twitter.finatra#finatra-http_2.11;2.0.0.M1: configuration not public in com.twitter.finatra#finatra-http_2.11;2.0.0.M1: ‘test’. It was required from default#atelie_2.

11;0.0.0 test

 I have fixed with the below snippet:

"com.twitter.finatra" %% "finatra-http" % "2.0.0.M1",
"com.twitter.finatra" %% "finatra-http" % "2.0.0.M1" % "test",
"com.twitter.finatra" %% "finatra-http" % "2.0.0.M1" % "test" classifier "tests"

https://groups.google.com/forum/#!topic/finatra-users/F6DbEj-kr1A

Standard
Uncategorized

Má experiência: Os cuidados ao se adotar parcialmente praticas ágeis.

Depois de um tempo digerindo uma situação que passei, estou postando, tentando ser o mais imparcial possível.

(Antes me desculpem pelo post um pouco longo, mas acho que vale a pena!)

Eu tenho nos últimos tempos estudado bastante sobre desenvolvimento ágil, especialmente falando sobre práticas de XP (posso me referir a essas práticas, tanto como práticas ageis, quanto práticas de XP neste texto), como pareamento, TDD, revisão de código, valores do XP como coragem, comunicação, propriedade coletiva de código , etc. Este desejo de estudar desenvolvimento ágil, foi devido a algum tempo, enquanto desenvolvia software, eu tinha diversas sensações ruins, como o medo. O medo apareceu diversas vezes, quando eu alterava uma coisa e tinha medo que quebrasse coisas que dependiam dela. Então o que fazemos neste caso, testamos tudo relacionado.

Aqui nasce um primeiro problema, se testamos manualmente, como todo ser humano estamos sujeitos a erros, imagine a seguinte situação bastante comum em todos os projetos: imagina que desenvolvemos uma funcionalidade, e para esta funcionalidade executamos, digamos, 15 combinações de testes na mão. Agora desenvolvemos uma nova funcionalidade que depende da anterior, mas ai precisamos fazer alguma alteração na primeira funcionalidade. Agora temos que garantir que a primeira e a segunda funcionalidade continuam tendo o comportamento que esperamos. 0K até aqui nenhuma novidade, mas garantir que a funcionalidade anterior continua funcionando, significa que temos que executar os 15 testes da antiga, e digamos que para a nova funcionalidade há mais 15 testes.

Agora são 30!

Essas dependencias entre partes do meu sistemas, sabemos que são naturais, testar é necessário, mas sabemos que testar 30 cenário é bem chato! Além do que podemos esquecer, e mesmo se estiver escrito, podemos sem querer pular um cenário, isso quando não acaba a paciência e testamos apenas alguns poucos cenários que PENSAMOS ser necessários, etc.

Definitivamente esse tipo de coisa me deixava frustrado ao escrever aplicações. Eu não queria passar a minha vida inteira fazendo coisas desse tipo. Mas definitivamente, eu gostava do que fazia, gostava de escrever código, e ver coisas irem para a produção.

Outra coisa que me incomodava bastante é que eu não sabia escrever código bonitos, eu simplesmente não conseguia escrever código sem grandes lógicas condicionais, métodos extremamente grandes, dificeis de ler, de dar manutenção. E aqui nasce mais medo, mais frustração.

E perante a isso tudo, fui atrás de respostas, eu queria saber o que eu poderia fazer para melhorar tudo isso. E depois de passar por vários livros, estudando técnicas e metodologias eu acabei me deparando com ágil.

As práticas de XP que citei no começo elas tentam lidar com esses medos, exemplo: quando faço TDD, a cada passo que vou para frente, tenho um feedback, esse feedback me mostra se estou fazendo certo ou errado, se eventualmente estiver errado, volto e adoto uma nova abordagem, mas sem que seja necessário percorrer um grande caminho até perceber que eu estava errado. Além disso, os testes me força bastante a ter um cuidado com design e tomar bastante cuidados com a Orientação a Objetos, especialmente os test first do TDD. E isso me fez estudar bastante orientação a objetos também, fazendo com que eu evoluísse muito meus códigos, e conhecimento sobre padrões de projeto.

Outro ponto do TDD é que se automatizo meus cenários, não vou precisar testa-los a mão, é só rodar os testes e garanto que não quebrei nada, me permitindo que eu possa refatorar e melhorar o design do código deixando-o sucindo e funcionando! Isso reduz drasticamente meu extress ao desenvolver aplicação. E me deixa muito mais feliz, por que meus códigos estão muito mais interessantes, e flexiveis, além do mais não estou executando centenas, ou atém milhares de cenários de teste na mão.

Perante estes fatos, a primeira coisa que adotei no meu dia a dia, foi TDD. Apenas destacando que a equipe não adotava praticas ageis, a equipe adotava scrum (framework ágil, mas que não preocupações com qualidade interna de código).

Então um dia desenvolvendo uma funcionalidade, percebi um pequeno bug em um componente, ao olhar para dentro deste componente, vi que seria chato fazer a correção deste pequeno bug, por que era um código cheio de lógica condicional. Então com o valor de coragem no coração, eu escrevi testes que tentavam garantir o funcionamento deste componente, depois da famosa barra verde, eu refatorei o código para utilizar polimorfismo, removendo assim as inumeras lógicas condicionais, e deixando o código mais fácil de ler e mais sucinto! Ai depois veio a correção do pequeno Bug.

Depois fiz um pequeno teste de aceitação e tudo funcionando! TUDO?

Bom, não foi bem assim, este componente era usado por diversas outras funcionalidades, e esta correção que eu fiz (prestem bem a atenção, não foi a refatoração que quebrou o código e sim a correção do pequeno bug), gerou um outro bug para as funcionalidades que usavam esse componente. Isto devido a entrada diferente que era dada para este componente nos outros pontos do código!

Resultado, bug em produção, estress, superior bravo!

Mas e ai qual foi o problema realmente, mexer no que estava funcionando para os outros casos, ou seja, mexer no que estava FUNCIONANDO é ruim então? Quem desenvolve aplicações a algum tempo, quase sempre já viu ou participou de situações que alguém queria reescrever o código, por que estava muito difícil evoluir, incluir novas funcionalidades ou corrigir bugs. Então mexer no que está funcionando não é algo ruim, ajuda a melhorar, a encontrar bugs (como foi o caso), mas isso tem que ser feito com cuidado evidentemente, tem que ter cobertura de testes, e não somente unitário, os erros que estouraram no caso foram em telas, teste de aceitação nessas telas teriam sido capazes de ver que o código estava quebrando.

Então aqui está o primeiro ponto, escrevam testes, escrevam testes para tudo, vocês vão gastar tempo quando começarem, só depois de automatizar, é só rodar, e você não gastar tempo com testes na mão, e garante que funcionalidades existentes continuam funcionando!

Um outro ponto é o seguinte, eu sozinho fiz essa alteração, e não percebi que aquela alteração poderia afetar outras coisas, agora para mim, é evidente que eu deveria ter testado outras coisas que dependiam deste componente, não só o meu caso. Mas naquele momento isso não era tão evidente para mim, será que se tivesse algum outro desenvolvedor, ao meu lado a chance de detectar isso não teria aumentado?

Nós estamos falando aqui de pareamento, o par aumentaria bastante essa possibilidade, de ter visto esta dependencia. E muito provavelmente teríamos pego esses problemas.

Para quem diz, que pareamento é muita perca de tempo, pense em grande parte do desenvolvedores que conhecemos, quanto tempo eles perdem tempo, olhando eventualmente o twitter, facebook, etc. Não estou falando que não pode fazer isso, estou falando apenas que fazemos muito menos se estivermos com alguém do lado, trabalhamos o dia inteiro, sinceramente, saindo no final do dia com a sensação de que trabalhamos muito, e produzimos bastante, isso me dá uma sensação de satisfação muito grande!

E agora, e se outros devs além do par, olhassem para o código para ver as alterações, se é possível evoluir algo, se ve algum problema? Isso é a revisão de código!

Revisão do código aumentaria mais ainda a possibilidade da detecção do problema! E pensem por um momento, um exemplo clássico é muito útil, quando um escritor escreve um livro, passa por diversas revisões, por que certamente pode escrever algo errado. Qual é a chance de escrevermos algo errado, em algo que não é tão trivial como o código de nossa aplicação? É muito grande!

Bom, eu pensei bastante, e fiquei bastante surpreso como as práticas ágeis de desenvolvimento poderiam ter capturado este problema antes de ir para a produção. A adoção apenas do TDD, me ajudou bastante, mas é evidente adoção parcial, requer certos cuidados, principalmente se a equipe não está muito disposta a adotar as diversas práticas. Mas não espere que as pessoas em volta entendam isso. Temos que evoluir independentes dos erros que possam acontecer, e estes erros nos ensinam bastante!

Standard
java, joda time

Dica preciosa de JodaTime em tempos de mudança de horário de verão

Muitos de nós simplesmente odiamos as APIs padrões do java de data (Calendar, Date). E se você ainda não odeia, recomendo fortemente a pensar em odiar, e um ponto de partida é conhecer JodaTime. A API simplifica enormemente, o uso de datas.
http://joda-time.sourceforge.net/
Aqui nesse post, estou colocando algo que eu passei com JodaTime, eu não vou me preocupar com detalhes basicos da API. Se você não viu ainda, brinque um pouco e volte aqui por que creio que vai lhe ser muito útil.
A história começa mais ou menos assim: Um belo dia, eu chego na empresa, e me falam que os testes unitários estavam quebrando (olha o valor dos benditos testes unitários). Mas o curioso é o seguinte, nenhuma classe envolvida nos testes unitários foram alteradas. #MEDO!!!
Os testes eram referentes uma consulta em alguns objetos, eu tenho uma consulta que fazia usando joda time, para não ficar preso aos dias no qual eu estava escrevendo, eu fiz o seguinte:
Testa entre 7 e 4 dias atrás, dessa forma, toda vez que meu teste rodava, será com as datas com referencia no dia atual, não a uma data fixa.
Olhando para o teste junto com outro analista (agradeço ao Felipe Pedrine – @felipepedrini), o teste quebrou bem no dia que irá mudar o horário de verão, e na hora 00
A exceção era o seguinte:

  • Exception in thread “main” org.joda.time.IllegalFieldValueException: Value 0 for millisOfDay is not supported: Illegal instant due to time zone offset transition: 2011-10-16T00:00:00.000 (America/Sao_Paulo)

BOOM!

E agora, o que fazemos batman?

O trecho de código era bem parecido com o seguinte:
diaDaMudancaDeHorarioDeVerao.millisOfDay().withMinimumValue();

bom caros devs, vamos pensar um pouco, devido ao time zone, o joda time sabe que nesse dia tem mudança de horário de verão. E se agente pensar ainda mais, vamos perceber uma coisa bem bizarra, mas é fato:

  • no dia em que há a mudança de horário deve verão, os relógios são adiantados de 00:00 Hs para 01:00 Hs. Então na verdade no dia do horário da mudança, o periodo entre 00:00 e 00:59:59.999 SIMPLESMENTE NÃO EXISTE!!!!!!!!!!!!!!!

Óóóóóóóó que triste! E por que esse periodo não existe, a Classe DateTime do JodaTime se recusa o deixar você colocar o horário do dia com millis Segundos do dia como zero, como o código mostrado fazia.

Bom, mas o que podemos fazer?

Claro, isso depende um pouco do caso, o primeiro ponto é que essa aplicação, fazia consultas que eu tinha que pegar da primeira hora do dia, até a última hora do dia. A alternativa para este caso é a seguinte, use o LocalDate da seguinte forma:

  • diaDaMudancaDeHorarioDeVerao.toLocalDate().toDateTimeAtStartOfDay()

Quando você usa o LocalDate, e chama o método toDateTimeAtStartOfDay, ele já se preocupa com o time zone para você, e não tentar começar o dia a meia noite, e sim a uma hora da manhã. Além do fato de ser totalmente compativel com time zone de paises como eu vi algum que a mudança de horário começar a uma hora da manhã para as duas horas da manhã (não me pergunte o porque).

  • Se o sistema está com preocupações como ser 24/7, e a sua data precisa de hora, é melhor usar o LocalDateTime.

Apenas para reforçar, o problema só foi percebido, antes de entrar na produção, por que havia testes. Então escrevam testes, eles são para te dizer se algo está certo ou errado, antes de gerar um stress maior.

Abraço

[Editado]

P.S.: Agradeço aqui os meu camarada salsa @dcmdeivid que sempre faz revisões importantes nesses posts, Vlw velho!

Standard
branch coverage, desenvolvimento de software, line coverage, tdd

Cobertura de Teste

Olá amigos, como estão?

Por coincidência, nos últimos dias eu participei de duas discussões sobre o quanto deveria ser a cobertura de código, principalmente quando falamos de TDD, imaginamos código com uma ótima cobertura. Mas que número representa essa ótima cobertura de teste.

Bom este assunto é sempre muito polemico e eu não poderia deixar de dar meus pitacos sobre este ele, também já muito discutido. Como sempre vou colocando que não sou o dono da razão então, eu me reservo o direito de escrever o que pensar, mas também me dou o direito de receber feedback, isso sempre é muito bem vindo!

Algumas das opniões mais comuns são as seguintes:

    • Eu não testo algumas coisas por que não há tempo, o cliente chega uma hora e fala: esquece tudo isso ai por que eu quero virar minha versão semana que vem. No mundo corporativo isso não é possivel;
    • A cobertura de teste tem que ser 100%, por que assim temos muita segurança na redução de bugs, mesmo que signifique em algum momento escrevermos testes mais intrusivos, e não ter 100% nos leva ao problema da janela quebrada, com certeza vai chegar um outro desemvolvedor que não vai escrever teste por que diz: há aquilo ali não está testado;
    • Os testes serão escritos até o momento que eu tiver segurança de que aquilo que eu que eu quis implementar está DONE, isto é, eu codifiquei todo o comportamento que eu gostaria de codificar;
Bom vamos dissecando de vagar. O primeiro argumento me leva a pensar no seguinte: se eu faço algo que considero importante, mas que eu posso descartar no meio do projeto (detalhe: não estou falando de experimentação, ou testes para fazer refactoring de coisas que não há teste, que eventualmente jogamos coisas fora, mas valem realmente muito a pena), então eu reavaliar duas coisas: primeiro muito provável em boa parte dos casos é questionar se eu estou executando algo exatamente da maneira como deveria ser? Se avaliarmos criteriosamente e chegarmos a resposta que sim para esta questão, então partimos para o segundo questionamento: será que o que estamos fazendo vale a pena?
Bom me parece claro que usar TDD e ter uma boa cobertura de teste ajuda e muito as nossas aplicações a reduzirem drasticamente os bugs, economia de tempo em debug, nos tornamos muito mais confidentes do código que escrevemos, reduzimos drasticamente a programação por coincidência, reduzimos o tempo de manutenção, os testes são também ótima fonte de documentação, etc. Isto é os argumentos no primeiro questionamente são extremamente frageis. Ainda citando o fato da pessoa colocar: mas seu eu tenho uma camada do meu software que só faz delegação (bom creio que ele estava se referenciando aos antipattens Façade, e service usado como façade). Eu vou questionar o seguinte: para que eu preciso de camada de software que não faz nada só delega? (Estes problemas são os mesmo o por que tem um bando de gente usando remotabilidade, etc, a explicação é a seguinte: é por que ela nunca viu algo diferente e nunca se questionou se isso era realmente necessário).
Bom com isso considero esse argumento não valido.Partindo para o segundo argumento agora, mas eu vou descutir junto neste ponto a terceira opnião. Ter 100% de line coverage na nossa aplicação é realmente um ótimo cenário, temos um código totalmente testado, e isso de fato é muito bom. O problema é o seguinte, eu escrevo testes para cada pequeno comportamento que eu adiciono, fato, e chega um determinado momento que eu entendo como feito minha feature. Neste momento o que eu faço: rodo algo para gerar uma medida de cobertura de código para ver qual é a cobertura dessa nova feature, então eu faço o esforço necessário para que tenha a tão sonhada cobertura de 100%. Bom é neste momento que eu acho que as coisas começam a ficar um pouco esquisitas, este esforço tenta cobrir qualquer que seja a combinação possível do meu código, me dá a sensação de que deixou de ser qualidade da feature e sim a cobertura de código. Bom, é importante eu deixar claro aqui, que não estou falando que as coisas que eu faço de 0, 5, 10, 50, 90, 100% de line coverage, e nem estou dizendo que não devemos gerar medidas da cobertura de código dos nossos testes, até por que a medida pode nos dizer que um ponto da nossa aplicação está extremamente sujeito a falhas, por que os testes não cobrem adequadamente e devo atacar para dar qualidade a essa área. Eu estou defendendo que eu enquanto desenvolvendo não devo ficar preso ao 100%.
Kent Back enfatiza isso no TDD by example, e cita uma frase: Até que ponto eu testo? Até o ponto que a insegurança se torne monotonia. Além de dizer também, depois de um refactoring: Eu não escrevi um teste explicito para este caso, mas por que eu sei que se os testes que eu escrevi estiverem passando, então eu sei que o comportamento da minha classe está ok! Mas claro ele cita também a seguinte frase no final do capitulo 17, o TDD seguido religiosamente deveria gerar 100% de cobertura de teste. Batendo esta última afirmação com a penutima, podemos dizer o seguinte: Faça testes, use o baby step, isso certamente vai lhe aproximar da cobertura de 100%, por que a cada adição de um pequeno comportamento, você está gerando testes, e criando um armadura para a sua aplicação. Tire bastante medidas do seu código também, eles são ótimos para fazermos analises de problemas, mas também, não se desespere se rodar alguma tipo de medida e seu código tiver 90%, 95% ou 99% coberto, se você está seguro de o que você fez está funcionando, então os testes cumpriram sua obrigação enquanto garantia de qualidade do desenvolvido.
Abraços
Standard
Uncategorized

Lei de Demeter

Sempre que se fala em lei de demeter, causamos vários desconfortos!

http://en.wikipedia.org/wiki/Law_of_Demeter

Basicamente ele está falando daquela longa lista de encadeamento de chamadas de método, e que com razão ele fala que isto pode gerar acoplamento de uma unidade com diversas classes, já que quando fazemos essas chamadas, muitas vezes acabamos acessando mais de um objeto em uma unidade.

Sim, creio que isto sempre deve estar em nossas cabeças: ELE TEM COMPLETA RAZÃO! Mas e aquelas elegantes DSLs que utilizamos? Invariavelmente fazemos encadeamento de chamada de métodos, não é?

Bom, esquecendo a parte não fale com estranhos – que creio é um grande consenso – outros objetos diferente dos vizinhos – o caso é que ele descreve que não é bom cada unidade se relacionar com mais de uma unidade – sob uma perspectiva de comportamento em orientação a objetos, cada método deve ser uma unidade de comportamento.

Alguns defendem que o encadeamento de método é difícil para debugar. Esse argumento não é valido, já que como temos juízo desenvolvemos baseado em testes/comportamento cada unidade deve estar testada. 0k, argumento rejeitado!

Mas sinceramente, se, e somente se, a DSL se relacionar única e exclusivamente com o objeto e seu vizinho, continuamos respeitando de não falar com estranhos e entregamos ao usuário da API um grande conforto (a final, quem usa DSL sabe que a vida dos desenvolvedores é muito melhor! :-D).

Sinceramente, não há como abrir mão no nosso dia desta excelente ferramenta, muito útil, e que tornam nossas aplicações muito mais manuteniveis!

Martin Fowler chega a dizer que a lei de Demeter, na verdade deveria ser chamada de Sugestão de Demeter.

http://martinfowler.com/articles/mocksArentStubs.html

Bom, realmente acho que a Sugestão de Demeter é importantíssima, mas com certeza, pode ser adaptada as nossas necessidades, mas em fim, não ferimos tanto assim ela!

Standard
Uncategorized

BDD não é um bixo que morde!

Olá amigos!

Tenho percebido que muitos desenvolvedores encaram a sigla BDD (Behavior Driven Development) como Outra coisa nova, para caras que nunca vão usar para nada.

Dan North desenvolveu esta abordagem, por que percebe que muitas das vezes os testes que ele desenvolvia ou em algum treinamento que ele aplicava era focado simplesmente em testar a aplicação, que efetivamente diversas vezes não tinha nenhuma relação com o negócio em si. Ou seja, o foco não estava no que o software deveria fazer, não estava no comportamento (Behavior), não estava no que realmente agrega valor ao cliente, na verdade estava em simplesmente testar a aplicação, criando coisas com grande cobertura de teste, mas que mesmo assim, diversas vezes falhavam em entregar as funcionalidades ao cliente.

http://dannorth.net/introducing-bdd/

A idéia então é focar no comportamento, para que seja desenvolvido o que  realmente importa: o backlog. E a utilização de BDD não exclui o uso das tecnicas de TDD, muito pelo contrário. O único detalhe é o foco do desenvolvimento dos seus teste unitários ou de aceitação (ver link abaixo).

Bom quando disse acima que muitos dizem que é coisa nova, isto é algo que simplesmente mostra o esvaziamento das pessoas com relação a evolução de suas carreiras. Não estou falando nada de novo neste artigo (como sempre), gente muito mais respeitada do que eu já falou sobre este assunto, basta digitar no google, além do mais eu disse anteriormente que as técnicas de TDD devem ser utilizadas aqui, então efetivamente não há nada de novo.

O BDD está altamente enraizado hoje na comunidade Ruby, com os rock stars Test::Unit e RSpec/Cucumber, porém o primeiro framework para BDD que nasceu foi para java, o JBehavior. Então, não vejo  o porque desta resistência! O JBehavior integra bem (obrigado!!!!) com o Maven, além de fazer excelente parceria com o selenium.

http://css.dzone.com/news/continuous-testing-selenium?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+zones%2Fcss+(CSS+Zone)

Abram espaço para o BDD, ele efetivamente pode ajudar nos seu projetos, e na sua carreira!

Abraços

Standard