Ir para o conteúdo
ou

Software livre Brasil

Minha rede

 Voltar a Planeta do A...
Tela cheia Sugerir um artigo

Helio Costa - hlegius : Obtendo o primeiro Test Pass

12 de Maio de 2014, 7:35 , por Software Livre Brasil - 0sem comentários ainda | Ninguém está seguindo este artigo ainda.
Visualizado uma vez

Depois de ficar maravilhado com as promessas de um mundo melhor código mais harmonioso, manutenível e desacoplado, vem uma curta pergunta que nos leva a nossa primeira Rua sem Saída: como fazer meu primeiro teste (do projeto) passar?

You shall Pass!

As minhas Ruas sem saída foram: "em um projeto novo, o que testar primeiro?" e, "em um projeto legado como fazer o primeiro teste?"

Vou criar um cenário hipotético, apenas para fins de apoio: você é contratado para fazer uma Extranet de Bike Shop. Os requisitos em alto nível são:

  • Área segura para somente funcionários/gestores logarem no sistema

Somente após login, a aplicação liberará acesso às features:

  • Cadastro de Marcas e Modelos de bicicleta;
  • Cadastro de bicicleta;
  • Cadastro de peças de reposição para uma (ou várias) marcas de bicicletas. - Pense nessas peças como peças de um determinado fabricante de carro: você pode comprar a peça "original" com a logo do fabricante do carro na peça ou a "paralela" feita pelo mesma empresa (por ex. Cofap, de amortecedores) mas sem a logomarca de nenhuma fabricante de carro, em um CarShop qualquer de rua.
  • Cadastro de peças genéricas (a tal da paralela).
  • Listagem de tudo isso que foi pedido.

Para efeitos de exemplos:

Marca: Caloi
Modelo: Urbe
Peça de reposição: Guidão Flat
Peça genérica: Cambio Traseiro Shimano TX 7 Velocidades

A peça genérica em nosso bike shop, em tese servirá para qualquer bicicleta que precisar daquele componente.

Começando: você escolhe a linguagem de programação, um possível bootstrap para subir um Hello Test no navegador e pronto. Está pronto para começar a fazer as coisas. Mas, e agora?

Sabendo por onde começar

A pergunta inicial não deveria ser "Por onde começar?" mas sim, "O que é mais importante no projeto?". Seu cliente/chefe irá ver o projeto de tempos em tempos e você certamente terá dúvidas que só ele saberá responder. Enquanto o projeto não está pronto, o que é dispensável no projeto?

O sistema de autenticação é claro! Incrivelmente com todos que falei ou fiz essa pergunta (incluindo eu mesmo - sim, falo sozinho), o sistema de autenticação é escolhido como primeira coisa a ser feita. Pense bem. Para que raios a autenticação é importante agora? Ela evitará acesso indevido, mas se o software está em processo embrionário, com acesso limitado ao servidor e dados dummies, para que ele serve? Ignore-o por enquanto e foque no core do negócio!

Os pingos nos ís

Nat Price, sugeriu em seu livro criar um Teste de Aceitação e com este, criar seu primeiro Teste Unitário de Unidade. Seguiria criando os testes de unidade fazendo-os passar até que o teste de aceitação passaria também, finalizando assim aquela feature.

Ciclo do TDD por Nat Price

Eu já fiz essa abordagem, mas achei ela um tanto verbosa em casos onde o do teste de aceitação é muito parecido com o teste de unidade - até porque um software web é arquitetonicamente diferente de um software de missão crítica ou embarcado, por exemplo.

Atualmente, eu sigo apenas o processo interno, sem Teste de Aceitação ou/e Integração pelo simples fato de ser mais direto e não há nenhum efeito colateral no processo em si.

TDD Red Green Refactor ciclo

O Primeiro Green, Like a Boss!

Eu começaria pela Peça. Uma classe para identificar Peças "Originais" e outra para Peças Genéricas ou apenas uma?

O legal é esse tipo de decisão, pode ser adiado com Test-Driven Development. Vamos começar pelo mais fácil: uma classe Peça.

@test
everyGenuinePartBelongsToABicycle()

Assim como em Concessionárias de automóveis, há peças que são relacionadas ao veículo e por mais que sirva em mais de um modelo, a relação Parte-Veículo torna-se indispensável.

Algo assim, pode ser um começo:

class BicyclePartTest {
        private subject = new Part();
        private bicycle = a_bicycle_mock_object;

