A primeira parte está aqui .
Imagine a situação. Você se depara com a tarefa de desenvolver novas funcionalidades. Você tem desenvolvimentos de seus antecessores. Supondo que você não tenha obrigações morais, o que você faria?
Na maioria das vezes, todas as conquistas antigas são esquecidas e tudo começa de novo. Ninguém gosta de descobrir o código de outra pessoa e, se você tiver tempo, por que não começar a criar seu próprio sistema? Essa é uma abordagem típica e amplamente correta. Mas em nosso projeto, fizemos de errado. Estabelecemos as bases para o futuro sistema de teste automatizado com base em testes de unidade no utPLSQL de nossos antecessores e, em seguida, fomos trabalhar em várias direções paralelas.
- Restaure testes de unidade antigos. Recuperação refere-se à adaptação de testes ao estado existente do sistema de fidelidade e à adaptação de testes aos padrões utPLSQL.
- A solução para o problema da compreensão e o que exatamente, quais métodos e processos, estamos cobertos por autotestes. Você deve manter essas informações em mente ou tirar conclusões com base no próprio código de autoteste. Portanto, decidimos criar um catálogo. Atribuímos um código mnemônico exclusivo a cada autoteste, formamos uma descrição e corrigimos as configurações (por exemplo, sob quais condições ele deve iniciar ou o que deve acontecer se o teste começar a falhar). Essencialmente, preenchemos os metadados sobre os autotestes e os colocamos nas tabelas de esquema utPLSQL padrão.
- Definir uma estratégia de expansão, ou seja, seleção de funcionalidade a ser verificada pelos autotestes. Decidimos prestar atenção a três coisas: novas melhorias no sistema, incidentes de produção e principais processos do sistema. Assim, estamos desenvolvendo em paralelo com o release, oferecendo maior qualidade, expandindo simultaneamente o volume de regressão e garantindo a confiabilidade do sistema em locais críticos. O primeiro gargalo desse tipo foi o processo de distribuição de descontos e bônus em um cheque.
- Naturalmente, começamos a desenvolver novos autotestes. Uma das primeiras tarefas de lançamento foi avaliar o desempenho de amostras predefinidas do sistema de fidelidade. Em nosso projeto, há um bloco de consultas sql rigidamente fixadas que selecionam clientes de acordo com as condições. Por exemplo, obtenha uma lista de todos os clientes cuja última compra foi em uma cidade específica ou uma lista de clientes cujo valor médio de compra esteja acima de um determinado valor. Após autotestes escritos, verificamos as amostras predefinidas, corrigimos os parâmetros de desempenho de referência e, além disso, fizemos testes de carga.
- O trabalho com autotestes deve ser conveniente . Na maioria das vezes, duas ações são executadas: executando autotestes e criando dados de teste. Assim, em nosso sistema, apareceram dois módulos auxiliares: o módulo de inicialização e o módulo de geração de dados.
O iniciador é apresentado como um único procedimento universal com um parâmetro de texto de entrada. Como parâmetro, você pode passar o código mnemônico de autoteste, o nome do pacote, o nome do teste, a configuração de autoteste ou uma palavra-chave reservada. O procedimento seleciona e executa todos os autotestes que atendem às condições.
O módulo de geração de dados é apresentado na forma de um pacote no qual, para cada objeto do sistema em teste (tabela no banco de dados), é criado um procedimento especial que insere dados nele. Neste procedimento, os valores padrão são preenchidos o máximo possível, o que garante a criação de objetos com o clique de um dedo. E para facilitar o uso, foram criados modelos para os dados gerados. Por exemplo, crie um cliente de uma certa idade com um telefone de teste e uma compra perfeita. - Os autotestes devem ser executados em um horário aceitável para o seu sistema. Portanto, foi organizado um lançamento noturno diário, cujos resultados geram um relatório e o enviam para toda a equipe de desenvolvimento por correio corporativo. Após restaurar os autotestes antigos e criar novos, o tempo total de operação foi de 30 minutos. Esse desempenho foi adequado a todos, já que o lançamento ocorreu após o expediente.
Mas tive que trabalhar para otimizar a velocidade do trabalho. A atualização do sistema de fidelidade na produção é feita à noite. Como parte de um dos lançamentos, tive que fazer alterações com urgência à noite. A meia hora de espera pelos resultados dos autotestes às três da manhã não deixou a pessoa responsável pela liberação feliz (saudações ardentes a Alexei Vasyukov!), E na manhã seguinte muitas palavras gentis foram ditas em relação ao nosso sistema. Mas com base nos resultados, foi estabelecido um padrão de trabalho de 5 minutos.
Para acelerar o desempenho, usamos dois métodos: os autotestes começaram a ser executados em três threads paralelos, o que é muito conveniente devido à arquitetura do nosso sistema de fidelidade. E abandonamos a abordagem quando o autoteste não cria dados de teste para si mesmo, mas tenta encontrar algo adequado no sistema. Depois de fazer as alterações, o tempo total de operação foi reduzido para 3-4 minutos. - O projeto com testes automáticos deve poder ser implantado em vários estandes. No início da jornada, houve tentativas de gravar seus próprios arquivos em lotes, mas ficou claro que uma instalação automatizada auto-escrita era um horror completo e voltamos para as soluções industriais. Devido ao fato de o projeto possuir muito código direto (em primeiro lugar, armazenamos o código para autotestes) e muito poucos dados (os principais dados são metadados sobre autotestes), foi muito simples introduzir o Liquibase no projeto.
É uma biblioteca independente de banco de dados de código aberto para rastrear, gerenciar e aplicar alterações no esquema do banco de dados. Gerenciado via linha de comando ou estruturas como o Apache Maven. O princípio de operação do Liquibase é bastante simples. Temos um projeto organizado de uma certa maneira, que consiste em alterações ou scripts que precisam ser lançados no servidor de destino e arquivos de controle que determinam em qual sequência e com quais parâmetros essas alterações devem ser instaladas.
No nível do DBMS, é criada uma tabela especial na qual o Liquibase armazena o log de execução. Cada alteração possui um hash calculado, que é comparado a cada vez entre o projeto e o estado no banco de dados. Graças ao Liquibase, podemos facilmente transferir as alterações de nosso sistema para qualquer circuito. Agora, os autotestes são executados em loops de teste e liberação, bem como em contêineres (loops pessoais de desenvolvedores).

