If you can't read please download the document
Upload
fabio-miranda
View
1.967
Download
5
Embed Size (px)
DESCRIPTION
- TDD: Red – Green – Refactor - Testes de Unidade x Testes de Integração - Ports and Adapters Pattern - Business Domain versus Technical Domain - Testes de Unidade com JMock - Coverage Tests - Logging Tests
Citation preview
2. Roadmap
3. TDD:RedGreenRefactor 4. Testes de Unidadex Testes de Integrao 5. Ports and Adapters Pattern
Testes de Unidade com JMock 6. Coverage Tests 7. Logging Tests 8. Autenticao num Service Provider de Terceiros
POST http://isp-authenticator.dev.globoi.com:8280/ws/rest/autenticacao XML Resquest Autenticao: 303a6a6f616f646576406d61696cfulano123456127.0.0.1 XML Response Autenticao [email protected]@spam.laAUTENTICADOATIVONAO_ASSINANTE21588993 9. Por onde comear?
10. Queremos uma classe que realize autenticao (um Authenticator) 11. O ponto de partida ser AuthenticatorTests 12. Qual o foco do teste? O nome do teste expressa a inteno?
Um Authenticator deve realizar autenticao caso o nome do usurio e a senha estejam corretos. 13. @Test 14. public void shouldAuthenticateWhenCredentialsAreValid() { 15. } 16. Exercitando o teste
17. @Test 18. public void shouldAuthenticateWhenCredentialsAreValid() {
} 19. Setup e Assertions
20. private final Authenticator authenticator = new Authenticator(); 21. private final String validUsername = [email protected]; 22. private final String validUsername = va1idpassw0rd; 23. @Test 24. public void shouldAuthenticateWhenCredentialsAreValid() {
26. assertThat(authentication response, response.isAuthenticated(), is(true)); } 27. Implemente as classes do domnio (stubs vazios)
28. Observe o testefalhar 29. A mensagem de falha do teste expressa suficientemente bem o que est quebrado? 30. A importncia de falhar antes
31. Promove boas prticas dediagnstico de falhas (GOOS Best Practice!)
32. Elas ajudaro a diagnosticar problemas, quando novas features provoquem quebra de cdigo existente. 33. A ausncia de mensagens claras sobre a falha forar o desenvolvedor a ter que ler e entender a implementao para saber o que quebrou (pior caso: quando o dev que fez quebrar o cdigo no o prprio autor do cdigo) Hamcrest Library: matchers so synthax sugar e ajudam a criar mensagens de falha mais detalhadas. 34. Implemente o cdigomais simplesque permita o testePASSAR
35. KISS Keep It Simple 36. No perca o foco do teste. 37. No se distraia com premissas que devem ser validadas em outros testes. 38. DONE?
O que o Authenticator est fazendo? publicAuthenticationResponse authenticate(String username, String password)throwsAuthenticationFailure { return newAuthenticationResponse();// lazy boy... } public classAuthenticationResponse { publicBoolean isAuthenticated() { return true ;// aham... } }
39. Pausa para Reflexo
40. Resposta: Depende (nenhuma verdade absoluta) 41. Se est interessado em criar um Domain Model, importante separar classes de domnio das classes que possuem detalhes tcnicos de como a funcionalidade implementada. 42. Ports and Adapters Pattern
43. Adapters: implementam as interfaces, encapsulando o domnio tcnico da aplicao 44. Testes de Unidade: verificam o comportamento do Authenticator. 45. Testes de Integrao: verificam a implementao do delegate. 46. Ports and Adapters Pattern (GOOS) 47. Retornando foco ao teste...
privateMockerycontext=newMockery(); private finalAuthenticator.Delegatedelegate=context .mock(Authenticator.Delegate. class ); privateAuthenticatorauthenticator=newAuthenticator( delegate ); @Test public voidshouldAuthenticateSucessfully()throwsException { context .checking( newExpectations() {{ AuthenticationResponse sucessfullAuthentication =newAuthenticationResponse(); sucessfullAuthentication.setAuthenticated( true ); oneOf( delegate ).performAuthentication(with( validUsername ), with( validPassword )); will( returnValue (sucessfullAuthentication)); }}); AuthenticationResponse response =authenticator .authenticate( validUsername ,validPassword ); assertThat ( "authentication response" , response,is ( notNullValue ())); assertThat ( "authentication response" , response.isAuthenticated(),is ( true )); } 48. Rodando os Testes...
49. Falhar o teste : o teste falha de forma clara, facilitando o correto diagnstico? 50. Corrigir Authenticator e AuthenticationResponse epassar 51. DONE?
52. O Delegate responsvel pela autenticao via POST/XML injetado no Authenticator, via construtor. 53. Resta prover uma implementao do Delegate um RestTemplateDelegate, por exemplo e escrever um teste de integrao. 54. Teste de Integrao @RunWith (SpringJUnit4ClassRunner. class ) @ContextConfiguration (locations= "classpath:beans.xml" ) public classRestTemplateAuthenticatorTests { @Autowired privateRestTemplateAuthenticationDelegaterestTemplateDelegate ; privateAuthenticatorauthenticator ; @Before public voidsetup() { authenticator=newAuthenticator( restTemplateDelegate ); } @Test public voidauthenticateUser()throwsException { assertTrue ( authenticator .authenticate( "[email protected]" ,"teste123456" ).isAuthenticated()); } 55. RestTemplateAutenticationDelegate public classRestTemplateAuthenticationDelegateimplementsAuthenticator.Delegate { private finalStringurl ; private finalRestTemplaterest ; publicRestTemplateAuthenticationDelegate(String url, RestTemplate rest) { this . url= url; this . rest= rest; } publicAuthenticationResponse performAuthentication(String username, String password)throwsAuthenticationFailure { try{ XmlAuthenticationRequest xmlRequest =newXmlAuthenticationRequest(); xmlRequest.setIp( "127.0.0.1" ); xmlRequest.setLogin(username); xmlRequest.setSenha(password); XmlAuthenticationResponse xmlResponse =rest .postForObject( url , xmlRequest, XmlAuthenticationResponse. class ); AuthenticationResponse response =newAuthenticationResponse(); response.setAuthenticated(xmlResponse.getStatus().equals( "AUTENTICADO" )); returnresponse; }catch(Throwable e) { throw newAuthenticationFailure(e); } } } 56. E depois?
57. Coverage Test (Eclipse Emma) 58. Manter a cobertura dos testes em nvel elevado (acima de 90%) praticamente impossvel se voc no pratica Test First. 59. Aumentar a cobertura de cdigo Test After muito mais difcil, e pode dar um falsa sensao de cobertura. 60. Se der tempo...
ShouldNotAuthenticateInvalidPassword()
shouldLogFailureOnAuthenticationErrors() 61. LoggingTests! 62. Logging Tests
private static finalLoggerlogger= Logger.getLogger(Authenticator. class ); ... if( logger .isDebugEnabled()) logger .debug(message);
63. Deve-se dar tanta importncia a testes de Logging como damos a testes de UI! 64. No desejvel que as mensagens crticas de logging quebrem com a evoluo da aplicao 65. Caso existam ferramentas automticas de anlise de log, elas iro quebrar caso o logging no seja estvel com o passar do tempo. 66. Mensagens de debbuging no precisam ser testadas. 67. Deve-se selecionar com critrio as mensagens crticas para a aplicao, que precisam ser testadas. 68. Tratar como Logging como Requisitos de Suporte? 69. Logging: Business Domain x Technical Domain
70. Amarra a implementao biblioteca de Logging (mistura o domnio do negcio com o domnio tcnico). 71. Ports and Adapters strikes back
72. Testes de unidade verificam a relao entre Authenticator e FailureReporter 73. Testes de Integrao verificam a implementao do FailureReporter. 74. Logging com Ports e Adapters
75. Dvidas?