        @test
        public everyGenuinePartBelongsToABicycle() {
            subject.setBicycle(bicycle)
            assertTrue(subject.isGenuine())
        }
}

Ou seja, para Part (Peça da bike) ser Genuína (Original), a peça precisa estar relacionada a uma bike em específico. Esse simples teste já nos guia para nosso próximo:

class BicycleTest {
        private subject = new Bicycle();

        @test
        public willContainGenuineParts() {
            subject.addGenuinePart(a_mocked_part)
            assertCount(1, subject.getGenuineParts())
        }
}

Uma bicicleta deverá ter Peças. Neste caso, Peça Genuína devemos atentar que a relação é uma Composição, ou seja, a Parte(Part) não existe sem o Todo (Bicycle). Já sabemos também que:

class Bicycle {

        public void addGenuinePart(Part genuinePart) {
            parts.add(genuinePart)
            genuinePart.setBicycle(this)
        }
}

A relação bi-direcional deverá existir, conforme o teste do BicyclePart sugeriu lá no começo.

Montando a classe Part para que satisfaça o teste do BicyclePart, você já verá o Green na tua tela. Mais do que um, dois pontos verdes.

Eu já consigo ter uma próxima dúvida: em peças genuínas, poderá haver mais de uma peça por bike? Sim, não?

Sim! Pode-se optar por quantificar quantas peças daquela a bike tem e aonde elas ficam:

class BicyclePartTest {
        private subject = new Part();
        private bicycle = a_bicycle_mock_object;

        @test
        public genuinePartMustHaveQuantityAndPosition() {
            subject.setBicycle(bicycle);
            subject.definePositionAndQuantity("front", 2)
            subject.definePositionAndQuantity("rear", 2)

            assertEquals(4, subject.getRequiredQuantity())
            assertEquals(["front", "rear"], subject.getPositions())
    }

        @test
        public everyGenuinePartBelongsToABicycle() { ... }
}

Implementando o código de produção, o teste passará mais uma vez. 3 greens!

E Part não Genuína? Também terá posicionamento e quantidade? Uma porca do Cubo da roda, por exemplo são duas na frente (direita e esquerda) e duas atrás (direita e esquerda). Então:

class BicyclePartTest {
        private subject = new Part();
        private bicycle = a_bicycle_mock_object;

    @test
        public partMustHaveQuantityAndPosition() {
            subject.definePositionAndQuantity("front", 2)
            subject.definePositionAndQuantity("rear", 2)

            assertEquals(4, subject.getRequiredQuantity())
            assertEquals(["front", "rear"], subject.getPositions())
    }

        @test
        public everyGenuinePartBelongsToABicycle() { ... }
}

Neste caso nem precisei fazer outro teste. Apenas mudei o input e nome do teste anterior. Agora o teste diz que uma Part precisa ter quantidade e posição. Ok, mas e se eu não a definir? Uma vez que é obrigatório (..) uma ideia é mover para o construtor de Part, não? A simples ideia de fazer por steps, nos faz pensar sobre o negócio que estamos criando e consequentemente, criar um código mais legível e coeso (harmonioso, por exemplo).

Mas, mas...

E o Database Schema? A herança do ActiveRecord ou o Repository do DataMapper? Uma coisa que eu faço - até com Rails - é criar POJO's/PORO's/POPO's - Plain Old (Java | Ruby | PHP) Objects. depois que eu tenho uma relação mínima feita, daí sim eu crio as relações, os schemas, etc - pois eu sei que precisarei isolá-los e etc.

A autenticação ficou para uma fase mais madura do projeto. Poderá ser até mais para o fim, quando realmente ela for útil.

Concluíndo

Seguir o de sempre e começar sempre pelo mesmo lugar não é algo justo de ser feito. Talvez você precise de uma Introspecção para rever algumas práticas (..)

Criar software orientado a testes é muito divertido, você precisa tentar, sério!

Challenge

Se você quer tentar, pegue esse simples projeto que citei aqui e tente implementá-lo em com sua linguagem do momento. Se quiser, pode me enviar por Github para te dar umas dicas. Se quiser também, podemos marcar uma conversa para discutirmos o design da aplicação. Será muito valioso para todos participantes. ;)


Fonte: http://hlegius.pro.br/post/obtendo-o-primeiro-test-pass

0sem comentários ainda

Enviar um comentário

Os campos são obrigatórios.

Se você é um usuário registrado, pode se identificar e ser reconhecido automaticamente.