terça-feira, 8 de abril de 2014

Processo de desenvolvimento de software de maneira simples

Fala pessoal tudo bem? Hoje vou ser bem clássico pois vou falar de um assunto que envolve parte seu conhecimento universitário e parte o seu conhecimento na prática. Para aqueles que só tem a teoria eu recomendo a prática e para os analistas desenvolvedores da prática eu recomendo uma pausa para a leitura de hoje que é sobre o "processo de desenvolvimento de sofware".

Ok mas como eu defino o processo de desenvolvimento de software?


O processo de desenvolvimento de software é entre outras definições um conjunto de ações parcialmente ordenadas, com a finalidade de obter um sistema informatizado. Ele é estudado principalmente na área de Engenharia de Software, sendo considerado um dos principais mecanismos para a entrega de um sistema coeso que atenda as necessidades de seus usuários. A qualidade e velocidade para entregar um software é determinante dentro dos estudos da engenharia de software, mas não se engane ela não é uma métrica exata.

Dentro do processo do desenvolvimento de software existem diversas etapas e vou falar um pouquinho de cada uma que são:

1 - Análise de requisitos
2 - Especificação
3 - Arquitetura de Software
4 - Implementação
5 - Testes


OBS: Saiba que com o movimento ágil utilizando SCRUM e XP esse processo não necessáriamente é tão burocrático pois o manifésto agil prega a agilidade (Recomendo fortemente essa leitura aqui sobre o manifesto agil).


Ainda assim o processo clássico não será descartado e vamos mostrar suas responsabilidades.


1 - Análise de requisitos

Quando se trata do entendimento dos requisitos para um sistemas sendo uma parte importante do processo de projeto de sistemas, no qual o analista de negócio, aliado com outros participantes de software identificam as necessidade ou requisitos de um usuario. 
Uma vez que os requisitos do sistema tenham sido identificados, os projetistas de sistema (entenda-se o carinha que vai pensar no business) estarão preparados para projetar a solução.
Existe a divisão de requisitos sendo Requisito funcional e Requisito não-funcional, esta parte do processo o analista faz as primeiras entrevistas com os clientes e/ou usuários do software para conhecer as funcionalidades do sistema que será desenvolvido. Mas atenção é aqui que acontece a maior parte dos erros, pois a falta de experiência dos clientes ou usuários faz com que eles nem sempre tenham claro em sua mente quais funcionalidades o software necessita.

A grande questão da analise de requisitos é: como como saber se as necessidades do domínio do sistema foi captada? O objetivo dessa fase é justamente levantar os requisitos e garantir o amadurecimento deles, gosto muito de adicionar o básico diagrama de classes da UML nessa fase pois pelo menos eu consigo ter algo "palpavel" rsrs. Pois bem já deu para perceber que essa fase é imprescindível não é? E depois disso como eu começo a pensar no meu "ecosistema"?.


2 - Especificação

A especificação é a definição do que se espera que um software faça. Ela pode ser informal, neste caso ela pode ser considerada como um blueprint ou manual de usuário do ponto de vista do desenvolvedor, ou formal, no caso de ela ser definida principalmente em termos matemáticos ou programáticos.

Na prática, as especificações mais bem sucedidas são escritas para a compreensão e ajustes em uma aplicação que já se encontra bem desenvolvida, embora sistemas de sistemas de segurança críticos sejam cuidadosamente especificados antes do desenvolvimento da aplicação. Especificações são mais importantes para interfaces externas que devem permanecer estáveis. Aqui na especificação é que acontece o tão "famoso" prototípo que costumam chamar de fase de prototipação, sinceramente não curto muito essa montagem "coxinha" da especificação pois na minha opinião usando UML e criando pequenos wireframes já conseguimos abordar muita coisa, e como eu disse antes as coisas devem ser feitas em pequenos trechos, imagine que vc vá desenvolver um e-commerce vão não vai especificar TUDO não é? melhor começarmos pelo catalogo, depois carrinho, logística do armazém e etc, assim garantimos mais exatidão na hora da entrega :D.


