Não tem teste? Já nasceu legado. Hedley Luna
Não tem teste? Já nasceu legado.Hedley Luna
Quem?
Graduado em Ciência da Computação - UECEMestrando em Ciência da Computação - UECELíder Técnico INSERT-UECEAgilista desde 2010@[email protected]
Agora sim...
Mas… o que é teste?
– Dicionário Aurélio
“Averiguação do funcionamento de algo.”
Mas, como?
“na unha”“print/alert/console“Teste automatizadoTeste unitárioTeste de integraçãoTeste de aceitaçãoTest Driven DevelopmentBehaviour Driven DevelopmentAcceptance Test Driven DevelopmentPlanilhasChecksCaixa PretaCaixa BrancaCaixa Cinzaetc…
Mas...
Tá pronto!(falta só testar….)
Mas, vale a pena…
–Agile Manifesto
“Continuous attention to technical excellence and good design enhances agility.”
Coisa de dev?
NÃO!
“Pair Testing"
–Agile Manifesto
“The most efficient and effective method of conveying information to and within a development team is face-to-face conversation.”
public static int calculaSoma(int a, int b) {return 0;
}
public static void main(String args[]) {System.out.println(“A soma deve ser 4. E foi: “ + calculaSoma(2,2);
}
Testes Automatizados
Qualquer teste que rode sem intervenção humana(ou com pouca)Porque? Velocidade(mesmo nos de aceitação)!Teste de regressão!Feedback rápido e contínuo(Karma, Infinitest…!)Não garante qualidade de código!Não garante “Clean Code”Integração Contínua e Entrega Contínua
“Padrão" de Testes
Teste Unitário
eXtreme Programming!Teste a menor porção de código possívelDeve ser simples e conciso = Isolado = DesacopladoRápida execuçãoDevem ser poucos por classe
val stack = new Stack[Int] stack.push(1) stack.push(2)
assert(stack.pop() === 2) assert(stack.pop() === 1) }List(1, 2, 3, 4, 5) should contain oneOf (5, 7, 9)
it("should pop values in last-in-first-out order") {
Mocks
Facilitar os testesAbstrair implementações complexasMock !== Fake Object !== StubMock = ComportamentoLegados!
@Mock private Gerenciador gerenciador;
NaoDeveExcluirCasoExistamDocumentosVinculados() {when(gerenciador.documentosDo(“fulano”)).thenReturn("existeDocumento");when(gerenciadorSaidas.buscarSaidas()).thenCallRealMethod();
assertFalse(gerenciador.excluir("fulano"));}@Test public void
Teste de Integração
Parafraseando Bruno Maomeh e Matheus Fechine:Se conversa com o DB, não é teste unitárioSe comunica pela rede, não é teste unitárioSe ele toca no sistema de arquivos, não é teste unitárioSe ele não pode rodar junto de outro teste, não é teste unitário
(Possível)Porta de entrada para testes em legados
@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(locations= {"classpath:applicationContext-test.xml"})@Transactionalpublic class UsuarioServiceTest {
private UsuarioService usuarioService;
@Test public void deveCarregarUsuarioJoao(){Usuario usuario = usuarioService.carregaUm(usuarioJoao());assertEquals(usuarioJoao(), usuario);
}
@Autowired
Teste de Aceitação
GUI testingTeste final de uma user story(ou similares)Lento, Custoso e FrágilDev + Tester/RequisitosCaixa Preta
it('should add on service', function(){ element(by.model('service.identifier')).sendKeys('security'); element(by.model('service.function')).sendKeys('Security'); selectDropdownByNumber(element(by.id('serviceType')), 1); element(by.id('utilizationLevel')).sendKeys(protractor.Key.ENTER); element(by.id('btnAdd')).click(); services = element.all(by.repeater('row in renderedRows')); expect(services.count()).toEqual(QUANTITY_SERVICES + 1); });
TDD
Testar !== TDDBaby StepsRápido Feedback + Melhoria ContínuaDesign/Arquitetura de CódigoRegras de Negócio = “Pair Testing” === Compartilhamento de conhecimento
Fluxo TDD
Não escrevo código novo enquanto um teste não quebrar
BDD
Similar ao TDD, mas numa linguagem mais próxima do negócioVantagens do TDD + Traz o business mais perto do desenvolvedorCompartilhamento de ConhecimentoÉ a “evolução do TDD”
public void I_have_a_hello_app_with(String greeting) {hello = new Hello(greeting);
}
@When("^Eu executo minha aplicacao$")public void I_ask_it_to_say_hi() {
hi = hello.sayHi();}
@Then("^Ela deveria responder com \"([^\"]*)\"$")public void it_should_answer_with(String expectedHi) {
assertEquals(expectedHi, hi);}@Given("^Minha saudacao e \"([^\"]*)\"$")
ATDD
Dev + QA/Tester/Requisitos/BusinessEspecificações criadas durante a criação do backlog: Time + PO + Stakeholders(se necessário)Top-Down ou Bottom-Up? Não há consenso.Ponto de Vista do Usuário != Ponto de Vista do Código, logo TDD !== ATDD
Mais importante é… O que NÃO TESTAR!
–Refactoring: Improving the Design of Existing Code, 1999
“The key is to test the areas that you are most worried about going wrong. That way you get the most benefit for your testing effort. It is better to write and run incomplete tests than not to run complete tests”
–Agile Manifesto
“Simplicity--the art of maximizing the amount of work not done--is essential.”
“Novo” requisito =Novo Teste
= Refatoração
–Agile Manifesto
“Welcome changing requirements, even late in development. Agile processes harness change for the customer's competitive advantage.”
Por que nasceu legado?
"Mais fácil re-escrever que refatorar"“Na minha máquina funciona!”“Funciona, só não sei porque…"Difícil de evoluir! Cadê a segurança?Nova feature === +10 Bugs(e que você só detecta em produção)Error prone!
Leituras Recomendadas
Livro de Cabeceira
Testes
Refactoring