Upload
henrique-oliveira
View
19
Download
6
Embed Size (px)
Citation preview
TESTE DE SOFTWARE - TEORIA
Propósito: Avaliar se o software ● Cumpre os requisitos; ● Responde corretamente às entradas; ● Desempenha as funções em tempo aceitável; ● Possuí boa usabilidade; ● É compatível com o ambiente alvo; ● Atinge os objetivos estabelecidos pelos stakeholders.
Técnicas:
● Testes estáticos: Feitos sem que o programa seja rodado: Ex: revisão de código. ● Testes dinâmicos: Feitos rodando o programa. ● Caixa-branca: Teste de estruturas internas do programa. ● Caixa-preta: Testa funcionalidades externas do programa, sem conhecimentos
da estrutura interna. ● Testes não-funcionais: Teste de requisitos não-funcionais como desempenho,
usabilidade, confiabilidade, etc. Níveis:
● Unidade/Componente: Verifica a funcionalidade de uma parte específica do código. No caso de Orientação a Objeto, essa parte geralmente é uma classe ou um método.
● Integração: Testa as interações entre os componentes. ● Sistema: Testa o sistema inteiro em funcionamento, usando o método de “caixa-
preta”. ● Aceitação: Teste feito pelo usuário/cliente. ● Operação: Teste no ambiente final do software. Pode incluir testes de instalação,
compatibilidade, desempenho, etc. Processos:
● Bottom Up: de testes de unidade a teste do sistema. ● Top Down: de teste de sistema a testes de unidade. ● Cascata: Testes realizados após o desenvolvimento da funcionalidade. ● Desenvolvimento orientado a testes (TDD): Testes de unidade são escritos
antes da funcionalidade. ● etc...
Ferramentas de automação de testes:
● Teste Unitário e de Integração: JUnit, DBUnit, TestNG ● Teste de Carga e Desempenho: JMeter, JUnitPerf ● Teste de Interface Web: Selenium ● Gestão de issues: Bugzilla, JIRA, Mantis ● Detecção de Erros: FindBugs, PMD ● etc...
XP Programming
● Utiliza o Desenvolvimento orientado a testes (Test-driven development ou TDD). ● Etapas do TDD:
1. O próprio desenvolvedor da funcionalidade deve escrever os testes (antes da funcionalidade!) utilizando a documentação (casos de uso e user stories).
2. Executar todos os testes (“teste dos testes”). 3. Escrever o código da funcionalidade. 4. Executar novamente os testes. 5. Refatorar, corrigir e limpar o código. 6. Repetir o ciclo para outras funcionalidades.
● Testes de integração realizados posteriormente por time de teste. ● Práticas de integração continuada são freqüentemente usadas com o TDD. Nela, um
servidor é configurado para rodar automaticamente testes de unidade e verifica todo o código enviado para o repositório. Não usaremos pois é necessário muito tempo para configurar esse sistema.
● Ferramentas de automação de teste que iremos usar: ○ JUnit: Realiza testes unitários e de integração ○ JMeter: Realiza testes de carga e desempenho
JUNIT - plataforma para teste de unidade
Para cada classe “classe.java” a ser testada, uma classe “classeTest.java” deve ser criada para testá-la. Para fazer isso, no Eclipse, ir em File->New->Other, Java->Junit->”JUnit Test Case”, que gerará a classe “classeTest.java”. Exemplo de código a ser testado (Fibonacci.java) e código para o JUnit (FibonacciTest.java): Fibonacci.java package fibonacci; public class Fibonacci { static long fibo(int n) { int F = 0; // atual int ant = 0; // anterior for (int i = 1; i <= n; i++) { if (i == 1) { F = 1; ant = 0; } else { F += ant; ant = F ‐ ant; } } return F; } public static void main(String[] args) { // teste do programa. Imprime os 30 primeiros termos for (int i = 0; i < 30; i++) { System.out.print("(" + i + "):" + Fibonacci.fibo(i) + "\t"); } } } FibonacciTest.java: package fibonacci; import static org.junit.Assert.*; import org.junit.Test; import org.junit.Before; import org.junit.After; public class FibonacciTest {
// Introduz valores de entrada int valor1; int valor2; @Before public void setUp() { valor1 = 9; valor2 = 11; } @After public void tearDown() { valor1 = 0; valor2 = 0; } @Test public void test() { // Executa a função com o valor de entrada de teste e recebe o valor de retorno long retornofeito = Fibonacci.fibo(valor1); // Compara o valor de retorno com o esperado assertEquals("falhou primeiro",34,retornofeito,0); retornofeito = Fibonacci.fibo(valor2); assertEquals("falhou segundo",89,retornofeito,0); } } Ao rodar o código acima:
Alterando a linha: assertEquals("falhou primeiro",34,retornofeito,0);
por
assertEquals("falhou primeiro",33,retornofeito,0);
(ou seja, colocando um valor incorreto):
Teste de exceção: Também é possível testar a ocorrência de uma exceção no código, evitando a proliferação de try/catchs no mesmo. Por exemplo, caso eu inclua um “int testException = 1 / n” em Fibonacci.java, e mande n=0 como parâmetro, isso retornará um RuntimeException por causa da divisão por zero. Em FibonacciTest.java, o seguinte teste verifica essa exceção: @Test(expected = RuntimeException.class) public void TESTRuntimeException() throws Exception { Fibonacci myClass = new Fibonacci(); myClass.fibo(0);
} } Asserts: Além do assertEquals que foi usado, existem outras formas de asserts: assertEquals("failure - strings are not equal", expected, actual , tolerance); assertArrayEquals("failure - byte arrays not same", expected, actual); assertTrue(“true”, boolean condition); assertFalse("failure - should be false", boolean condition); assertNull("should be null", Object); assertNotNull("should not be null", Object); assertSame("should be same", aObject, aObject); assertNotSame("should not be same Object", expected, actual); assertThat(Arrays.asList("one", "two", "three"), hasItems("one", "three"));
Annotations: No código de exemplo, as annotations @Before e @After foram usadas apenas para
mostrar como usá‐las. Elas só são realmente necessárias caso você for usar uma Lista
ou outro objeto no seu método de teste, para que ele seja inicializado e
posteriormente limpado da memória. Além de @Test, @Before e @After, existem também as
seguintes Annotations:
Annotation Description
@Test public void method()
The @Test annotation identifies a method as a test method.
@Test (expected = Exception.class)
Fails if the method does not throw the named exception.
@Test(timeout=100) Fails if the method takes longer than 100 milliseconds.
@Before public void method()
This method is executed before each test. It is used to prepare the test environment (e.g., read input data, initialize the class).
@After public void method()
This method is executed after each test. It is used to cleanup the test environment (e.g., delete temporary data, restore defaults). It can also save memory by cleaning up expensive memory structures.
@BeforeClass public static void method()
This method is executed once, before the start of all tests. It is used to perform time intensive activities, for example, to connect to a database. Methods marked with this annotation need to be defined as static to work with JUnit.
@AfterClass public static void method()
This method is executed once, after all tests have been finished. It is used to perform clean-up activities, for example, to disconnect from a database. Methods annotated with this annotation need to be defined as static to work with JUnit.
@Ignore Ignores the test method. This is useful when the underlying code has been changed and the test case has not yet been adapted. Or if the execution time of this test is too long to be included.
Regras de boa prática com JUnit: Use apenas dados suficientes (não teste 10 condições se três forem suficientes) Não teste métodos triviais, tipo get e set. Achou um bug? Não conserte sem antes escrever um teste que o pegue. Comece pelas mais simples e deixe os testes “complexos“ para o final.
JMeter - plataforma para teste de desempenho
O JMeter permite avaliar o desempenho dos sistemas de cliente-servidor simulando diversas condições de carga no servidor. Para se utilizar o JMeter, primeiramente deve se fazer o download do binário no site: https://jmeter.apache.org/download_jmeter.cgi No caso do Windows, baixe o zip, descompacte-o e rode jmeter.bat que está na pasta bin. Exemplo simples: Faremos um exemplo simples utilizando em conjunto com o Apache Server, configurado em localhost 127.0.0.1 porta 80. Com o botão direito no Plano de Teste escolher a opção Add-> Threads(Users) -> Thread Group.
Nessa aba pode se fazer a configuração do teste que será feito. No teste exemplo, utilizaremos as seguintes configurações: Number of Threads (Users): 30 Ramp-Up Period (in seconds): 3 Essa configuração significa que será executado 10 threads a cada segundo. Caso queira repetir essa requisição basta alterar o Loop Count (Contador de iteração). Após configurado, com o botão direito sobre o Thread Group escolher Add -> Sampler -> HTTP Request No HTTP Request, alterar o Server Name or IP para localhost (caso esteja fazendo esse teste exemplo no localhost), a porta para 80 (ou qualquer outra que estiver configurada no servidor) e alterar o Path para ./example.php
Nesse exemplo será feito o teste com o uso de um arquivo php por ser bem simples. O conteúdo do arquivo exemplo é: example.php <html> <head> <title>PHP Test</title> </head> <body> <?php
for ($sum = $i = 0; $i < 10000000; $i++) { $sum += $i; } echo $sum;
?> </body> </html>
Na pasta htdocs (Da ferramenta que foi utilizada para subir o servidor em localhost) adicionar o arquivo example.php. Novamente sobre o Thread Group, escolher Add -> Listener -> View Results in Table (ou outra forma que achar conveniente para se visualizar os resultados) Após salvo as alterações, basta executar.
Mais informações: https://pt.wikipedia.org/wiki/Test_Driven_Development http://www.devmedia.com.br/testes-de-unidade-com-junit/4637 http://www.devmedia.com.br/junit-implementando-testes-unitarios-em-java-parte-i/1432 http://www.devmedia.com.br/usando-o-jmeter-para-teste-de-performance/20302 http://www.decom.ufop.br/imobilis/?p=1146 http://junit.org/ https://jmeter.apache.org/index.html