3 - Arquitetura de Software

A arquitetura de software é a fase que o desenvolvedor da as cartas, claro que se pensarmos no Domain Driven Design o desenvolvedor participa de TUDO, mas veja bem, é aqui que ele decide os componentes de software, sua regras básicas internas, suas propriedades externas, e seus relacionamentos com outros softwares. Essa fase tem como objetivo manter o sistema organizado no quesito estrutural e comportamental, garantindo que os dados tratados pelo software tenham comportamento coeso e definido, permitindo também mudanças lógicas sem afetar seu funcionamento. A arquitetura de software é necesserária para definir padrões e o design de uma aplicação, é aqui por exemplo que iriamos falar de Hexagonal Architecture, mas não vou falar sobre isso hoje pois eu me alongaria muito e tbm n tenho conhecimentos soloidos sobre isso rs.

Vou pegar um trecho que escrevi no segundo ano da faculdade sobre a arquitetura de software (que trabalho para copiar do caderno kkkkkk)
"O campo da ciência da computação tem lidado com problemas associados, como a complexidade da informação, desde sua criação. Os primeiros problemas de complexidade foram resolvidos pelos desenvolvedores através da escolha da estrutura de dados, do desenvolvimento de algoritmos e pela aplicação de conceitos de separação de escopos. Embora o termo arquitetura de software seja relativamente novo na indústria, os princípios fundamentais deste campo vêm sendo aplicados esporadicamente pela engenharia de software desde o início dos anos 80. As primeiras tentativas de capturar e explicar a arquitetura de software do sistema foram imprecisas e desorganizadas – freqüentemente caracterizadas por um conjunto de diagramas. Durante o decorrer da década de 90 houve um esforço concentrado para definir e codificar os aspectos fundamentais desta disciplina. Inicialmente um conjunto de padrões de projeto, estilo, melhores práticas, descrição de linguagens, e lógica formal foram desenvolvidas durante este período."


4 - Implementação

Analistas falem o que for essa é a parte mais PICA de todas, todo software é escrito em uma linguagem de programação, embora seja possível, com alguma dificuldade, escrevê-lo diretamente em linguagem de máquina. Diferentes partes de um programa podem ser escritas em diferentes linguagens, diferente do que o processo de software comum prega nessa fase também testamos o nosso código como prega o processo TDD 
"TDD é o desenvolvimento de software orientado a testes. Entenda mais detalhes e como usá-lo! TDD é o desenvolvimento de software orientado a testes, ou em inglês, Test Driven Development. Mas mais do que simplesmente testar seu código, TDD é uma filosofia, uma cultura.".

Diferentes linguagens de programação funcionam de diferentes modos. Por esse motivo, os programadores podem criar programas muito diferentes para diferentes linguagens; muito embora, teoricamente, a maioria das linguagens possa ser usada para criar qualquer programa.
Há várias décadas se debate se a programação é mais semelhante a uma arte (Donald Knuth), a uma ciência, à matemática (Edsger Dijkstra), à engenharia (David Parnas), ou se é um campo completamente novo. Ao meu ver desenvolvimento é uma mescla de arte com engenharia mas isso é minha opinião.

Para alguma tecnologias OPEN SOURCE o desenvolvedor precisa fazer tudo, TUDO mesmo, subir ambiente, banco de dados, então eu acredito que essa fase precisa de MUITA mas muita atenção e cuidado.

5 - Testes

O teste de software é a maneira de verificar a qualidade do fotware em relação ao contexto em que ele deve operar. Isso inclui o processo de utilizar o produto para encontrar seus defeitos.
O teste é um processo realizado pelo testador de software, que abrange outros processos da engenharia de software, e que envolve ações que vão do levantamento de requisitos até a execução do teste propriamente dito.
Segundo a DEVMEDIA:
Teste de software é o processo de execução de um produto para determinar se ele atingiu suas especificações e funcionou corretamente no ambiente p$paymentFormara o qual foi projetado. O seu objetivo é revelar falhas em um produto, para que as causas dessas falhas sejam identificadas e possam ser corrigidas pela equipe de desenvolvimento antes da entrega final. Por conta dessa característica das atividades de teste, dizemos que sua natureza é “destrutiva”, e não “construtiva”, pois visa ao aumento da confiança de um produto através da exposição de seus problemas, porém antes de sua entrega ao usuário final” 

