Exportar árvore de teste do JMeter para texto

Olá Habr!


Trabalho em um grande projeto de integração (IBM WAS, WebSphere MQ, Oracle) e envolvo nossa sangrenta empresa com uma rede de testes funcionais no JMeter, que é executada em um banco de testes e acorda com a chamada de Jenkins após a implantação de uma nova compilação. À medida que o número de testes aumentou, eu tive o problema de manter a documentação do teste atualizada.


A árvore de teste em si no JMeter é essencialmente um documento - as operações dividem a funcionalidade em partes lógicas, os controladores contêm testes dentro das operações e cada amostrador dentro do controlador é uma etapa separada. A hierarquia dos objetos é claramente numerada, com exceção das peças de serviço, como afirmações, temporizadores e outras coisas menos interessantes do ponto de vista da lógica de negócios.


O resultado é uma imagem bastante precisa:


imagem

No entanto, nem todo gerente está pronto para iniciar o JMeter em casa para ver a situação no campo do controle de qualidade. Historicamente, toda a documentação do projeto é mantida no Confluence.
Eu não estava pronto para copiar manualmente a descrição dos casos de teste para a página Confluence depois de desenvolvê-los no JMeter. A pesquisa desesperada não deu resultado - não encontrei uma solução pronta e fácil para exportar uma árvore de objetos do JMeter para texto ( se houver, escreva sobre isso nos comentários, por favor, e jogarei cinzas na minha cabeça a partir do widget “eu posso google” ).


Tendo examinado o arquivo JMX (a extensão padrão do plano de teste JMeter), descobri que todos os objetos que me interessavam estavam marcados com o atributo testname :


Fatia de arquivo JMX de amostra
<AuthManager guiclass="AuthPanel" testclass="AuthManager" testname="1.4.2   " enabled="true"> <collectionProp name="AuthManager.auth_list"> <elementProp name="" elementType="Authorization"> <stringProp name="Authorization.url">http://${ipKvp}:${portKvp}/TKVPImportTemporary</stringProp> <stringProp name="Authorization.username">${userKvp}</stringProp> <stringProp name="Authorization.password">${passKvp}</stringProp> <stringProp name="Authorization.domain">${domainKvp}</stringProp> <stringProp name="Authorization.realm"></stringProp> </elementProp> </collectionProp> <boolProp name="AuthManager.clearEachIteration">true</boolProp> </AuthManager> 

A única coisa que resta é escrever um analisador, que:


  1. O texto desejado com a descrição da etapa \ test \ group do arquivo JMX
  2. Lança linhas com a descrição de objetos desinteressantes (asserted, timers, etc.)
  3. Ele gravará tudo em um arquivo para que a atualização do documento inclua um copiar-colar solitário

O parágrafo 1 foi tratado com êxito pela expressão regular:


(? <= nome do teste = \ ") (. *) (? = \")

O reflexo de não usar o xpath adquirido no processo de gravação de seletores para testes do Selenium me impediu de usar o seletor de xpath.


Como não numerei os objetos de serviço na árvore, o item 2 foi implementado sem problemas em um loop no qual:


  • Eu recebo o primeiro caractere da string
  • Trago para int
  • se for bem-sucedido, escreva uma linha na lista
  • caso contrário, ignore
      try (BufferedReader br = new BufferedReader(new FileReader(JMX_FILE))) { String line; while ((line = br.readLine()) != null) { Matcher m1 = p.matcher(line); if (m1.find()) { try { Integer.parseInt(m1.group().substring(0, 1)); matchd.add(m1.group()); } catch (NumberFormatException e) { System.out.println(m1.group().substring(0, 1) + ": excluding non-number string"); } } } } 

E como o arquivo é processado sucessivamente de cima para baixo + a numeração de objetos na árvore segue uma lógica clara, não havia necessidade de inventar algo terrível para o item 3:


  FileWriter writer = null; try { writer = new FileWriter(RESULT_FILE); for (String str : matchd) { writer.write(str + "\n"); } } finally { if (writer != null) { writer.close(); } } 

O resultado final se encaixa em uma classe pequena (~ 50 linhas):


Código fonte
 import java.io.*; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; public class App { private static final String SAMPLER_NAME_REGEXP = "(?<=testname=\")(.*)(?=\" )"; private static final File JMX_FILE = new File("C:\\temp\\Test-plan.jmx"); private static final File RESULT_FILE = new File("C:\\temp\\output.txt"); public static void main(String[] args) throws IOException { Pattern p = Pattern.compile(SAMPLER_NAME_REGEXP); List<String> matchd = new ArrayList<>(); try (BufferedReader br = new BufferedReader(new FileReader(JMX_FILE))) { String line; while ((line = br.readLine()) != null) { Matcher m1 = p.matcher(line); if (m1.find()) { try { Integer.parseInt(m1.group().substring(0, 1)); matchd.add(m1.group()); } catch (NumberFormatException e) { System.out.println(m1.group().substring(0, 1) + ": excluding non-number string"); } } } } if (RESULT_FILE.delete()) { System.out.println("Deleting previous result file"); } else { System.out.println("Creating new result file"); } FileWriter writer = null; try { writer = new FileWriter(RESULT_FILE); for (String str : matchd) { writer.write(str + "\n"); } } finally { if (writer != null) { writer.close(); } } } } 

Como um experimento, tentei integrar esse código diretamente no plano de teste do JMeter, mas tive problemas de entender mal genéricos e importações e decidi ficar satisfeito em ligar para o exportador de árvores resultante no IDEA por enquanto.


Cuide do seu tempo. E obrigado por assistir.


imagem

Source: https://habr.com/ru/post/pt413481/


All Articles