2. IC Integração Contínua “Continuous Integration is a software development practice where members of a team integrate their work frequently, usually each person integrates at least daily - leading to multiple integrations per day. Each integration is verified by an automated build (including test) to detect integration errors as quickly as possible. Many teams find that this approach leads to significantly reduced integration problems and allows a team to develop cohesive software more rapidly.” http://www.martinfowler.com/articles/continuousIntegration.html
3. IC IC @ Atlas : Testes: Unidade/Funcionais (Integração)
4. IC Bottom Up! Injeção de Dependência Mocks TDD Integracao Continua / Hudson Conclusão
5. IC Dependency Injection Design Pattern Reduzir acoplamento Vários tipos (constructor injection, setter injection, interface injection)
6. IC Dependency Injection class HardcodedWorkflow { public void execute() { // do LOTS of workflow stuff ... FileSenderService service = new FileSenderService(fileName, "This is a message"); service.send(); // do LOTS more workflow stuff ... } }
7. IC Dependency Injection class FileSenderService implements ISenderService { private String message; private File file; public FileSenderService(String fileName, String message) { this.parameter = message; this.file = File.open(fileName); } public void send() { file.write(message); } }
8. IC Dependency Injection class EmailSenderService implements ISenderService { ... public void send() { smtpLib.send(emailAddress, message); } }
11. IC Dependency Injection class HardcodedWorkflow { public void execute(int delivery) { // do LOTS of workflow stuff ... ISenderService service; if(delivery == MsgDelivery.FILE) { service = new FileSenderService("This is a message"); } else if(delivery == MsgDelivery.EMAIL) { service = new EmailSenderService("This is a slightly different message"); } service.send(); // do LOTS more workflow stuff ... } }
13. IC Dependency Injection ... if(delivery == MsgDelivery.FILE) { service = new FileSenderService("This is a message"); } else if(delivery == MsgDelivery.EMAIL) { service = new EmailSenderService(userAddress, "This is a slightly different message""); } else if(delivery == MsgDelivery.ADMINISTRATOR_EMAIL) { service = new EmailSenderService(adminAddress, "SUDO this is a message!!!"); } else if(delivery == MsgDelivery.ABU_DHABI_BY_AIR_MAIL) { service = new AbuDhabiAirMailSenderService("Hello, Mama"); } else if(delivery == MsgDelivery.DEVNULL) { service = new DevNullSenderService("Hello, is anybody in there??!?!"); // why do I care?!?! } ...
16. IC Dependency Injection To The Rescue!!! class FlexibleWorkflow { private ISenderService service; public FlexibleWorkflow(ISenderService service) // << "LOOSE COUPLING" { this.service = service; } public void execute() { // do LOTS of workflow stuff ... this.service.send(); // do LOTS more workflow stuff ... } }
17. IC Dependency Injection To The Rescue!!! class FileWorkflowController { public void handleRequest() { ISenderService service = new FileSenderService("This is a message."); // << "TIGHT COUPLING!!!" FlexibleWorkflow workflow = new FlexibleWorkflow(service); workflow.execute(); } }
18. IC Dependency Injection To The Rescue!!! class EmailWorkflowController { public void handleRequest() { ISenderService service = new EmailSenderService(getUserEmail(), "This is a slightly different message."); FlexibleWorkflow workflow = new FlexibleWorkflow(service); workflow.execute(); } }
20. IC Testes com Mocks!!! class FlexibleWorkflowTest extends TestCase { // millions of other tests ... public void testMessageSend() { ISenderService mockService = new MockSenderService(); FlexibleWorkflow workflow = new FlexibleWorkflow(mockService); workflow.execute(); assertTrue(workflow.getResult(), true); mockService.assertCalled("send"); // millions of other assertions ... } }
21. IC Mock Objects Mocks aren’t Stubs! http://martinfowler.com/articles/mocksArentStubs.html
22. IC Stubs ISenderService stubService = new StubService(); FlexibleWorkflow workflow = new FlexibleWorkflow(stubService); workflow.execute(); // nada mais a fazer, o stub nao provê nenhuma informacao
25. IC Mock Objects Inspecionar comportamento class FlexibleWorkflowTestextends TestCase { public void testMessageSend() { ISenderService mockService = new MockSenderService(); FlexibleWorkflow workflow = new FlexibleWorkflow(mockService); workflow.execute(); assertTrue(workflow.getResult(), true); mockService.assertCalled("send"); // millions of other assertions ... } }
26. IC Mock Objects Simulando condições de erro public void testMessageSendError() { ISenderService mockService = new MockSenderService(); // mock lanca "SmtpTimeoutException" quando // metodo "send" e chamado mockService.setSideEffect("send", new SideEffect() { void run () { throw new SmtpTimeoutException();} }); FlexibleWorkflow workflow = new FlexibleWorkflow(mockService); try { workflow.execute(); } catch(Exception e) { assertFail(); } } interface SideEffect { void run(); }
28. IC TDD “You have probably heard a few talks or read a few articles where test driven development is depicted as a magic unicorn that watches over your software and makes everybody happy.”
29. IC TDD “ Well, about 18.000 lines of ‘magic unicorn’ code later, I'd like to put things into perspective.”
30. IC TDD “The truth is, test driven development is a huge pain in the ass.”
31. IC TDD “But do you know what sucks more? The liability that comes without those tests.” http://debuggable.com/posts/test-driven-development-at-transloadit:4cc892a7-b9fc-4d65-bb0c-1b27cbdd56cb
32. IC TDD Ok, “Test First” ... ... mas por onde eu começo?!?!
33. IC TDD Ok, “Test First” ... ... mas por onde eu começo?!?!
35. IC TDD Implementar mínimo necessário para o teste FALHAR. class Math { public int sum(int a, int b) { thrownew NotImplementedException(); } } class MathTest extends TestCase { public void testSum() { Math m = new Math(); assertEquals(m.sum(1,2), 3); } }
38. IC TDD Vantagens Código é testável “por natureza”. Ajuda a usar Mocks e Injeção de Dependências.
39. IC TDD Vantagens Código é testável “por natureza”. Ajuda a usar Mocks e Injeção de Dependências. Cobertura de Código.
40. IC TDD Vantagens Código é testável “por natureza”. Ajuda a usar Mocks e Injeção de Dependências. Cobertura de Código. Design gera interfaces (de código) mais “amigáveis”.
41. IC TDD Vantagens Código é testável “por natureza”. Ajuda a usar Mocks e Injeção de Dependências. Cobertura de Código. Design gera interfaces (de código) mais “amigáveis”. TDD não tem “ciúminho”.
45. IC TDD Desvantagens Na 1a. vez, prepare-se para errar. Muito. Mas aprender, mais ainda!
46. IC TDD Desvantagens Na 1a. vez, prepare-se para errar. Muito. Mas aprender, mais ainda! Nada é de graça (No Unicorns)
47. IC TDD Desvantagens Na 1a. vez, prepare-se para errar. Muito. Mas aprender, mais ainda! Nada é de graça (No Unicorns) Código legado
48. IC TDD Desvantagens Na 1a. vez, prepare-se para errar. Muito. Mas aprender, mais ainda! Nada é de graça (No Unicorns) Código legado É um “pé no saco”