Existem alguns conceitos básicos associados ao teste de software que são: defeito, erro e falha.
A figura 1 expressa a diferença entre esses conceitos. Defeitos fazem parte do universo físico (a aplicação propriamente dita) e são causados por pessoas, por exemplo, através do mal uso de uma tecnologia. Defeitos podem ocasionar a manifestação de erros em um produto, ou seja, a construção de um software de forma diferente ao que foi especificado (universo de informação). Por fim, os erros geram falhas, que são comportamentos inesperados em um software que afetam diretamente o usuário final da aplicação (universo do usuário) e pode inviabilizar a utilização de um software.

Existem alguns conceitos bem conhecidos de teste que são;

A - Caixa Branca
Também chamada de teste estrutural ou orientado à lógica, a técnica de caixa-branca avalia o comportamento interno do componente de software. Essa técnica trabalha diretamente sobre o código fonte do componente de software para avaliar aspectos tais como: teste de condição, teste de fluxo de dados, teste de ciclos, teste de caminhos lógicos, códigos nunca executados.
Os aspectos avaliados nesta técnica de teste dependerão da complexidade e da tecnologia que determinarem a construção do componente de software, cabendo portanto avaliação de mais aspectos que os citados anteriormente. O testador tem acesso ao código fonte da aplicação e pode construir códigos para efetuar a ligação de bibliotecas e componentes. Este tipo de teste é desenvolvido analisando o código fonte e elaborando casos de teste que cubram todas as possibilidades do componente de software. Dessa maneira, todas as variações relevantes originadas por estruturas de condições são testadas.
Um exemplo bem prático desta técnica de teste é o uso da ferramenta livre JUnit para desenvolvimento de classes de teste para testar classes ou métodos desenvolvidos em Java. Também se enquadram nessa técnica testes manuais ou testes efetuados com apoio de ferramentas para verificação de aderência a boas práticas de codificação reconhecidas pelo mercado de software. A aderência a padrões e boas práticas visa principalmente a diminuição da possibilidade de erros de codificação e a busca de utilização de comandos que gerem o melhor desempenho de execução possível. Apesar de muitos desenvolvedores alegarem que não há ganhos perceptíveis com essa técnica de teste aplicada sobre unidades de software, devemos lembrar que, no ambiente produtivo, cada programa pode vir a ser executado milhares ou milhões de vezes em intervalos de tempo pequenos. É na realidade de produção que a soma dos aparentes pequenos tempos de execução e consumo de memória de cada programa poderá levar o software a deixar de atender aos objetivos esperados. A técnica de teste de caixa-branca é recomendada para as fases de teste de unidade e teste de integração, cuja responsabilidade principal fica a cargo dos desenvolvedores do software, que por sua vez conhecem bem o código fonte produzido.

B - Caixa Preta
Também chamada de teste funcional, orientado a dado ou orientado a entrada e saída, a técnica de caixa-preta avalia o comportamento externo do componente de software, sem se considerar o comportamento interno do mesmo.4 Dados de entrada são fornecidos, o teste é executado e o resultado obtido é comparado a um resultado esperado previamente conhecido. Como detalhes de implementação não são considerados, os casos de teste são todos derivados da especificação.
Quanto mais entradas são fornecidas, mais rico será o teste. Numa situação ideal todas as entradas possíveis seriam testadas, mas na ampla maioria dos casos isso é impossível. Outro problema é que a especificação pode estar ambígua em relação ao sistema produzido, e como resultado as entradas especificadas podem não ser as mesmas aceitas para o teste. Uma abordagem mais realista para o teste de caixa-preta é escolher um subconjunto de entradas que maximize a riqueza do teste. Pode-se agrupar subconjuntos de entradas possíveis que são processadas similarmente, de forma que testar somente um elemento desse subconjunto serve para averiguar a qualidade de todo o subconjunto. Por exemplo, em um sistema que aceita um inteiro como entrada, testar todos os casos possíveis pode gerar pelo menos dezenas de milhares de casos de testes distintos. Entretanto, a partir da especificação do sistema, pode-se encontrar um subconjunto de inteiros que maximizem a qualidade do teste. Depende do propósito do sistema, mas casos possíveis incluem inteiros pares, inteiros ímpares, zero, inteiros positivos, inteiros negativos, o maior inteiro, o menor inteiro.

