TDD - Outside In vs dentro para fora

50

Qual é a diferença entre criar um aplicativo Outside In vs construí-lo Inside Out usando o TDD?

Estes são os livros que eu li sobre TDD e testes unitários: Desenvolvimento orientado a testes: por exemplo
Desenvolvimento Orientado a Testes: Um Guia Prático: Um Guia Prático
Soluções do mundo real para o desenvolvimento de frameworks e aplicativos PHP de alta qualidade
Desenvolvimento orientado a testes no Microsoft .NET
Padrões de teste xUnit: refatoração Código de teste
A arte do teste de unidade: com exemplos no .Net
< href="http://rads.stackoverflow.com/amzn/click/0321503627"> Desenvolvimento de software orientado a objetos, guiado por testes --- > Este foi realmente difícil de entender, pois JAVA isn ' t meu idioma principal:)

Quase todos eles explicaram os fundamentos do TDD e os testes unitários em geral, mas com pouca menção das diferentes maneiras pelas quais o aplicativo pode ser construído.

Outra coisa que notei é que a maioria desses livros (se não todos) ignora a fase de design ao escrever o aplicativo. Eles se concentram mais em escrever os casos de teste rapidamente e deixar o design surgir sozinho.

No entanto, me deparei com um parágrafo em xUnit Test Patterns que discutia as formas como as pessoas abordam o TDD. Existem 2 escolas por aí Fora em vs Dentro de fora .

Infelizmente, o livro não elabora mais sobre este ponto. Desejo saber qual é a principal diferença entre esses dois casos.
Quando devo usar cada um deles?
Para um iniciante no TDD qual deles é mais fácil de entender?
Quais são as desvantagens de cada método?
Existe algum material que discuta este tópico especificamente?

    
por Songo 27.09.2012 / 13:05
fonte

4 respostas

42