Então, vamos falar sobre os resultados da aplicação do nosso sistema de teste de unidade.
- Obviamente, antes de tudo, estamos convencidos de que começamos a desenvolver um software melhor. Os testes automáticos são executados diariamente e encontram dezenas de erros todos os anos. Além disso, alguns desses erros estão indiretamente relacionados à funcionalidade que realmente queríamos mudar. Há grandes dúvidas de que esses erros foram encontrados pelo teste manual.
- A equipe ganhou confiança de que a funcionalidade específica está funcionando corretamente ... Antes de tudo, diz respeito aos nossos processos críticos. Por exemplo, nos últimos seis meses, não tivemos problemas com a distribuição de descontos e bônus no cheque, apesar das mudanças nos lançamentos, embora nos períodos anteriores erros ocorressem em alguns intervalos
- Conseguimos reduzir o número de iterações de teste. Devido ao fato de os autotestes serem escritos para novas funcionalidades, as análises e os testadores de meio período obtêm um código de melhor qualidade, porque Já foi verificado.
- Parte dos desenvolvimentos dos testes automatizados é usada pelos desenvolvedores. Por exemplo, dados de teste em contêineres são criados usando o módulo de geração de objetos.
- É importante que tenhamos desenvolvido a “adoção” de um sistema de teste automatizado pelos desenvolvedores. Há um entendimento de que isso é importante e útil. E, por experiência própria, posso dizer que isso está longe de ser o caso. Os autotestes devem ser escritos, devem ser mantidos e desenvolvidos, os resultados devem ser analisados e, frequentemente, esses custos de tempo simplesmente não valem a pena. É muito mais fácil ir à produção e lidar com problemas lá. Em nosso lugar, os desenvolvedores se alinham e pedem para cobrir suas funcionalidades com testes automáticos.
O que vem a seguir

