|
Asas-Torne os testes unitários inteligentes e totalmente automatizadosprefácio Testes unitários são um meio muito eficaz para garantir a qualidade do software, seja do ponto de vista do conceito de intervenção precoce nos testes ou das características dos testes unitários que podem ser verificados em alta velocidade sem serem afetados pela interface, então o desenvolvimento orientado a testes defendido pela indústria, o driver de teste mencionado aqui refere-se mais ao driver de teste unitário. No entanto, a equipe geral de desenvolvimento ainda raramente executa testes unitários de forma sistemática, e o teste para software de aplicação é mais realizado por equipes profissionais de teste para realizar testes caixa-preta. A maior dificuldade dos testes unitários não é que a entrada e a saída não possam ser determinadas, afinal, já estão determinadas na fase de desenvolvimento do módulo, mas que a escrita dos casos de teste unitário consumirá muitas horas de trabalho dos desenvolvedores e, segundo estatísticas relevantes, o tempo dos casos de teste unitário excederá em muito o tempo de desenvolvimento da própria função. Aqui estão algumas das razões mais comuns pelas quais o desenvolvimento não escreve testes unitários: ●Os requisitos são sempre infinitos, e ainda há requisitos funcionais a serem realizados na próxima etapa, e não há tempo para preencher a unidade ●Há testes unitários demais para serem complementados, e não há como começar, então eu resisto subjetivamente. ● Testes unitários são difíceis de escrever. Por um lado, a razão pode ser que a implementação da função funcional não seja razoável o suficiente, e, por outro, não existem (ou desconhecidos) frameworks úteis de teste unitário e frameworks de mock. ● Testes unitários não estão incluídos na carga de trabalho. Em segundo lugar, os requisitos funcionais ainda são instáveis, e o custo de escrever testes unitários não é alto. Em outras palavras, se os requisitos mudarem amanhã, não só o código funcional será descartado, mas também os testes unitários. Se você não escrever testes unitários, essa parte do esforço não será em vão. Na verdade, a causa raiz dos pontos acima é que a escrita dos testes unitários é muito demorada, o que eventualmente leva à perda de potência do motor pilotado por testes, fazendo com que a bela visão do desenvolvimento guiado por testes fique paralisada no cenário real, porque é difícil e caro demais construir o motor para essa condução. As várias unidades "x" no mercado e frameworks de testes unitários apenas resolvem o problema de gerar quadros externos orientados a testes, sem qualquer lógica de casos de uso e capacidades de geração de dados baseadas em um entendimento profundo do programa. Portanto, isso torna os desenvolvedores resistentes a vários cenários relacionados ao desenvolvimento. O lançamento do Wings (atualmente para C) resolve um dos maiores problemas para os programadores e tem o potencial de mudar fundamentalmente o status quo dos testes unitários, o que efetivamente aliviará a pressão dos testes caixa-preta em nível de sistema e testes automatizados baseados em enormes recursos humanos. Os casos de teste de restrições são gerados automaticamente por programas, e a tecnologia subjacente mais crítica é a de análise de parâmetros complexos. Ou seja, pode definir arbitrariamente a análise recursiva em nível aninhado no nível do compilador para tipos arbitrariamente complexos. Sem esse avanço nessa tecnologia crítica, o sistema automático de geração de casos de teste seria comercialmente incapaz ou evoluiria para produzir dados de teste compatíveis com eficiência muito baixa. Por exemplo, a famosa ferramenta de fuzzing American Fuzzy Lop não consegue identificar o tipo de estrutura exigida pelo programa do usuário e precisa evoluir o algoritmo de busca com base na camada mais externa. As características do programa são que a entrada no nível da interface e os requisitos de dados de um módulo interno estão distantes, e os dados externos geralmente são transformados camada por camada de transformação complexa para se tornar o tipo de estrutura de dados exigido pelo módulo interno, então a quantidade de computação e tempo necessários para explorar a partir da camada externa será inimaginável. Baseado no Fuzzy Lop americano, para poder gerar uma declaração SQL legítima, o módulo interno do programa precisa ser explorado em dias, longe de ser minutos ou horas. Outra restrição é que as entradas que cada programa pode assumir são dados cuidadosamente estruturados e compilados, com um grande número de regras, e é muito irrealista e extremamente demorado gerar esses dados por métodos aleatórios + exploratórios. Portanto, não é viável gerar casos de uso gerados automaticamente a partir da caixa-preta e da entrada mais externa. Se o caso de uso orientado for gerado a partir da análise da estrutura interna do software, é necessário ter um entendimento profundo da estrutura de compilação do software. Um sistema viável de geração de casos de teste deve ser baseado no meio do programa (ponto de entrada da chave) como o ponto de entrada mais apropriado. As entradas desses módulos transformaram entradas difusas em parâmetros altamente estruturados. Desde que essas estruturas complexas possam ser identificadas, os tipos de dados complexos possam ser degradados em tipos simples passo a passo, e a construção dos parâmetros possa ser concluída ao mesmo tempo, a geração de casos de uso de condução pode ser concluída automaticamente. Testes baseados em módulos, que podem ser classificados como testes unitários tradicionais, são a melhor forma de encontrar e conter defeitos na fase de P&D. No entanto, devido às limitações dos testes unitários, um grande número de drivers precisa ser desenvolvido, e a promoção e aplicação na indústria são bastante limitadas. Claro, testes unitários também podem ser executados após a integração do sistema para evitar a construção de programas virtuais stub. O produto Wings da Nebulas Testing, lançado no mundo pela primeira vez há alguns dias, é um sistema inteligente e totalmente automatizado de geração de casos de teste unitário, que estudou e resolveu as seguintes dificuldades, e agora é compartilhado com você. (1) Análise aprofundada dos parâmetros do programa O Wings utiliza a tecnologia subjacente do compilador para formar objetos de módulo com base no arquivo fonte de entrada de acordo com a função. O objeto contém os parâmetros de entrada da função, o tipo de valor de retorno e outras informações, que podem ser usadas pelo módulo de função driver e pelo módulo de casos de teste. Cada arquivo é uma unidade que realiza uma análise aprofundada de cada parâmetro de cada função nela, e pode realizar análise e decomposição precisas para tipos aninhados, tipos complexos, etc., explicar tipos complexos camada por camada como tipos básicos de dados e gerar um arquivo de descrição (PSD) da estrutura de parâmetros. (2) Geração automática de módulos por acionamento de funções De acordo com as informações de formato do arquivo PSD, todas as funções do driver do programa fonte em teste são geradas automaticamente, e o processo de teste unitário não depende mais dos desenvolvedores para escreverem manualmente as funções de teste, mas apenas precisa compilar as funções geradas do driver e os arquivos-fonte em teste juntos, e os resultados do teste podem ser executados e os resultados do teste podem ser visualizados. O driver de teste gera automaticamente o programa com base na descrição do PSD, constrói automaticamente todos os parâmetros e variáveis globais necessárias que conduzem o teste em teste, e pode gerar um driver de teste estruturado de acordo com a hierarquia de variáveis complexas, o que pode economizar muito tempo na escrita de casos de teste unitário. (3) Geração e gerenciamento automáticos de dados de teste Ele é usado para gerar automaticamente dados de teste, que correspondem às informações extraídas pela função de teste, e os dados são armazenados em um arquivo JSON com uma certa relação lógica hierárquica. Os dados e o tipo de dado após decomposição e expansão correspondem um ao outro. Os usuários podem marginalizar arbitrariamente esses dados de acordo com as necessidades do negócio e usar arquivos JSON para exibi-los de forma estruturada e hierárquica, o que é muito claro. Os dados de teste incluem os valores das variáveis globais e os valores dos parâmetros quando a função sob teste é chamada. O Wings fornece um método de teste unitário para gerar automaticamente funções de driver, que inclui principalmente as seguintes etapas: Figura 1: Fluxo de build orientado por testes unitários 1 Extração das informações do programa em testeA informação estrutural do programa sob teste inclui principalmente as variáveis globais e informações de função no programa, e as informações de função incluem principalmente o número de parâmetros, tipos de parâmetros e tipos de valor de retorno da função. O mais importante é extrair as informações de símbolos e tipos de alguns tipos complexos, e analisá-los em tipos básicos camada por camada para completar a construção de variáveis globais e parâmetros de função. Os tipos de variáveis geralmente são divididos em tipos básicos, tipos de construção, tipos de ponteiro e tipos nulos. O Wings utiliza a tecnologia de compilação subjacente para lidar com diferentes tipos de variáveis de maneiras distintas. (1) Tipos básicos, como int sem sinal u_int=20, Wings analisarão o nome da variável para u_int e o tipo de dado para int sem sinal. (2) Tipos de construção, tipos de construção são divididos aproximadamente em arrays, structs, commons e tipos de enumeração. ● Tipo de arranjo, como intarray[2][3], nome do array é array, tipo int e comprimento do array 2D, comportamento 2, coluna 3. ●Tipo de estrutura, para structs como arrays, listas ligadas de struct, etc., diferentes marcadores são divididos. (3) Tipo de ponteiro, por exemplo, int **ptr = 0; , analisa o ponteiro como um ponteiro de nível 2 do tipo int. (4) Tipo nulo, que é resolvido como NULL. (5) Tipos de sistema, como Arquivo, size_t, etc., são marcados como tipos de sistema e serão adicionados ao modelo e atribuídos pelo usuário. (6) Tipo de ponteiro de função, analisar o tipo de valor de retorno, tipo de parâmetro e número de parâmetros da função Para cada unidade de compilação do programa fonte em teste, as informações da função analisada são armazenadas na estrutura PSD correspondente, e os seguintes exemplos de código-fonte são descrevidos:
No programa acima, void StructTypeTest3(myy_struct mm_struct[2])A estrutura PSD salva é a seguinte:
Os significados de cada nó no arquivo PSD são os seguintes: ●StructTypeTest3 representa o nome da função, parmType0 representa o tipo de parâmetro e parmNum representa o número de parâmetros ●mm_struct representa o símbolo do parâmetro da função, baseType1 representa a classificação dos tipos (tipo de dado básico, tipo construção, tipo apontador, tipo nulo), tipo representa tipos específicos, incluindo int, char, short, long, double, float, bool, e esses tipos de tipos sem sinal e outros tipos básicos, e existem alguns tipos especiais como: ZOA_FUN tipo representa o tipo de função, StructureOrClassType representa o tipo de struct, etc., e o nome representa o nome do tipo struct, union e enum ●i_int representa o tipo base, que é a menor unidade de atribuição ●array_one representa o tipo de arranje, RowSize representa o comprimento do array, e o array pode ser dividido em arrays unidimensionais, bidimensionais, etc ●point representa o tipo de ponteiro, o ponteiro é dividido em ponteiro de primeiro nível, ponteiro de segundo nível, etc., e o ponteiro geral é usado como parâmetro de função como um array, assim, para o tipo básico de ponteiro, o método de matriz de alocação dinâmica é usado para atribuir valores, e o usuário pode modificar o arquivo de valores correspondente conforme as necessidades. ● w representa o tipo de campo de bits, e bitfileld representa o número de dígitos ●functionPtr representa o tipo de ponteiro da função, que analisa o tipo de parâmetro, número de parâmetros e informações de valor de retorno, respectivamente ●Dem significa tipo consórcio ● dy representa o tipo de enum, e valor representa o valor do tipo de enum ●file representa o tipo de estrutura, SystemVar representa que essa variável pertence à variável no arquivo cabeçalho do sistema; para esse tipo de variável, o Wings adiciona variáveis template à biblioteca de templates, permitindo que os usuários atribuam valores especiais de acordo com necessidades específicas. Por exemplo, o tipo de arquivo é tratado da seguinte forma:
Os usuários também podem adicionar seus próprios métodos de atribuição. Para tipos de sistema, Wings podem ser distinguidos dos tipos comuns definidos pelo usuário, e ao analisar para o tipo embutido do sistema, pode parar a análise recursiva para baixo. ●g_int representa variáveis globais, e globalType representa variáveis globais ●next representa a estrutura de lista encadeada, e NodeType representa essa estrutura como uma lista encadeada ●returnType representa o tipo de valor de retorno da função. 2 Geração automática de driversNo artigo acima, as informações estruturais das variáveis e funções globais são analisadas e extraídas, e as informações a seguir são usadas para salvar no PSD e completar a geração geral da estrutura de condução do programa fonte em teste. A geração é dividida principalmente nos seguintes aspectos: Ø Declaração das variáveis globais Ø Operação de atribuição dos parâmetros da função, de acordo com o número de parâmetros da função, atribuem valores por sua vez Ø A atribuição das variáveis globais é realizada sequencialmente de acordo com o número de variáveis globais usadas pela análise Ø Chamada da função original Alguns pontos a serem observados são os seguintes: ●Durante o processo de geração do driver, algumas funções especiais, como funções principais, estáticas, etc., não são processadas temporariamente porque não podem ser acessadas pelo mundo exterior. ● Para cada arquivo fonte em teste, um arquivo de driver correspondente é gerado. ● O controle de drive está incluído no Driver_main.cpp para configurar automaticamente o número de testes da função por meio de macros A função driver gerada pelo programa fonte acima é a seguinte: ● Todas as variáveis são nomeadas antes do nome da variável original, adicione _ ●Ao obter os dados de teste correspondentes, as variáveis são atribuídas por sua vez ●Para os parâmetros embutidos do sistema e os parâmetros especiais do usuário, o método de atribuição é configurado uniformemente através do método template. ●Atribuir e chamar parâmetros para a função em teste. 3 Os dados de teste são gerados automaticamenteA seguir, um conjunto de dados gerados no formato PSD na Figura 3, cada conjunto de dados é salvo em formato JSON, facilitando a visualização da relação hierárquica dos dados.
Para cada unidade de compilação, um conjunto de arquivos de dados de teste correspondentes a todas as funções é gerado por padrão, e a geração de valor pode ser modificada pelo número de configurações. 4 MysqlOs resultados dos testes do programa são exibidosComo completar a geração do framework de drivers, a seguir está uma explicação detalhada de todo o processo de geração do programa open source MySQL. A seguir está o diagrama principal da interface do Wings testando o Mysql: Clique no botão Arquivo para definir o diretório do projeto do programa fonte em teste. Após as configurações, clique na operação da função, que inclui principalmente análise de parâmetros, geração de drivers, geração de arquivos de valor e adição de templates. As seguintes pastas são geradas para a análise: Entre eles, o módulo de análise de parâmetros gera FunXml e GlobalXml, que armazenam as informações da função e das variáveis globais de cada unidade de compilação extraída, respectivamente. O módulo de geração de driver será gerado Wings_Projects pasta correspondente, que armazena os arquivos de driver para cada unidade de compilação O módulo de geração de valor armazena os dados de teste gerados para cada unidade de compilação. A figura a seguir mostra as informações da estrutura do arquivo do driver carregadas pelo Mysql, e a árvore de navegação à esquerda é o arquivo do driver gerado, que contém as funções de cada unidade de compilação, bem como os parâmetros e variáveis globais das funções. Clique em uma das unidades de compilação para carregar o arquivo de driver correspondente e o arquivo de valor correspondente. O acima é o arquivo de driver e o arquivo de valores correspondentes à geração geral do Mysql, e o arquivo de driver é descrito em detalhes no código a seguir. ● Para cada unidade de compilação, a referência da variável global é por externo. ●A função do driver é nomeada uniformemente como método Driver_XXX, JSON é usado como forma de obter dados de teste, e vezes representa o número de testes de uma única função. ●Para cada operação de atribuição de parâmetros, o formato de armazenamento PSD analisado é usado para atribuir valores a cada estrutura de camada por sua vez. A aplicação do Wings é muito simples, a seguir está um índice estatístico dos dados de teste gerados usando código Mysql que pode ser compilado normalmente no Visual Studio 2015. Por exemplo, todo o processo de geração não requer intervenção manual, apenas precisa formular o caminho do código-fonte que precisa ser gerado e conduzido. mysqlDados de teste | MysqlVersão | | CNúmero de arquivos de código de idioma | | Tempo necessário para analisar (PSDTempo de geração) | | O tempo necessário para impulsionar a geração | | O valor é gerado pelo tempo que leva para gerá-lo | |
Instruções de configuração do computador: | Sistema Operacional | | | Inter(R) Core(TM) i7-7700cpu 3.60GHz | | | | |
Abaixo estão os resultados obtidos usando a ferramenta de estatísticas do código-fonte, com mais de 4 milhões de linhas de código válido de teste unitário geradas pelo Wings de forma totalmente automática. O que é ainda mais interessante é que pode-se ver que o custo do desenvolvimento manual desses códigos chega a ser de 1.079 meses-homem-homem, e o custo chega a chegar a 10,79 milhões.
O Wings realizou o primeiro passo de exploração do programa para gerar automaticamente o programa, a primeira versão está atualmente lançada, desenvolvedores interessados podem baixá-la diretamente na plataforma Code Cloud (https://gitee.com/teststars/wings_release), licenciamento comercial oferece um período ilimitado de um mês de experiência funcional, você pode rapidamente experimentar o poder mágico do Wings, a versão em linguagem C do Wings suporta múltiplas plataformas, como o Visual Studio, vxworks, gcc, qt, etc. O Wings é projetado e desenvolvido pela equipe de testes (www.teststar.cc) da Nebulas, e desenvolvedores interessados podem entrar em contato com a equipe de testes da Nebulas por meio da plataforma interativa da Codecloud para contribuir com suas ideias de design e feedback sobre uso do produto (para as excelentes sugestões adotadas, a Nebulas pode estender seu período de uso gratuito por pelo menos três meses). O Wings possui um gene forte e subjacente para melhorar significativamente a qualidade do software e, no futuro, o Wings otimizará profundamente a legibilidade de programas escritos automaticamente (mais próximo do nível de escrita de bons programadores) e o suporte para a linguagem C++.
|