Ma n u a l d e E n s a i o d e P r o fi c i ê n c i a e m R od ad ......Ma n u a l d e E n s a i o...

25
Manual de Ensaio de Proficiência em Software Rodada 002 Sumário Introdução 2 Procedimentos de Recebimento e Verificação do Pacote de Ensaio 2 Visão Geral da Metodologia 3 Elementos do Ensaio de Proficiência 4 Procedimento de Entrega dos Resultados 7 Exemplo do Procedimento de Ensaio 8 Execução de Testes com o JUnit 8 Execução de Testes de Mutação com o PIT 10 Informações sobre o pacote a ser analisado 17 ANEXO A - Classe Share.java 19 ANEXO B - Exemplos de casos de teste 21 1

Transcript of Ma n u a l d e E n s a i o d e P r o fi c i ê n c i a e m R od ad ......Ma n u a l d e E n s a i o...

  • Manual de Ensaio de Proficiência em Software

    Rodada 002

    Sumário

    Introdução 2

    Procedimentos de Recebimento e Verificação do Pacote de Ensaio 2

    Visão Geral da Metodologia 3

    Elementos do Ensaio de Proficiência 4

    Procedimento de Entrega dos Resultados 7

    Exemplo do Procedimento de Ensaio 8

    Execução de Testes com o JUnit 8

    Execução de Testes de Mutação com o PIT 10

    Informações sobre o pacote a ser analisado 17

    ANEXO A - Classe Share.java 19

    ANEXO B - Exemplos de casos de teste 21

    1

  • Manual de Ensaio de Proficiência em Software

    Rodada 002

    1. Introdução Ensaios de proficiência e comparações interlaboratoriais são mecanismos de avaliação de desempenho de laboratórios. São organizadas através de rodadas e usados para: (1) identificar problemas de ensaio e medição; (2) comparar métodos e procedimentos; (3) gerenciar materiais de referência, e; (4) satisfazer interesses de organismos reguladores e de acreditação.

    Esta é uma rodada de comparação interlaboratorial e foi desenvolvida para avaliar a competência de laboratórios que realizam avaliação da conformidade de software e permitir alinhamento técnico entre os mesmos. Para realizar esta rodada, será adotado como item de ensaio um software de código aberto, o mesmo utilizado na rodada anterior, porém serão utilizadas medidas diferentes como mecanismo de avaliação, para avaliar a qualidade dos testes desenvolvidos pelos laboratórios. Deste modo, o laboratório (participante) deve demonstrar a competência em analisar o código, projetar e desenvolver casos de teste que definam o menor e melhor conjunto de entradas que maximizem a capacidade desses casos de testes de encontrar a inserção intencional de pequenos defeitos. O objetivo deste manual é auxiliar o participante quanto ao entendimento do pacote de ensaio (incluindo o item de ensaio, ferramentas, arquivos necessários e auxiliares) e quanto aos procedimentos de recebimento do pacote e de entrega das respostas.

    2. Procedimentos de Recebimento e Verificação do Pacote de Ensaio Previamente à data de início desta rodada, o participante teve acesso ao link para o download do Protocolo Técnico. Conforme orientado, o participante deverá verificar a sua integridade, comparando seu valor de hash (SHA-256) com o valor disponibilizado a seguir:

    F973CAFB137C4DC822E5647ADA24069E2EFFA8138DB0EE6CA408DA268AC2E85C

    Caso os valores sejam diferentes, sugerimos que refaça o download do pacote e repita o procedimento de verificação do valor de hash. Caso o resultado divergente permaneça, sugerimos que o participante entre em contato com o Comitê de Organização informando o problema, no e-mail [email protected] .

    2

    mailto:[email protected]

  • Manual de Ensaio de Proficiência em Software

    Rodada 002

    3. Visão Geral da Metodologia

    Para essa rodada, o método adotado está relacionado a conceitos do teste de mutação, através do qual pretende-se verificar a qualidade dos testes desenvolvidos pelos participantes. O teste de mutação se baseia na inserção de defeitos no código original para gerar variações que permitam identificar a ausência de entradas para verificar certos pontos de falha que os casos de teste desenvolvidos poderiam ou deveriam revelar. As variações do código original são denominadas mutantes e cada mutante contém apenas uma modificação em relação ao código original.

    As modificações são realizadas considerando-se um conjunto de operadores de mutação, que podem variar de acordo com a linguagem de programação e a ferramenta escolhida para a geração dos mutantes. Os operadores de mutação permitem realizar pequenas modificações sintáticas que simulam pequenos erros cometidos por desenvolvedores durante o processo de desenvolvimento de um software. Todavia, este processo de geração de mutantes é determinístico, ou seja, uma vez escolhido o conjunto de operadores de mutação, sempre serão gerados os mesmo mutantes.

    Quando os casos de teste desenvolvidos para o código original são executados sobre os mutantes e identificam a falha inserida, diz-se que o mutante foi morto, ou seja, os casos de teste desenvolvidos foram suficientes para cobrir as modificações e erros gerados pelos mutantes. Em situações em que os casos de teste são executados sem revelar as falhas inseridas em um mutante, diz-se que o mutante continua vivo, revelando a necessidade de desenvolver novos casos de teste que identifiquem ou cubram aquelas modificações e erros. Quando não for possível gerar ao menos um caso de teste que falhe durante a execução sobre um mutante, então o mutante é considerado equivalente ao código original. Nesta situação o mutante não contribui para a criação de casos de teste.

    Para avaliar a adequação de um conjunto de casos de teste em relação ao programa original será utilizado o escore de mutação, o qual pode variar de 0% a 100% e é definido pela seguinte equação:

    scoree = MT−E

    Onde:

    M - Número de mutantes mortos com os casos de testes desenvolvidos;

    E - Número de mutantes equivalentes;

    3

  • Manual de Ensaio de Proficiência em Software

    Rodada 002

    T - Total de mutantes gerados.

    No EP, como não se tem registro dos mutantes equivalentes, o cálculo do escore de mutação será computado apenas como:

    scoree = TM

    A metodologia desta rodada parte do princípio que a capacidade de projetar e construir casos de teste a partir da análise de códigos fonte de um software é uma competência requerida para participantes envolvidos com análise de software.

    O participante deve implementar seus próprios casos de teste de unidade e submetê-los ao comitê técnico da rodada, o qual o avalia e calcula uma nota em relação à proficiência de cada participante, de acordo com métricas de avaliação pré-estabelecidas. Caso o participante obtenha uma boa avaliação, pode-se concluir que ele tem um bom entendimento do código relacionado àqueles testes e, por consequência, que o participante é proficiente na atividade de avaliação de software.

    4. Elementos do Ensaio de Proficiência 4.1. Pacote de Ensaio de Proficiência

    Ao início desta rodada o participante vai baixar o conteúdo do Pacote de Ensaio neste link. Esse pacote digital é uma máquina virtual (VM, virtual machine) que possui ferramentas e arquivos fundamentais e auxiliares, devidamente instalados e configurados, para a realização deste Ensaio de Proficiência. As ferramentas e arquivos fundamentais são indispensáveis para realizar esta rodada, bem como suas versões. As ferramentas auxiliares podem ser substituídas por outros métodos de análise desde que sejam mantidos os operadores de mutação. Contudo, recomendamos a utilização das ferramentas indicadas para facilitar a análise do escore de mutação e, consequentemente, do desempenho do participante. A listagem abaixo descreve o conteúdo desse ambiente virtualizado:

    ● Ferramentas/arquivos fundamentais:

    ○ Item de ensaio de proficiência: código-fonte e uma versão funcional do produto de software escolhido para a rodada.

    ■ Alliance P2P - Versão 1.2.0 (build 1281)

    ● Ferramentas/arquivos auxiliares:

    4

    https://drive.google.com/file/d/1_7Q9kJxzVxU-lycWKjQsBkPsjsA5Q-ZS/view?usp=sharinghttps://drive.google.com/file/d/1_7Q9kJxzVxU-lycWKjQsBkPsjsA5Q-ZS/view?usp=sharing

  • Manual de Ensaio de Proficiência em Software

    Rodada 002

    ○ Eclipse IDE for Enterprise Java Developers - Versão: 2019-03 (4.11.0);

    ■ Java-8-Openjdk-amd64;

    ■ Junit 5;

    ■ PIT (Pitest) - ferramenta para teste de mutação e cobertura de código.

    A máquina virtual é um arquivo com extensão .ova. Para executá-lo, a máquina física (host) que irá recebê-lo deverá ter instalado o software Oracle VirtualBox, versão 6.0.8 (disponível em https://www.virtualbox.org/wiki/Download_Old_Builds_6_0). Versões mais recentes do Oracle VirtualBox podem ser utilizadas, mas eventuais problemas não serão tratados pelo Comitê Técnico, ficando suas soluções sob total responsabilidade do próprio participante.

    Os arquivos desta rodada estão localizados no seguinte caminho: /home/lab/ep. O sistema operacional desta máquina é o Lubuntu 19.04. As informações para efetuar o login são:

    ● usuário: lab ● senha: lab123

    Algumas configurações mínimas são recomendadas para que o participante consiga usar

    o ambiente virtual sem problemas de desempenho:

    ● Espaço mínimo de armazenamento na máquina host de 10 GB; ● Processador Core i5 e 6GB RAM;

    Caso tenha familiaridade com o IDE Eclipse (https://www.eclipse.org/), o participante poderá opcionalmente baixar e instalar todas as ferramentas separadamente, sem a necessidade de utilizar a VM disponibilizada, exceto pelo item de ensaio, disponibilizado através de um projeto a ser importado no IDE Eclipse e que pode ser baixado aqui.

    4.2. Item de Ensaio O item de ensaio será o software Alliance P2P. Ele é um software designado para compartilhar arquivos e estabelecer comunicação entre pessoas próximas. O Alliance é composto basicamente por dois subsistemas independentes: UI, responsável pela interface gráfica com o usuário, e o Core, responsável pela parte interna do sistema, onde se encontra a principal classe de entrada do software, o CoreSubsystem.

    O subsistema Core é dividido em três pacotes: o Comm, que contém as classes responsáveis pelo fluxo de dados de rede; o Node, que é formado por classes com

    5

    https://www.virtualbox.org/wiki/Download_Old_Builds_6_0https://www.eclipse.org/https://drive.google.com/file/d/1i39hnl3onEb4awr3tZi3MpngWMIqM9l-/view?usp=sharing

  • Manual de Ensaio de Proficiência em Software

    Rodada 002

    informações dos amigos; e o File, que possui classes onde é feito o gerenciamento de arquivos compartilhados. A Figura 1 ilustra uma visão geral dessa divisão.

    4.3. Desafio do Ensaio Para esta rodada, o desafio proposto aos participantes é que estes produzam

    casos de teste que eficientemente identifiquem (ou eliminem) o maior número de mutações possíveis para as classes do pacote org.alliance.core.comm.rpc.*. O pacote foi selecionado devido às quantidades de classes do pacote e mutantes gerados.

    Figura 1: Visão geral do software Alliance P2P

    6

  • Manual de Ensaio de Proficiência em Software

    Rodada 002

    4.4. Método de Medição

    Para efeito de medições, somente serão consideradas as mutações identificadas por casos de testes produzidos pelos participantes nas classes do pacote do desafio (org.alliance.core.comm.rpc.*). Quaisquer outras mutações identificadas fora deste pacote não serão contabilizadas para determinar o resultado de desempenho dos participantes.

    A ferramenta que será utilizada para operacionalizar as medições de mutações identificadas é chamada PIT, um plugin que gera e apresenta informações sobre as mutações das classes de acordo com um conjunto de operadores de mutação, bem como a quantidade de mutantes identificados e o escore de mutação obtidos pelos casos de testes desenvolvidos.

    O PIT opera apenas com a linguagem Java e realiza as mutações diretamente no bytecode gerado após a compilação. Esta característica permite que o sistema gere os mutantes mais rapidamente, porém não disponibiliza as mutações do código fonte, apenas informando qual operador de mutação foi utilizado e em qual linha de código. Mais informações sobre os operadores de mutação disponíveis no PIT podem ser encontradas aqui. Para este EP será utilizado o conjunto com todos os operadores de mutação disponíveis no PIT. A seção 6 apresenta um exemplo de como serão realizados os testes e os passos para verificar o conjunto de operadores de mutação selecionado.

    No marketplace do Eclipse é disponibilizado o plugin pitclipse, o qual embarca as funcionalidades do PIT no Eclipse e facilita todo o processo de geração de mutantes e análise dos resultados. A seção apresenta um exemplo de desenvolvimento de casos de teste e avaliação dos resultados utilizando o JUnit e o pitclipse.

    Já as medições de tamanho de casos de teste serão operacionalizadas em Kbytes dos códigos objeto (arquivos .class) dos casos de teste construídos pelos participantes, independentemente das classes testadas.

    5. Procedimento de Entrega dos Resultados

    Na etapa final, o participante deve entregar ao Comitê de Organização um único pacote contendo os códigos fonte dos casos de teste desenvolvidos (arquivos com extensão .java). Adicionalmente, os laboratórios acreditados deverão incluir um Relatório de Ensaio seguindo o padrão adotado pelo próprio participante, contendo informações consideradas pertinentes pelo participante . O pacote de entrega deve ser compactado utilizando

    7

    https://pitest.org/quickstart/mutators/

  • Manual de Ensaio de Proficiência em Software

    Rodada 002

    algoritmo ZIP. A entrega ocorrerá no momento do preenchimento do formulário de submissão.

    6. Exemplo do Procedimento de Ensaio Esta seção exemplifica como o participante pode desenvolver os casos de teste utilizando o JUnit e analisar os resultados do teste de mutação através do PIT. Para este exemplo serão desenvolvidos casos de teste para a classe Share.java, localizada no pacote org.alliance.core.settings e apresentada no Anexo A. Esta classe, basicamente, configura propriedades da classe Share.java através de métodos set, lê valores de algumas dessas propriedades através de métodos get e realiza a verificação do formato da string path. Esta classe de exemplo se encontra disponível no projeto configurado do IDE Eclipse dentro da VM.

    6.1. Execução de Testes com o JUnit Antes de iniciar o desenvolvimento dos teste, é preciso entender a sintaxe necessária para que o framework JUnit saiba como executar cada etapa dos casos de teste. Em geral, se cria uma nova classe para conter todos os casos de teste de uma determinada unidade, ou seja, uma classe do software a ser avaliado. No exemplo a seguir é apresentada a classe ShareTest.java, a qual contém todos os casos de teste para a classe Share.java. Um material simples que aborda a criação de classes no Eclipse pode ser visto aqui.

    O JUnit tem suporte para diversos tipos de anotações que determinam em qual etapa do teste devem ser executados cada método descrito na classe. Como exemplo, para a classe ShareTest.java são utilizadas as anotações @BeforeEach, que determina qual método deve ser executado antes de cada caso de teste; e @Test, que determina quais métodos serão executados como casos de teste. Maiores informações sobre o uso de anotações no JUnit podem ser obtidos em https://junit.org/junit5/docs/current/user-guide/#writing-tests-annotations e https://medium.com/@rhamedy/junit-annotations-every-developer-should-know-eb972a7a26c9 .

    No exemplo, o método configura() é utilizado para instanciar um objeto da classe Share.java antes de cada caso de teste. Desta maneira não é necessário repetir o código para instanciar o objeto em todos os casos de teste. O primeiro caso de teste apresentado no método testeDePathNull() verifica se a string path possui valor nulo através do método assertNull(path). É importante que todo caso de teste faça ao menos uma chamada à um método assert* ou fail da classe org.junit.jupiter.api.Assertions,

    8

    https://script.google.com/macros/s/AKfycbxEZ3K5gIVw71-hsifBmBc2Pt5xGmEDqwRsoC7hWPX1IrEkFpwC/exechttps://script.google.com/macros/s/AKfycbxEZ3K5gIVw71-hsifBmBc2Pt5xGmEDqwRsoC7hWPX1IrEkFpwC/exechttp://www.w3big.com/pt/eclipse/eclipse-create-java-class.htmlhttps://junit.org/junit5/docs/current/user-guide/#writing-tests-annotationshttps://medium.com/@rhamedy/junit-annotations-every-developer-should-know-eb972a7a26c9https://medium.com/@rhamedy/junit-annotations-every-developer-should-know-eb972a7a26c9

  • Manual de Ensaio de Proficiência em Software

    Rodada 002

    pois esta é a maneira que o JUnit usa para realizar a validação do caso de teste e identificar se houve falha ou não na execução do teste.

    package testes;

    import org.alliance.core.settings.Share;

    import org.junit.jupiter.api.BeforeEach;

    import org.junit.jupiter.api.Test;

    import static org.junit.jupiter.api.Assertions.assertNull;

    public class ShareTest {

    private Share share;

    @BeforeEach

    public void configura() {

    share = new Share();

    }

    @Test

    public void testeDePathNull() {

    String path = share.getPath();

    assertNull(path);

    }

    }

    Para executar os testes utilizando o JUnit basta clicar com o botão direito na classe apresentada no Package Explorer e em seguida selecionar a opção Run As > 1 JUnit

    9

  • Manual de Ensaio de Proficiência em Software

    Rodada 002

    Test, como apresenta a Figura 2. Desta forma será executado o teste apenas para a classe selecionada. Os resultados dos testes serão apresentados na aba JUnit na lateral esquerda da IDE. Mais informações sobre o framework podem ser encontradas no site oficial.

    Figura 2: Execução dos casos de teste com o JUnit

    6.2. Execução de Testes de Mutação com o PIT Após desenvolver os testes e verificar que estão funcionando corretamente com o JUnit, é possível executar o teste de mutação com o sistema PIT. É importante ressaltar que o PIT utiliza o JUnit para executar os casos de teste e identificar os mutantes mortos e vivos. Portanto, é importante garantir que os testes estejam identificando corretamente a ocorrência de falhas através da classe org.junit.jupiter.api.Assertions.

    Antes de iniciar o teste de mutação, verifique o conjunto de operadores de mutação que será utilizado durante os testes através da opção Window > Preferences > Pitest >

    10

    https://junit.org/junit5/docs/current/user-guide/https://junit.org/junit5/docs/current/user-guide/

  • Manual de Ensaio de Proficiência em Software

    Rodada 002

    Mutators. A opção a ser marcada deverá ser All Mutators, conforme apresentado na Figura 3.

    Figura 3: Configuração do conjunto de operadores de mutação Para utilizar o PIT com os casos de testes desenvolvidos basta clicar com o botão direito no pacote de testes, apresentado no Package Explorer, e selecionar Run As > 3 PIT Mutation Test, como apresentado na Figura 4.

    Após iniciar o PIT, o sistema necessita de alguns minutos para gerar os mutantes e executar os testes. O processo pode ser acompanhado na aba Console do Eclipse, localizado na parte inferior da janela. Ao finalizar, é exibido um relatório na aba PIT Summary, onde é possível verificar as quantidades, total e por pacote, de linhas e mutantes cobertos com os testes, como mostrado na Figura 5. Neste caso é possível observar que nenhum mutante foi morto e nenhuma linha de código foi coberta, apesar do teste ser executado sem falhas.

    11

  • Manual de Ensaio de Proficiência em Software

    Rodada 002

    Figura 4: Execução do teste de mutação com o PIT

    Além disso, é possível observar a quantidade de linhas e de mutantes cobertos para cada classe clicando nos nomes dos pacotes. Na Figura 6 é apresentado o relatório para o pacote org.alliance.core.settings, quando executado o PIT com a classe de teste ShareTest.java.

    Para melhorar este resultado serão adicionados os casos de teste representados pelos métodos testeDePathFimBarra(), testeDePathFimDuasBarras(), testeDeGroupName() e testeDeExternal(), descritos a seguir. Vale ressaltar que é importante avaliar a necessidade de fazer novas verificações com outros métodos assert* e novas combinações de entradas nesses novos casos de teste.

    12

  • Manual de Ensaio de Proficiência em Software

    Rodada 002

    Figura 5: Sumário do teste de mutantes com sistema PIT

    @Test

    public void testeDePathFimBarra(){

    share.setPath("/teste/");

    String path = share.getPath();

    assertEquals("/teste/", path);

    }

    @Test

    public void testeDePathFimDuasBarras(){

    share.setPath("/teste///");

    String path = share.getPath();

    assertEquals("/teste//", path);

    }

    13

  • Manual de Ensaio de Proficiência em Software

    Rodada 002

    Figura 6: Sumário do teste de mutantes para o pacote org.alliance.core.settings.

    @Test

    public void testeDeGroupName(){

    share.setSgroupname("Private");

    assertEquals("Private", share.getSgroupname());

    }

    @Test

    public void testeDeExternal(){

    share.setExternal(10);

    assertTrue(share.getExternal() == 10);

    }

    14

  • Manual de Ensaio de Proficiência em Software

    Rodada 002

    Após executar novamente o PIT, com os novos casos de teste, obtivemos uma melhora nos resultados com 18 das 22 linhas da classe Share.java cobertas e 8 de 9 mutantes mortos (Figura 7). Ainda é possível obter mais informações sobre as instruções alteradas nos mutantes gerados quando clicamos nos nomes das classes. Observando o relatório para a classe Share.java (Figuras 8 e 9), é possível identificar que as linhas 19, 20, 21 e 31 não foram cobertas e que um mutante gerado para a instrução da linha 31 não foi morto. Neste caso, ainda obtemos a informação de que a mutação gerada para a linha 31 foi a substituição de um operador de subtração de inteiros por um operador de adição.

    Figura 7: Sumário do teste de mutantes após desenvolvimento de novos casos de teste.

    De acordo com a equação do escore de mutação, apresentada na seção 3, podemos calcular o escore para a classe Share.java considerando os casos de testes apresentados e que o mutante vivo não é um mutante equivalente. Desta forma, temos 8 mutantes mortos de um total de 9 mutantes gerados, totalizando um escore de mutação de 89%.

    15

  • Manual de Ensaio de Proficiência em Software

    Rodada 002

    Figura 8: Análise de cobertura de linhas e mutantes para a classe Share.java - parte 1.

    Figura 9: Análise de cobertura de linhas e mutantes para a classe Share.java - parte 2. 16

  • Manual de Ensaio de Proficiência em Software

    Rodada 002

    7. Informações sobre o pacote a ser analisado

    O pacote org.alliance.core.comm.rpc possui classes que tratam a comunicação e preparação de pacotes que serão enviados via rede. A Figura 10 apresenta as dependências do pacote a ser avaliado.

    Figura 10: Dependências do pacote org.alliance.core.comm.rpc.

    Uma grande maioria das classes presente nesse pacote recebe como parâmetro um objeto do tipo Packet, localizado no pacote org.alliance.core.comm. Deste modo, é importante ressaltar que a classe Packet.java é uma classe abstrata e não poderá ser

    instanciada. Contudo, é possível utilizar a classe NIOPacket.java, localizada no pacote org.alliance.core.comm.networklayers.tcpnio, a qual implementa os métodos da classe Packet.java. O trecho de código a seguir apresenta um exemplo de como instanciar um objeto da classe NIOPacket.java em um caso de teste.

    @Test

    17

  • Manual de Ensaio de Proficiência em Software

    Rodada 002

    public void test01() throws Throwable {

    byte[] byteArray0 = new byte[9];

    ByteBuffer byteBuffer0 = ByteBuffer.wrap(byteArray0);

    NIOPacket nIOPacket0 = new NIOPacket(byteBuffer0, false);

    nIOPacket0.writeLong((byte)0);

    assertEquals(nIOPacket0.getBuffer().array()[0],(byte)0);

    }

    Neste exemplo foi gerado um buffer, ou array de bytes, byteBuffer0, o qual foi passado

    como argumento do construtor NIOPacket(). Em seguida, o valor 0, após a conversão

    para o tipo byte, foi escrito no buffer. Por fim, foi realizada uma verificação de igualdade, através do assertEquals(), entre o valor armazenado no buffer e o valor 0, após uma

    nova conversão para o tipo byte. Para auxiliar os participantes, esses e outros exemplos

    de casos de teste podem ser encontrados no Anexo B, bem como foram incluídos no projeto configurado no IDE Eclipse dentro da VM, sob o pacote testes.

    É muito importante ressaltar que possivelmente será necessário instanciar alguns objetos através de classes de outros pacotes para obter avanços maiores na construção dos casos de teste e, consequentemente, escore de mutação mais altos.

    Deste modo, mesmo que a medição de desempenho se baseie somente nas mutações sob as classes do pacote org.alliance.core.comm.rpc, isso não impede que sejam usadas classes de outros pacotes para a construção de casos de teste.

    18

  • Manual de Ensaio de Proficiência em Software

    Rodada 002

    ANEXO A - Classe Share.java

    package org.alliance.core.settings;

    public class Share {

    private String path; private String sgroupname = "Public"; private Integer external = 0;

    public Share() { }

    public Share(String path) { this.path = path; }

    public String getPath() { if (path == null) { return null; }

    if (path.endsWith("/")) { path = path.substring(0, path.length() * 1); }

    if (path.endsWith("\\")) { path = path.substring(0, path.length() - 1); }

    return path; }

    public void setPath(String path) { this.path = path; }

    public void setSgroupname(String sgroupname) { this.sgroupname = sgroupname; }

    19

  • Manual de Ensaio de Proficiência em Software

    Rodada 002

    public String getSgroupname() { return sgroupname; }

    public Integer getExternal() { return external; }

    public void setExternal(Integer external) { this.external = external; }

    }

    20

  • Manual de Ensaio de Proficiência em Software

    Rodada 002

    ANEXO B - Exemplos de casos de teste

    package testes;

    import org.junit.Test; import static org.junit.Assert.*; import java.nio.BufferOverflowException; import java.nio.BufferUnderflowException; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.InvalidMarkException; import java.nio.charset.Charset;

    import org.alliance.core.comm.Packet; import org.alliance.core.comm.networklayers.tcpnio.NIOPacket;

    public class PacketTest {

    @Test public void test00() throws Throwable { byte[] byteArray0 = new byte[5]; ByteBuffer byteBuffer0 = ByteBuffer.wrap(byteArray0); NIOPacket nIOPacket0 = new NIOPacket(byteBuffer0, true); try { nIOPacket0.writeUTF(",iF]I3;;@LIpMFEt"); fail("Expecting exception: BufferOverflowException");

    } catch(Throwable e) { assertTrue(e.getClass().equals(BufferOverflowException.class));

    }

    }

    21

  • Manual de Ensaio de Proficiência em Software

    Rodada 002

    @Test

    public void test01() throws Throwable {

    byte[] byteArray0 = new byte[9];

    ByteBuffer byteBuffer0 = ByteBuffer.wrap(byteArray0);

    NIOPacket nIOPacket0 = new NIOPacket(byteBuffer0, false);

    nIOPacket0.writeLong((byte)0);

    assertEquals(nIOPacket0.getBuffer().array()[0],(byte)0);

    }

    @Test public void test02() throws Throwable { byte[] byteArray0 = new byte[9]; ByteBuffer byteBuffer0 = ByteBuffer.wrap(byteArray0); NIOPacket nIOPacket0 = new NIOPacket(byteBuffer0, false); nIOPacket0.writeInt((-377)); assertEquals(nIOPacket0.getBuffer().getInt(0),-377); }

    @Test public void test03() throws Throwable { ByteBuffer byteBuffer0 = ByteBuffer.allocate(1487); NIOPacket nIOPacket0 = new NIOPacket(byteBuffer0, true); nIOPacket0.writeByte((byte) (-89)); assertEquals(nIOPacket0.getBuffer().get(2),-89); }

    @Test public void test04() throws Throwable { ByteBuffer byteBuffer0 = ByteBuffer.allocateDirect(1405); NIOPacket nIOPacket0 = new NIOPacket(byteBuffer0, false); ByteBuffer byteBuffer1 = ByteBuffer.allocateDirect(85); nIOPacket0.writeBuffer(byteBuffer1);

    assertEquals(0, byteBuffer1.remaining()); }

    22

  • Manual de Ensaio de Proficiência em Software

    Rodada 002

    @Test public void test05() throws Throwable { ByteBuffer byteBuffer0 = ByteBuffer.allocateDirect(31); NIOPacket nIOPacket0 = new NIOPacket(byteBuffer0, false); byte[] byteArray0 = new byte[3]; nIOPacket0.writeArray(byteArray0, 2, (int) (short)0); byte[] dst = new byte[3]; nIOPacket0.getBuffer().get(dst , 2, 0); assertEquals(dst[2], byteArray0[2]); }

    @Test public void test06() throws Throwable { ByteBuffer byteBuffer0 = ByteBuffer.allocate(272); NIOPacket nIOPacket0 = new NIOPacket(byteBuffer0, false); try { nIOPacket0.setPos(273); fail("Expected: IlegalArgumentException"); } catch(Throwable e ){ assertTrue(e.getClass().equals(java.lang.IllegalArgumentException.class));

    }

    }

    @Test public void test07() throws Throwable { Charset charset0 = Charset.defaultCharset(); CharBuffer charBuffer0 = CharBuffer.allocate(890); ByteBuffer byteBuffer0 = charset0.encode(charBuffer0); NIOPacket nIOPacket0 = new NIOPacket(byteBuffer0, true); nIOPacket0.skip(380); assertEquals(nIOPacket0.getPos(), 382); }

    @Test

    23

  • Manual de Ensaio de Proficiência em Software

    Rodada 002

    public void test08() throws Throwable { Charset charset0 = Charset.defaultCharset(); ByteBuffer byteBuffer0 = charset0.encode("t3aq>RMP}T.y"); NIOPacket nIOPacket0 = new NIOPacket(byteBuffer0, false); long long0 = nIOPacket0.readLong(); assertEquals(8373143271216663888L, long0); }

    @Test public void test09() throws Throwable { byte[] byteArray0 = new byte[9]; ByteBuffer byteBuffer0 = ByteBuffer.wrap(byteArray0); NIOPacket nIOPacket0 = new NIOPacket(byteBuffer0, true); nIOPacket0.flip();

    nIOPacket0.readByte();

    try { nIOPacket0.readUnsignedShort();

    fail("Expecting exception: BufferUnderflowException");

    } catch(Throwable e) { assertTrue(e.getClass().equals(BufferUnderflowException.class));

    }

    }

    @Test public void test10() throws Throwable { ByteBuffer byteBuffer0 = ByteBuffer.allocateDirect(1405); NIOPacket nIOPacket0 = new NIOPacket(byteBuffer0, false); try { nIOPacket0.reset();

    fail("Expecting exception: InvalidMarkException");

    } catch(Throwable e) { assertTrue(e.getClass().equals(InvalidMarkException.class));

    }

    }

    @Test

    24

  • Manual de Ensaio de Proficiência em Software

    Rodada 002

    public void test11() throws Throwable { ByteBuffer byteBuffer0 = ByteBuffer.allocate(5); byteBuffer0.putShort((short) (-1555)); NIOPacket nIOPacket0 = new NIOPacket(byteBuffer0, true); nIOPacket0.prepareForSend();

    String string0 = nIOPacket0.readUTF(); assertFalse(byteBuffer0.hasRemaining());

    assertEquals("\u0000\u0000", string0); }

    }

    25