Inside-Out e Outside-In são termos bastante raros, mais frequentemente eu ouvi / li sobre escola clássica e escola de Londres .

  • De dentro para fora (Escola clássica, de baixo para cima ): você começa no nível de componente / classe (dentro) e adiciona testes aos requisitos. À medida que o código evolui (devido a refatorações), novos colaboradores, interações e outros componentes aparecem. O TDD guia o design completamente.

  • Outside-In (escola de Londres, de cima para baixo ou "mockist TDD" como Martin Fowler chamaria isso: você sabe sobre as interações e os colaboradores de antemão (especialmente aqueles nos níveis mais altos) e começa lá (nível superior), zombando das dependências necessárias. Com cada componente finalizado, você se move para os colaboradores que já foram burlados e começa com o TDD novamente, criando implementações reais (que, embora usadas, não eram necessárias antes, graças a abstrações ). Note que a abordagem outside-in combina bem com o princípio YAGNI .

Nenhuma das abordagens é a única e ; ambos têm o seu lugar dependendo do que você faz. Em grandes soluções corporativas, onde partes do design vêm de arquitetos (ou existem de antemão), pode-se começar com a abordagem "estilo londrino". Por outro lado, quando você se depara com uma situação em que não tem certeza de como seu código deve parecer (ou como ele deve se encaixar em outras partes do sistema), pode ser mais fácil começar com algum componente de baixo custo e deixá-lo evoluir à medida que mais testes, refatorações e requisitos forem introduzidos.

O que você usa, geralmente é situacional.

Para ler mais, há postagem do grupo do Google com uma discussão bastante interessante sobre como essa distinção (pode ter) se originou e porque Londres pode não ser o nome mais apropriado.

    
por 27.09.2012 / 13:48
fonte
15

Resposta curta: Como de costume, depende de sua preferência de codificação e abordagem de equipe.

A codificação

Inside out é ótima porque você sempre tem algo funcionando. A desvantagem é que isso não necessariamente ajuda você a chegar a um lugar radicalmente diferente. É mais difícil traçar um curso dessa maneira. Da mesma forma, escrever código fora em tem o lado negativo de não necessariamente ter o benefício de desenvolvimento iterativo rápido e não necessariamente ver todas as oportunidades e padrões que podem surgir da profundidade da estrutura do código. / p>

Cheguei a acreditar que os dois estilos de desenvolvimento são importantes e que, de fato, é útil ter uma mistura de estilos em uma equipe. A ideia é que o interior é ótimo para criar blocos de construção, e o exterior em pensamento fornece estrutura e direção de forma.

Parte do meu raciocínio vem de uma escola de pensamento muito popular que atualmente promove o desenvolvimento iterativo, que é frequentemente sinônimo de desenvolvimento avesso. Eu acredito que o desenvolvimento iterativo é ótimo quando você não tem muito para onde ir. Mas eu acho que pensar em grande figura, ao contrário de um processo puramente iterativo, é inestimável para certos tipos de inovação e para chegar a um lugar menos óbvio. Corretamente gerenciado, dentro e fora em conjunto pode ser uma combinação muito eficaz.

    
por 27.09.2012 / 13:35
fonte
8

Você deve adicionar Agile Prinicples, Patterns and Practices em C # a essa lista. Eu não sei porque ele colocou "C #" no final. Os livros não são a língua em tudo e a única razão pela qual não conseguiu 5 estrelas na Amazon é de pessoas que ficaram desapontadas com o C # de seus exemplos.

O autor defende que, sempre que possível, você deve tentar escrever código de fora para dentro e confiar strongmente no design evolucionário, e eu concordo com a afirmação dele. Seu raciocínio é que, à medida que adicionamos funcionalidade, nosso design sempre evoluirá. Se começarmos com componentes de baixo nível à medida que os recursos forem adicionados, perceberemos que esses componentes não estão fazendo o que gostaríamos que eles fizessem, ou que as coisas precisam ser movidas. Isso pode ficar bastante caro, especialmente se, toda vez que você mudar a funcionalidade de uma classe para outra, você precisa fazer o mesmo em todos os projetos de teste de unidade.

Por outro lado, se você determinar o que seu aplicativo deve fazer, você codifica a interface externa. À medida que os recursos são adicionados e o código sob teste aumenta de tamanho, você refatora seu aplicativo em mais classes, mas enquanto esse esforço de refatoração continua, os testes de unidade originais que você escreveu permanecem válidos. Então você começa completamente do lado de fora e continua a refatorar em mais e mais classes de baixo nível, enquanto adiciona testes de unidade adicionais àquelas classes internas, mas você raramente teria que se movimentar e reescrever seus testes de unidade.

No entanto, se você identificar um subsistema de baixo nível específico que seu aplicativo precisará (e talvez sua empresa já precise desses subsistemas em outros aplicativos), esse seria o momento de começar com um bloco de construção de baixo nível primeiro e depois construir o aplicativo em cima disso.

    
por 27.09.2012 / 16:18
fonte
7

A meu ver, o conceito de desenvolvimento Outside-in realmente se espalha em dois níveis. Gerard Meszaros brevemente descreve-os como "design externo " e "fora -in / inside-out codificação ".

  • O primeiro nível é um nível organizacional e de processo. O design externo é feito em oposição a top-down (waterfall / taylorist) e bottom-up. Com uma abordagem externa, nos concentramos na perspectiva do usuário final. Começamos com testes de história, testes de ATDD ou BDD e vamos "para dentro", inferindo testes técnicos e código. Portanto, o design externo geralmente é o que você faria em um contexto Ágil. Dan North tem uma ótima conversa sobre as abordagens BDD, top-down, bottom-up e outside-in.

  • O segundo nível é técnico e tem a ver com camadas aplicativas. A codificação Outside-in basicamente significa partir da UI e ir para dentro da camada central (normalmente a camada business / domain). É feito em oposição à codificação de dentro para fora que começa na camada central e codifica as camadas externas por último.

Assim, você pode ter um design externo com codificação externa ou codificação de dentro para fora.

Onde não concordo com Meszaros é quando ele associa codificação de dentro para fora com testes de integração, argumentando que, em um contexto de dentro para fora, "na verdade, não testamos o software externo isoladamente do software interno". Mas acredito que nada impede que você faça isso. Você pode escolher perfeitamente testar seus objetos da camada externa zombando dos objetos da camada interna, mesmo se o código de produção para esses já existir. Você só precisa adicionar interfaces e mocks sobre os objetos concretos existentes em vez de escrever as interfaces, zombando delas e depois criando as implementações mais tarde, como faria com a codificação externa.

Em outras palavras, o estilo mockista ou classicista TDD é uma preocupação ortogonal com a codificação de dentro para fora / para fora. Você pode perfeitamente usar um estilo mockista junto com uma abordagem de dentro para fora. A razão por trás disso é que o estilo mockista / classicista é sobre o código dependências enquanto a codificação fora-dentro / dentro-fora é sobre camadas do aplicativo .

Outra coisa importante é que as dependências não são apenas entre camadas, elas também existem entre objetos na mesma camada. Por exemplo, você pode querer começar com um objeto em sua camada central de negócios (abordagem de dentro para fora) e usar mocks para isolar seu objeto de outros objetos da camada de negócios com os quais ele fala. Isso acontece muito com o IoC - as abstrações das quais seu objeto depende são frequentemente declaradas na mesma camada, mas as implementações concretas estão em uma camada diferente.

Robert "Uncle Bob" Martin menciona brevemente a codificação de dentro para fora e como isso não entra necessariamente em conflito com uma arquitetura desacoplada em seu post " Arquitetura Limpa ".

    
por 28.09.2012 / 01:04
fonte