Essa técnica é aplicável a todas as fases de teste – teste unitário, teste de integração, teste de sistema e teste de aceitação. A aplicação de técnicas de teste leva o testador a produzir um conjunto de casos de teste (ou situações de teste). A aplicação combinada de outra técnica – técnica de particionamento de equivalência (ou uso de classes de equivalência) permite avaliar se a quantidade de casos de teste produzida é coerente. A partir das classes de equivalência identificadas, o testador construirá casos de teste que atuem nos limites superiores e inferiores destas classes, de forma que um número mínimo de casos de teste permita a maior cobertura de teste possível.
Uma abordagem no desenvolvimento do teste de caixa-preta é o teste baseado na especificação, de forma que as funcionalidades são testadas de acordo com os requisitos. Apesar de necessário, esse tipo de teste é insuficiente para identificar certos riscos num projeto de software

C - Unitários

Fase em que se testam as menores unidades de software desenvolvidas (pequenas partes ou unidades do sistema). O universo alvo desse tipo de teste são as subrotinas ou mesmo pequenos trechos de código. Assim, o objetivo é o de encontrar falhas de funcionamento dentro de uma pequena parte do sistema funcionando independentemente do todo. Para as linguagens de programação mais sofisticadas existem os chamados frameworks xUnit, criados com o intuito de facilitar e padronizar os testes de unidade, normalmente o prefixo é substituido por alguma identificação da linguagem como por exemplo PhpUnit para PHP, jUnit para java, entre tantos outros, fornecem a estrutura para os testes e também podem criar métricas de cobertura de teste.


D - Teste de Integração
Na fase de teste de integração, o objetivo é encontrar falhas provenientes da integração interna dos componentes de um sistema. Geralmente os tipos de falhas encontradas são de transmissão de dados. Por exemplo, um componente A pode estar aguardando o retorno de um valor X ao executar um método do componente B; porém, B pode retornar um valor Y, gerando uma falha. Não faz parte do escopo dessa fase de teste o tratamento de interfaces com outros sistemas (integração entre sistemas). Essas interfaces são testadas na fase de teste de sistema, apesar de, a critério do gerente de projeto, estas interfaces podem ser testadas mesmo antes de o sistema estar plenamente construído.

E - Teste de Sistema
Na fase de teste de sistema, o objetivo é executar o sistema sob ponto de vista de seu usuário final, varrendo as funcionalidades em busca de falhas em relação aos objetivos originais. Os testes são executados em condições similares – de ambiente, interfaces sistêmicas e massas de dados – àquelas que um usuário utilizará no seu dia-a-dia de manipulação do sistema. De acordo com a política de uma organização, podem ser utilizadas condições reais de ambiente, interfaces sistêmicas e massas de dados.

F - Teste de Aceitação
Geralmente, os testes de aceitação são realizados por um grupo restrito de usuários finais do sistema, que simulam operações de rotina do sistema de modo a verificar se seu comportamento está de acordo com o solicitado. Teste formal conduzido para determinar se um sistema satisfaz ou não seus critérios de aceitação e para permitir ao cliente determinar se aceita ou não o sistema. Validação de um software pelo comprador, pelo usuário ou por terceira parte, com o uso de dados ou cenários especificados ou reais. Pode incluir testes funcionais, de configuração, de recuperação de falhas, de segurança e de desempenho.


Pois bem amiguinho,  basicamente o desenvolvimento de software segue esses processos, dúvidas, sugestões ou críticas é só falar!