Vamos falar sobre os planos de desenvolvimento para o projeto de teste automatizado.
Obviamente, enquanto o sistema de fidelidade da Sportmaster ainda está vivo e continua a se desenvolver, também é possível desenvolver testes automáticos quase infinitamente. Portanto, a principal direção do desenvolvimento é a expansão da área de cobertura.
À medida que o número de autotestes aumenta, o tempo total de seu trabalho aumenta constantemente e teremos que voltar novamente à questão da produtividade. Provavelmente, a solução será aumentar o número de threads paralelos.
Mas esses são caminhos de desenvolvimento óbvios. Se falamos de algo mais não trivial, destacamos o seguinte:
- Atualmente, os autotestes são gerenciados no nível do DBMS, ou seja, você precisa do conhecimento de PL / SQL para funcionar com sucesso. Se necessário, controle o sistema (por exemplo, iniciando ou criando metadados), você pode criar algum tipo de painel de administração usando Jenkins ou algo semelhante.
- Todo mundo adora indicadores quantitativos e qualitativos. Para testes automatizados, essa métrica universal é Cobertura de código ou métricas de cobertura de código. Usando esse indicador, podemos determinar qual porcentagem do código do nosso sistema de teste é coberta por autotestes. A partir da versão 12.2, o Oracle fornece a capacidade de calcular essa métrica e sugere o uso do pacote padrão DBMS_PLSQL_CODE_COVERAGE.
Nosso sistema de autoteste tem pouco mais de um ano e talvez agora seja a hora de avaliar a cobertura. No meu projeto passado (um projeto não da Sportmaster) aconteceu. Um ano depois de trabalhar em autotestes, a gerência estabeleceu uma meta para avaliar qual porcentagem do código que cobrimos. Com cobertura superior a 1%, a gerência ficaria feliz. Nós, os desenvolvedores, esperávamos um resultado de cerca de 10%. A cobertura do código parafusado, medida, recebeu 20%. Para comemorar, fomos para um prêmio, mas como fomos para ele e para onde fomos depois é uma história completamente diferente. - Os testes automáticos podem verificar os serviços da Web expostos. O Oracle permite que você faça isso, e não encontraremos mais vários problemas.
- E, é claro, nosso sistema de teste automatizado pode ser aplicado em outro projeto. Nossa solução é universal e requer apenas o uso do Oracle. Ouvi dizer que em outros projetos da Sportmaster há interesse em testes automáticos e, talvez, iremos a eles.
Conclusões
Vamos resumir. No projeto, o sistema de fidelidade no Sportmaster conseguiu implementar um sistema de teste automatizado. Sua base é a solução utPLSQL de Stephen Feuerstein. Em torno do utPLSQL estão o código de autoteste e os módulos auto-escritos auxiliares: módulo de inicialização, módulo de geração de dados e outros. Os testes automáticos são executados diariamente e, mais importante, funcionam e trazem benefícios. Estamos convencidos de que começamos a lançar software de qualidade superior. Ao mesmo tempo, a solução resultante é universal e pode ser aplicada livremente em qualquer projeto em que seja necessário organizar testes automatizados no Oracle DBMS.
PS Este artigo não é muito específico: há muito texto e quase nenhum exemplo técnico. Se o tópico for globalmente interessante, estamos prontos para continuar e retornar com uma continuação, onde informaremos o que mudou nos últimos seis meses e daremos exemplos de código.
Escreva comentários se houver pontos nos quais vale a pena focar no futuro ou perguntas que exijam divulgação.