• Nenhum resultado encontrado

POPT: uma abordagem de ensino de programação orientada a problema e testes

N/A
N/A
Protected

Academic year: 2017

Share "POPT: uma abordagem de ensino de programação orientada a problema e testes"

Copied!
144
0
0

Texto

(1)

Universidade Federal do Rio Grande do Norte Centro de Ciências Exatas e da Terra

Departamento de Informática e Matemática Aplicada Programa de Pós-Graduação em Sistemas e Computação

Dissertação de Mestrado

POPT: Uma Abordagem de Ensino de

Programação Orientada a Problema e Testes

Vicente Pires Lustosa Neto

Prof. Dra. Roberta de Souza Coelho Orientadora Prof. Dr. Dalton Serey Guerrero Co-orientador

(2)

Universidade Federal do Rio Grande do Norte Centro de Ciências Exatas e da Terra

Departamento de Informática e Matemática Aplicada Programa de Pós-Graduação em Sistemas e Computação

POPT: Uma Abordagem de Ensino de

Programação Orientada a Problema e Testes

Vicente Pires Lustosa Neto

Dissertação apresentada ao Programa de Pós-Graduação em Sistemas e Computação do Departamento de Informática e Matemática Aplicada da Universidade Federal do Rio Grande do Norte como requisito para a obtenção do grau de Mestre em Sistemas e Computação.

Prof. Dra. Roberta de Souza Coelho Orientadora Prof. Dr. Dalton Serey Guerrero Co-orientador

(3)

Catalogação da Publicação na Fonte. UFRN / SISBI / Biblioteca Setorial Centro de Ciências Exatas e da Terra – CCET.

Lustosa Neto, Vicente Pires.

POPT: uma abordagem de ensino de programação orientada a problema e testes / Vicente Pires Lustosa Neto. - Natal, 2013.

93 f.: il.

Orientadora: Profa. Dra. Roberta de Souza Coelho. Co-orientador: Prof. Dr. Dalton Serey Guerrero.

Dissertação (Mestrado) – Universidade Federal do Rio Grande do Norte. Centro de Ciências Exatas e da Terra. Programa de Pós-Graduação em Sistemas e Computação.

1. Software – Dissertação. 2. Teste de software – Dissertação. 3. Ensino – Dissertação. 4. Programação orientada a problema – Dissertação. I. Coelho, Roberta de Souza. II. Guerrero, Dalton Serey. III. Título.

(4)
(5)

Resumo

(6)

na qualidade do código gerado pelos alunos quando comparado a metodologia tradicional.

(7)

Abstract

There is a growing interest of the Computer Science education community for including testing concepts on introductory programming courses. Aiming at contributing to this issue, we introduce POPT, a Problem-Oriented Programming and Testing approach for Introductory Programming Courses. POPT main goal is to improve the traditional method of teaching introductory programming that concentrates mainly on implementation and neglects testing. POPT extends POP (Problem Oriented Programing) methodology proposed on the PhD Thesis of Andrea Mendonça (UFCG). In both methodologies POPT and POP, students’ skills in dealing with ill-defined problems must be developed since the first programming courses. In POPT however, students are stimulated to clarify ill-defined problem specifications, guided by de definition of test cases (in a table-like manner). This paper presents POPT, and TestBoot a tool developed to support the methodology. In order to evaluate the approach a case study and a controlled experiment (which adopted the Latin Square design) were performed. In an Introductory Programming course of Computer Science and Software Engineering Graduation Programs at the Federal University of Rio Grande do Norte, Brazil. The study results have shown that, when compared to a Blind Testing approach, POPT stimulates the implementation of programs of better external quality – the first program version submitted by POPT students passed in twice the number of test cases (professor-defined ones) when compared to non-POPT students. Moreover, POPT students submitted fewer program versions and spent more time to submit the first version to the automatic evaluation system, which lead us to think that POPT students are stimulated to think better about the solution they are implementing. The controlled experiment confirmed the influence of the proposed methodology on the quality of the code developed by POPT students.

(8)

Agradecimentos

A minha orientadora Roberta de Souza Coelho pela disposição em ajudar e por sempre acreditar mesmo quando eu mesmo não acreditava. Desejo passar para meus alunos toda a compreensão e orientação que obtive da professora Roberta e sem do qual não teria conseguido chegar ao final dessa jornada.

A Andressa de Castro que me incentivou a continuar em frente e me confortou quando eu mais precisava. Sem ela não teria nem iniciado este trabalho e a considero uma parte importante da minha vitória.

Aos professores Dalton Serey e Andréa Mendonça pela ajuda nos diversos experimentos realizados e contribuições valiosas.

Aos professores Andre Campos e Eduardo Aranha que contribuíram também nos trabalhos realizados.

Aos alunos e colegas que participaram nos diversos experimentos realizados, pois sem eles, nada disso teria sido concluído.

(9)

Sumário

1  Introdução ... 13 

1.1  Solução proposta ... 13 

1.2  Objetivos ... 14 

1.3  Contribuições ... 15 

1.4  Organização do trabalho... 15 

2  Fundamentação Teórica ... 17 

2.1  Conceitos Básicos ... 17 

2.2  Teste de Software ... 18 

2.2.1  Testes funcionais (ou testes caixa-preta) ... 18 

2.2.1.1  Classes de equivalência ... 19 

2.2.1.2  Valores limites ... 20 

2.3  Testes estruturais (ou testes caixa-branca) ... 20 

2.4  Níveis de teste ... 21 

2.5  Automação de testes ... 22 

2.6  JUnit ... 22 

2.7  FITNESSE ... 23 

2.8  Test-Driven Development ... 24 

2.9  Programação Orientada a Problema ... 25 

2.10  Engenharia de Software Experimental ... 28 

3  Metodologia Proposta ... 30 

3.1  Visão geral ... 30 

3.2  Participantes e Papéis ... 31 

3.3  Práticas POPT ... 31 

3.4  Fluxo de Trabalho ... 32 

3.5  Conceitos Básicos apresentados aos alunos ... 34 

3.5.1  Passo 1: Receber Problema Mal-Definido ... 35 

3.5.2  Passo 2: Fazer Perguntas ao Tutor ... 35 

3.5.3  Passo 3: Escrever testes no TestBoot ... 36 

(10)

3.5.3.2  Valores Limites. ... 37 

3.5.4  Passo 4: Elaborar o código ... 38 

3.5.5  Passo 5: Executar testes no TestBoot ... 38 

3.5.6  Passo 6: Corrigir código ... 39 

3.5.7  Passo 7: Submeter versão do código ... 39 

3.6  Apresentação das demais etapas de POPT ... 40 

3.7  Discussões ... 41 

4  A Ferramenta TestBoot ... 42 

4.1  Arquitetura da TestBoot ... 42 

4.1.1  Classe Cell ... 43 

4.1.2  Classe Test ... 43 

4.1.3  Classe TestList ... 43 

4.1.4  Classe Executor ... 43 

4.1.5  Classe Tester ... 43 

4.1.6  Classe Parser ... 43 

4.1.7  Classe Build ... 44 

4.2  Como as classes interagem para execução dos testes ... 44 

4.3  Lendo os Dados de Entrada da Tabela ... 44 

4.4  Executando Múltiplos Testes ... 45 

4.5  Interface da Ferramenta ... 47 

5  Estudo de Caso ... 52 

5.1  Organização do Estudo ... 52 

5.1.1  Participantes ... 53 

5.1.2  Problema Alvo ... 53 

5.1.3  Casos de Teste ... 54 

5.2  Resultados do Estudo ... 55 

5.3  Discussões ... 58 

(11)

6  Experimento ... 65 

6.1  Definição do experimento ... 65 

6.2  Hipóteses ... 65 

6.3  Design do Experimento ... 66 

6.4  Participantes ... 66 

6.5  Execução do experimento ... 67 

6.6  Análise dos Resultados ... 67 

6.6.1  Teste de Anderson-Darling ... 69 

6.6.2  Teste de Shapiro-Wilk ... 70 

6.6.3  Teste de Tukey ... 71 

6.7  Tabela ANOVA ... 71 

6.7.1  Influência dos participantes e problemas utilizados ... 72 

6.7.2  Influência das metodologias ... 72 

6.8  Discussões Gerais ... 72 

7  Trabalhos Relacionados... 74 

7.1  Ensino Dirigido a Teste ... 74 

7.2  Teste Cego ... 75 

7.3  WebIDE ... 77 

7.4  Discussão sobre testes na grade curricular ... 78 

7.5  Discussões ... 78 

8  Conclusões ... 80 

8.1  Trabalhos Futuros ... 83 

(12)

Lista de Figuras

Figura 1 Defeito x Erro x Falha ... 18 

Figura 2 Teste caixa-preta ... 19 

Figura 3 Seleção de entradas ... 19 

Figura 4 Classes de Equivalência ... 20 

Figura 5 Modelo V: Atividades de desenvolvimento x Níveis de teste ... 21 

Figura 6 Arquitetura do JUnit ... 23 

Figura 7 Código para teste FitNesse ... 24 

Figura 8 Ciclo de atividades POP. Extraído de Mendonça ... 26 

Figura 9 Fluxo de desenvolvimento: (a) POPT + teste cego (b) teste cego. ... 33 

Figura 10 Ciclo de atividades POPT ... 35 

Figura 11 Execução do TestBoot ... 39 

Figura 12 Diagrama de classes do TestBoot ... 42 

Figura 13 Transformação do código ... 44 

Figura 14 Diagrama de sequência Build ... 45 

Figura 15 Diagrama de sequência TestBoot ... 46 

Figura 16 Diagrama de sequência Tester ... 47 

Figura 17 Arquitetura do sistema de submissão ... 48 

Figura 18 Base de dados TestBoot ... 49 

Figura 19 opening.php - página inicial ... 49 

Figura 20 enter.php - página de acesso ... 49 

Figura 21 register.php - página de cadastro ... 50 

Figura 22 homePage.php - lista de problemas POPT e não-POPT ... 50 

Figura 23 problem.php - página de problema POPT ... 50 

Figura 24 problem.php - página de problema não-POPT ... 51 

Figura 25 Testes x Tempo: (a) primeira versão (b) última versão ... 59 

Figura 26 Testes x versão: (a) Não-POPT (b) POPT. ... 60 

Figura 27 Gráfico Box-Plot ... 68 

Figura 28 Desempenho individual dos alunos ... 69 

Figura 29 Papel de probabilidade ... 70 

Figura 30 Histograma ... 70 

(13)
(14)

Lista de Tabelas

Tabela 1 Tabela FitNesse ... 24 

Tabela 2 POP x Não-POP: Requisitos Documentados ... 27 

Tabela 3 Design Quadrado Latino ... 29 

Tabela 4 Índice de Massa Corporal ... 33 

Tabela 5 Tabela TestBoot ... 34 

Tabela 6 Conversa entre Tutor e Aluno ... 36 

Tabela 7 Testes com entradas inválidas ... 37 

Tabela 8 Testes com valores limites ... 38 

Tabela 9 Testes com interação completa ... 38 

Tabela 10 Quantidade de testes e códigos com erros detectados ... 55 

Tabela 11 POPT: tempo x testes. ... 56 

Tabela 12 Não-POPT: tempo x testes. ... 56 

Tabela 13 POPT: versões x testes x tempo ... 57 

Tabela 14 Não-POPT: versões x testes x tempo ... 57 

Tabela 15 Versões: POPT x Não-POPT ... 58 

Tabela 16 Tempo x testes: POPT x Não-POPT... 61 

Tabela 17 Ameaças a Validade do Estudo ... 64 

Tabela 18 Exemplos de réplicas do quadrado latino ... 66 

Tabela 19 Etapas do experimento ... 67 

Tabela 20 Média e Desvio Padrão ... 68 

Tabela 21 Tabela ANOVA... 71 

Tabela 22 Ameaças a validade do experimento ... 73 

(15)

13

1 Introdução

Podemos perceber um interesse crescente da comunidade de ensino de Ciência da Computação para inclusão de conceitos de testes nas disciplinas iniciais de programação (Cowling, 2012; Desai et al. 2008, 2009; Janzen e Saiedian, 2006, 2008). No entanto, inserir conceitos de teste de software para alunos iniciantes dos Cursos de Ciência da Computação pode ser particularmente difícil, pois além de aprender as estruturas básicas de programação (e.g., estruturas de controle, estruturas de repetição, comandos de entrada e saída), os alunos precisam lidar com as peculiaridades das técnicas e ferramentas de testes. Por esse motivo, as grades curriculares muitas vezes relegam tópicos de teste para períodos mais avançados ou cursos separados, fazendo com que os alunos pensem que teste de software é difícil, menos importante, ou opcional (Cowling, 2012).

Além disso, os estudos também apontaram que os alunos têm dificuldades em lidar com o entendimento de problemas mal definidos, dificultando a especificação de requisitos. Algumas destas dificuldades incluem: identificar e eliminar ambigüidades em especificações de software (Blaha et al., 2005), e formular perguntas para esclarecer requisitos(Mendonça, Guerrero e Costa, 2009b). Como tais dificuldades tendem a persistir ao longo da prática profissional dos alunos (Conn, 2002; Nauman e Uzair, 2007), há uma necessidade de abordagens de ensino que visem focar no desenvolvimento de tais habilidades. Tradicionalmente, os cursos de programação focam na solução de problemas bem definidos, ensinando a sintaxe da linguagem de programação, não permitindo que o aluno desenvolva as habilidades necessárias para superar tais dificuldades (Pears, 2007).

1.1 Solução proposta

(16)

14

alunos são estimulados a desenvolver casos de teste formatados em uma tabela. Tais testes ajudam a ampliar o entendimento sobre os requisitos dos problemas e também melhorar a qualidade do código gerado.

Este conceito é apoiado por uma ferramenta chamada TestBoot, que traz os conceitos de tabelas FIT (Mugridge e Cunningham, 2005) para permitir que os alunos iniciantes definam tabelas simples baseadas em dados de entrada e saída de testes sem a necessidade de aprender uma API específica de framework de testes específicos, ou alterar a estrutura do programa para permitir o uso de assertivas (como proposto por outras abordagens, tais como ensino dirigido a testes (Janzen e Saiedian, 2006a, 2008a)).

1.2 Objetivos

A dissertação tem como objetivo principal propor uma abordagem de ensino de teste de software para alunos dos cursos introdutórios de programação. Além disso, o trabalho apresenta os seguintes objetivos específicos:

 Estudo das abordagens existentes para ensino de testes, identificando as limitações dessas abordagens.

 Propor uma metodologia de ensino que introduza conceitos de teste de software aos alunos dos cursos introdutórios de programação.  Desenvolver uma ferramenta para apoiar a construção e execução

dos testes, permitindo o uso de conceitos de testes de software sem adicionar complexidade na programação e na realização dos testes.  Realizar um estudo de caso em um ambiente de ensino real para

avaliar os reais benefícios da metodologia proposta com suporte a ferramenta desenvolvida para automação de testes.

(17)

15

1.3 Contribuições

Como principais contribuições deste trabalho, podemos citar: a metodologia POPT, a ferramenta de apoio TestBoot, o sistema web para submissão de versões (usado para registrar o fluxo de trabalho da metodologia POPT), o estudo de caso e o experimento realizados para avaliar a eficácia do uso combinado da metodologia e da ferramenta.

O estudo de caso comparou a metodologia POPT (acompanhada da ferramenta TestBoot) com um teste cego. Muitas vezes utilizado para a correção automática de exercícios de alunos em cursos de programação, o teste cego avalia os códigos dos alunos aplicando um conjunto de testes automatizados definidos pelo professor, exibindo apenas o resultado dos testes. Parte dos resultados obtidos neste estudo de caso foi publicada no seguinte artigo, que se encontra no Apêndice A:

LUSTOSA NETO, V.; COELHO, R. S.; LEITE, L.; GUERRERO, D. S.; MENDONCA, A. POPT: A Problem-Oriented Programming and Testing Approach for Novice Students. In: 35th International Conference on Software Engineering

(ICSE 2013), May 1826, 2013, San Francisco

Após este estudo de caso foi realizado o experimento controlado utilizando o design do Quadrado Latino, o qual avaliou a influencia da metodologia e de outros fatores (como problema utilizado, aluno alocado para o problema) na qualidade do código desenvolvido pelos alunos POPT.

1.4 Organização do trabalho

O restante deste trabalho está organizado da seguinte forma:

O Capitulo 2 apresenta brevemente os conceitos de Teste de Software e Programação Orientada a Problema.

O Capitulo 3 descreve a metodologia POPT e seu ciclo de atividades. O Capitulo 4 apresenta a ferramenta TestBoot e o sistema de submissão criado para auxiliar a execução do experimento.

(18)

16

O Capitulo 6 apresenta um experimento para avaliar a metodologia POPT utilizando a técnica de quadrado latino para análise estatística.

O Capitulo 7 descrevemos trabalhos relacionados.

(19)

17

2 Fundamentação Teórica

O objetivo deste capítulo é apresentar uma fundamentação teórica dos conceitos necessários para o entendimento deste trabalho. Inicialmente será apresentado o conceito de teste de software, definindo as principais técnicas de teste utilizada e os diferentes níveis de testes realizados nas fases de desenvolvimento de um software. Em seguida, serão apresentadas ferramentas de automação de testes e uma metodologia de ensino de iniciação a programação que introduz o uso de assertivas para criação de testes pelos alunos.

2.1 Conceitos Básicos

É necessário estabelecer algumas definições, antes de apresentar o conceito de teste de software. É fundamental conhecer a diferença entre defeitos, erros e falhas. As definições que se seguem estão presentes na terminologia padrão para Engenharia de Software do IEEE – Institute of Electrical and Electronics Engineers – (IEEE 610.12, 1990).

 Defeito: Problema de especificação, projeto ou implementação. Por exemplo, uma instrução incorreta em um software.

 Erro: O desvio da especificação, ou seja, a diferença entre o valor obtido e o valor esperado.

 Falha: Um resultado incorreto. Por exemplo, o resultado calculado foi 12, quando o resultado correto deveria ser 10.

(20)

18

Figura 1 Defeito x Erro x Falha

2.2 Teste de Software

O Teste de Software é um processo de verificação que consiste em executar um sistema com o objetivo de encontrar defeitos (Myers, 2004). A realização de testes aumenta a confiabilidade ao software, agregando qualidade através da remoção de erros.

Portanto, mais do que demonstrar a execução correta de um programa, devemos considerar que o software possui erros (uma hipótese válida para quase todo tipo de programa) e utilizar técnicas para descobri-los. Estabelecendo uma conduta investigativa, alterando realmente a postura de programador para testador para então testar o programa para encontrar o maior número de erros possíveis.

Para realização desta tarefa, existem algumas estratégias conhecidas. Duas das estratégias mais comuns são testes funcionais (testes caixa-preta) e testes estruturais (testes caixa-branca), que iremos explorar nas próximas duas seções.

2.2.1 Testes funcionais (ou testes caixa-preta)

(21)

19

esforço do testador será determinar quais entradas fornecidas ao software geram saídas não esperadas de acordo com a especificação do sistema.

Figura 2 Teste caixa-preta

Para encontrar todos os erros de um software, seria necessário realizar testes com todas as entradas possíveis, mas mesmos para simples programas, as situações tendem ao infinito. Portanto, é necessário estabelecer critérios de seleção de casos de testes que mantenham ao máximo a cobertura de erros existentes em um software.

O objetivo agora, representado na Figura 3, é criar um subconjunto finito de entradas selecionadas que se aproxime do subconjunto de entradas que geram erros, quanto maior a cobertura dos erros, mais eficiente será o critério utilizado.

Figura 3 Seleção de entradas

Serão apresentados nas próximas seções dois critérios de testes funcionais que visam auxiliar na escolha de entradas, com o objetivo de aumentar as chances de revelar as falhas do programa.

2.2.1.1 Classes de equivalência

(22)

20

subconjunto, como ilustrado na Figura 4. Assim, se uma entrada detectar um erro, o valor representativo de seu subconjunto também será capaz de reconhecer o mesmo erro (Ammann e Offutt, 2008; Pezze e Young, 2007; Delamaro, Maldonado e Jino, 2007).

Figura 4 Classes de Equivalência

2.2.1.2 Valores limites

Existe maior probabilidade de encontrar erros em um software com casos de testes que exploram situações limites. Essas situações são basicamente os valores superiores e inferiores das classes de equivalência. Seleção de casos de testes por valores limites, diferentemente da geração por análise de particionamento de equivalência, seleciona mais de um valor de entrada, considerando os extremos de cada subconjunto.

2.3 Testes estruturais (ou testes caixa-branca)

Também de acordo com Meyers (2004), diferentemente dos testes funcionais, os testes estruturais permite que você examine a estrutura interna do programa. Esta estratégia gera casos de testes a partir de uma análise da lógica do programa.

(23)

21

2.4 Níveis de teste

Uma das questões fundamentais na área de teste de software é quando devemos realizar os testes. Está questão vai além da execução dos testes, mas também do planejamento e criação dos testes.

O ideal é que os processos de teste de software acompanhem o ciclo de desenvolvimento do software. De acordo com o modelo de Craig e Jaskiel (2002), separando em níveis de testes, podemos observar na Figura 5 que o planejamento dos testes é efetuado de cima para baixo e sua execução é realizada de baixo para cima.

Figura 5 Modelo V: Atividades de desenvolvimento x Níveis de teste

Uma descrição básica dos níveis de testes é a seguinte:

 Teste de unidade: Esse nível de teste tem por objetivo testar a menor unidade do software, tentando provocar falhas de regra de negocio. Esse teste é feito por pequenos trechos de código isoladamente.  Teste de integração: Verifica se há falhas entre os módulos ou

interfaces, quando esses são integrados ao tentar fazer o funcionamento de um todo.

(24)

22

 Teste de aceitação: No inicio do desenvolvimento são declarados quais serão as funcionalidades que serão testadas para que o software seja declarado como entregue, esse nível de testes são efetuados geralmente por um grupo de usuários que verificam algumas funcionalidades para que o software seja considerado como aceito.

2.5 Automação de testes

De acordo com Fewster e Graham (1999), a automação de testes pode reduzir de maneira significativa o esforço necessário para realizar este processo, ou aumentar a quantidade de testes que podem ser realizados dentro de um tempo limitado.

Com o objetivo de automatizar parte deste processo, algumas ferramentas vêm sendo propostas. A automação de testes de software é o desenvolvimento de um sistema capaz de realizar o teste. Assim, um grande número de casos de teste pode ser validado rapidamente. As vantagens da automação tornam-se mais evidentes para os casos de softwares que possuem longa vida no mercado, devido ao fato de que até mesmo pequenas correções no código da aplicação podem causar a quebra de funcionalidades que antes funcionavam.

Uma prática comum no desenvolvimento de software é o uso de plataformas xUnit, que permitem realizar teste de unidade para determinar se os trechos do código estão processando de forma esperada em diversas circunstâncias. A plataforma xUnit mais conhecida atualmente é a Junit, que será apresentada na próxima seção.

2.6 JUnit

(25)

23

Figura 6 Arquitetura do JUnit

Como pode ser observado na Figura 6, no JUnit um teste de unidade corresponde a uma classe que estende a classe TestCase, está é a principal classe da arquitetura deste framework. Suas classes-filhas definem testes individuais que validam métodos de uma classe-alvo (o código que desejamos testar). Os testes assim criados podem ser adicionados em um objeto da classe TestSuite, que pode armazenar também outros conjuntos (TestSuite), assim todos os testes podem ser invocados com uma única chamada e o resultado armazenado em um objeto da classe TestResult para posterior analise

2.7 FITNESSE

FitNesse é uma ferramenta de colaboração para desenvolvimento de software que tem por objetivo integrar clientes, testadores e programadores, comparando as expectativas dos clientes com os resultados reais do sistema.

(26)

24

Tabela 1 Tabela FitNesse

A tabela será criada no FitNesse e o teste será realizado pela integração do código-alvo através de uma API FIT, a Figura 7 demonstra um código escrito para os testes descritos Tabela 1.

Figura 7 Código para teste FitNesse

Ferramentas FIT têm foco na integração entre os diferentes atores do processo de desenvolvimento (cliente, testador e programador), mas demanda esforço adicional para serem utilizadas na prática, dificultando a aplicação desta ferramenta nas atividades de aprendizado de programação.

2.8 Test-Driven Development

(27)

25

Em TDD, a elaboração dos testes precede o código de produção que eles exercitam. A dinâmica única que define TDD em grande parte decorre deste sequenciamento especial de atividades. A escrita do código de produção após o código de teste é o aspecto mais marcante do TDD.

2.9 Programação Orientada a Problema

De acordo com as diretrizes curriculares de cursos da área de computação e informática [MEC/SESU, 1999], o ensino de programação é entendido como:

Programação de computadores é uma atividade voltada à solução de problemas. Nesse sentido ela está relacionada com uma variada gama de outras atividades como especificação, projeto, validação, modelagem e estruturação de programas e dados, utilizando-se das linguagens de programação propriamente ditas, como ferramentas.

Consideremos mais a fundo a atividade de solucionar um problema, Mendonça (2010) apresenta duas relacionadas a esta atividade:

 Espaço do problema: descrição e caracterização do problema a ser resolvido. Portanto, o termo está associado à definição “do que” deve ser feito.

 Espaço da solução: conjunto das soluções possíveis para um dado problema. Portanto, o termo está associado ao “como” o problema será solucionado.

Sendo que na maioria das ementas das disciplinas de introdução a programação concentra-se muito mais esforços na construção de programas, desenvolvimento do raciocínio lógico e aprendizagem da sintaxe de uma linguagem de programação do que no entendimento do problema antes de prover uma solução para o mesmo.

Este desbalanceamento entre o espaço do problema e o espaço da solução no ensino de programação é evidenciado pela forma como os problemas são apresentados aos alunos.

(28)

26

entendimento do problema é facilitado e os estudantes podem concentrar seus esforços na elaboração e implementação de uma solução para o problema proposto.

Esta abordagem de ensino que considera apenas problemas bem definidos, apesar de desenvolver habilidades importantes e necessárias para o domínio da programação, restringe o aprendizado do aluno. Podendo gerar dificuldades em lidar com situações que exigem habilidades para entendimento de problemas.

POP é uma metodologia de ensino para disciplinas introdutórias de programação que se caracteriza por um conjunto de atividades organizadas em um ciclo de resolução de problemas que põe em prática atividades típica da Engenharia de Software, tais como, elicitação e especificação de requisitos, testes e programação.

O objetivo de POP é melhorar o aprendizado da prática de programação através de uma experiência mais completado papel de desenvolvedor, permitindo-lhes: iniciar com uma especificação mal definida; interagir com um cliente; construir outros artefatos além do programa; prover melhorias nestes artefatos; e, trabalhar tanto em grupo quanto individualmente.

Figura 8 Ciclo de atividades POP. Extraído de Mendonça

(29)

27

desse ponto, o aluno deve elaborar uma especificação auxiliado por um cliente-tutor que responderá quaisquer dúvidas sobre o problema.

Juntamente com a especificação inicial, testes são definidos. Estes artefatos servirão como guia para o desenvolvimento da primeira versão do programa e construção de testes automáticos para validação da solução.

Entregue a primeira versão do programa, o aluno, juntamente com o tutor-cliente, conclui a especificação, finalizando também a elaboração dos testes para que se conclua o ciclo POP com o desenvolvimento final do programa e dos testes automáticos.

No final, o aluno que passou por todo o ciclo POP, terá desenvolvido não apenas o código do programa, mas um documento de especificação e testes automáticos para avaliação da implementação.

A Tabela 2 apresenta os resultados de dois estudos realizados sobre a abordagem de ensino POP. Foi perceptível uma melhora na habilidade de entendimento do problema para os alunos que foram submetidos à metodologia de ensino com relação aos alunos que não foram submetidos à metodologia.

Tabela 2 POP x Não-POP: Requisitos Documentados

Portanto, POP contribuiu para o entendimento do problema, considerando o aprendizado não apenas em “como” o problema deve ser solucionado, mas também “o que” deve ser feito.

Porém, foram detectados nos estudos de casos da metodologia dificuldades na elaboração dos testes automáticos por parte dos alunos que participaram dos experimentos, pois os mesmos tinham que entender o uso de assertivas e criar código adicional para geração dos testes executados.

Grupos Requisitos Documentados Corretamente

(30)

28

2.10 Engenharia de Software Experimental

A pesquisa científica é um processo de aprendizado guiado (Box, Hunter e Hunter, 2005). De acordo com Wohlin, a realização de estudos empíricos quantitativos é a oportunidade de obter resultados objetivos e estatisticamente significativos em relação ao entendimento, controle, previsão e melhoria do desenvolvimento de software. Dessa forma, antes de introduzir um novo método, processo ou uma nova forma de trabalhar, é preferível uma avaliação empírica das características, prós e contras, de tais mudanças.

Estudos de caso são formas de avaliação para realizar uma simples investigação. Dentro da engenharia de software, estudos de caso podem ser usados, por exemplo, para comparação de diferentes tratamentos. No entanto, estudos de casos apresentam um baixo grau de controle de fatores. Por esta razão, as conclusões obtidas a partir de estudos de casos não podem ser generalizadas.

Por outro lado, experimentos controlados, além de coletaremos dados das métricas que comparam dois ou mais tratamentos, controlam outras variáveis que podem apresentar influência nos resultados. Além disso, os resultados de uma experiência controlada são expressos em termos de certo grau de confiança, fornecida por um teste de significância estatística que pode ser generalizado.

Ao realizar um experimento controlado, o pesquisador está interessado além das métricas e definição de tratamentos, o experimentador também precisa prestar atenção a outros fatores que podem influenciar o resultado do processo. Este tipo de influência indesejada é comumente chamado de ruído em estudos empíricos.

Desta forma o experimento controlado é organizar os tratamentos, as métricas e os fatores de uma forma que permita a repetição do experimento em diversas unidades experimentais.

Os tratamentos devem ser dispostos de uma forma que permitam uma chance igual para serem designados por qualquer unidade experimental e assim os fatores influentes podem ser controlados.

(31)

29

Tabela 3, por exemplo, descreve um quadrado latino para um experimento com três tratamentos A, B e C. Desta forma, as linhas representam um fator controlado e as colunas o segundo fator controlado.

Tabela 3 Design Quadrado Latino

Após a execução do experimento, o pesquisador analisa as métricas avaliadas, a fim de responder a algumas perguntas de pesquisa. Mas é preciso realizar uma análise estatística para verificar se os resultados podem ser generalizados.

Para está análise é realizado um teste de hipóteses. Na fase de planejamento do experimento duas hipóteses são formuladas, a hipótese nula e as hipóteses alternativas.

A hipótese nula geralmente afirma que não existe diferença significativa entre os tratamentos do experimento. Por outro lado, a hipótese alternativa é aquela rejeita a hipótese nula.

(32)

30

3 Metodologia Proposta

O objetivo deste capítulo é apresentar a abordagem de ensino POPT. Um exemplo motivador é apresentado na seção 3.1. Logo em seguida serão apresentadas na seção 3.3 as práticas utilizadas. Na seção 3.4 é descrito o fluxo de trabalho de POPT, seguido de uma lista de conceitos básicos apresentados aos alunos na seção 3.5. Demais etapas de POPT serão apresentadas na seção 3.5. O capítulo conclui na seção 3.6 com algumas discussões sobre as seções anteriores.

3.1 Visão geral

Estudos anteriores (Mendonça et al, 2009, 2010) propuseram uma metodologia de ensino de programação orientada a problema, chamada de Programação Orientada a Problema (POP). De acordo com o POP, a resolução de problemas deve ser realizada em ciclos, começando com um problema mal-definido. Para resolvê-lo, os alunos devem obter os requisitos com alguém jogando o papel do cliente, geralmente um assistente de ensino, chamado tutor nesta metodologia. Os alunos são estimulados a fazer perguntas para o professor, a fim de progressivamente esclarecer a especificação de requisitos, e escrever assertivas para expressar testes de software. Esta metodologia leva em consideração que no ambiente real de desenvolvimento, os programadores poderão receber problemas mal definidos e precisam, portanto, serem estimulados no ambiente acadêmico para lidar com este cenário.

(33)

31

3.2 Participantes e Papéis

Participam de POPT: professor, assistentes e alunos. No ciclo de atividades de POPT, o professor e os assistentes desempenham o papel de tutores e os alunos assumem o papel de desenvolvedores.

Os tutores devem responder aos questionamentos dos estudantes sobre os requisitos do programa.

Os desenvolvedores têm a responsabilidade de elaborar os casos de testes em uma tabela de dados de entrada e saída e implementar o código do programa para enviá-los ao sistema de submissão.

Está formatação dos testes é inspirada nas tabelas do framework de testes integrados FitNess. Assim simplificamos o processo de teste para a elaboração de testes de aceitação presentes na tabela construída.

Nos Apêndices B e C, nós apresentamos orientações sobre como os tutores e desenvolvedores devem proceder no ciclo de atividades POPT.

3.3 Práticas POPT

POPT baseia-se nos seguintes práticas:

 Entendimento dos requisitos guiado por testes. Em POPT, uma especificação mal definida é esclarecida através de questões relacionadas à como tal especificação pode ser exercitada. Ela estimula o aluno a pensar sobre os valores mais utilizados e os valores limites que o programa pode receber. Está prática se aproxima do conceito básico presente na abordagem TDD, onde o teste deve ser elaborado antes da escrita do código de produção.

 Simples construção de casos de teste. Os testes devem ser construídos na forma de tabelas de entradas e saídas. Ao longo do processo, estas tabelas serviram como testes automatizados, sem a necessidade da intervenção do aluno.

(34)

32

entrada e saída de dados com o console do computador durante a programação (Desai,Janzen e Clements, 2009; Briggs e Girard, 2007). Mudar a forma como estes alunos implementam seus primeiros programas podem impedi-los de adicionar testes no programa, e abandonarem a adoção de toda a metodologia. Assim, os casos de teste em POPT preservam o estilo de interação do programa.

 Teste independente. Esta prática indica que não há necessidade de código adicional para a construção dos testes. Seguindo a idéia das iniciativas de Briggs e Girard (2007), a construção dos testes deve ser feita separadamente da programação,no sentido de que durante a programação devemos encontrar formas de melhorar a confiança sobre o que estamos implementando.

 Qualidade sem nome. Esta prática afirma que não há necessidade de nomear os critérios de teste explicados. O conceito básico de valores limites e particionamento de entradas (Ammann e Offutt, 2008) podem ser abordados durante as aulas de programação. Os conceitos de teste são dados como parte do curso de programação como forma dos alunos poderem esclarecer o problema.

3.4 Fluxo de Trabalho

O fluxo de trabalho de POPT encontra-se ilustrado na Figura 9. Ele baseia-se na fluxo de trabalho proposto por POP: os alunos recebem um problema mal definido e devem resolvê-lo, fazendo perguntas específicas para um tutor. No entanto, em POPT as perguntas feitas ao tutor são sistematicamente definidas para guiar a construção de casos de teste, os quais podem ser valores normais ou valores limites que a solução deve tratar. Para apoiar o aluno durante a definição e execução dos casos de teste, foi desenvolvida uma ferramenta de teste chamado TestBoot.

(35)

33

Figura 9 Fluxo de desenvolvimento: (a) POPT + teste cego (b) teste cego.

TestBoot é uma ferramenta desenvolvida com o propósito de ajudar os alunos de cursos de programação a começar a desenvolver casos de teste. Os alunos precisam preencher uma simples tabela, inspirada nas tabelas dos frameworks FIT, tornando mais fácil para os alunos a definição dos casos de teste. Mas diferente dos frameworks de testes integrados (FIT) e das ferramentas de testes unitários XUnit, não é necessário aprender qualquer estrutura de API de testes ou alterar a estrutura dos programas implementados, de modo a torná-los testáveis por métodos de assertivas propostos por iniciativas de ensino dirigido a teste (Janzen e Saiedian, 2006a, 2008a; Briggs e Girard, 2007).

Considere o problema de cálculo do índice de massa corporal (IMC), que possui como dados de entrada o peso e a altura e tem como saída apenas um texto informando se o IMC está abaixo, acima ou no peso ideal. A Tabela 4 apresenta uma relação de valores de IMC e a situação para cada caso

Tabela 4 Índice de Massa Corporal

(36)

34

interrogação implicam que essa coluna corresponde a um conjunto de dados de saída, e o restante das colunas correspondem aos dados de entrada.

Tabela 5 Tabela TestBoot

A fim de executar os testes o aluno só precisa enviar o programa implementado e as planilhas como parâmetros para o TestBoot. Em seguida, ele alimenta o programa do aluno com os dados definidos como entradas e verifica se as saídas correspondem com os especificados na planilha. Os relatórios do TestBoot mostram o status de teste para o usuário no console padrão. Os programas dos alunos podem continuar usando as funções padrões para entrada e saída em C/C++ printf e scanf (únicas reconhecidas pelo sistema de teste) sem a necessidade de uma API para utilizar TestBoot.A seguir detalhamos cada um dos passos que compõem a metodologia POPT que estende POP.

3.5 Conceitos Básicos apresentados aos alunos

(37)

35

Figura 10 Ciclo de atividades POPT

As próximas seções irão abordar cada passo presente nesta representação, descrevendo cada atividade presente na metodologia POPT.

3.5.1 Passo 1: Receber Problema Mal-Definido

No início do processo, o aluno recebe um documento com o enunciado do problema, este artefato apresenta uma descrição incompleta e inconsistente de acordo com os conceitos presentes na programação orientada ao problema. Desta forma o aluno precisa complementar informações sobre o problema a partir da comunicação com o tutor que assumirá o papel de cliente e responderá as perguntas do aluno. O segundo passo descreve a forma de interação exigida neste diálogo.

3.5.2 Passo 2: Fazer Perguntas ao Tutor

(38)

36

Para preparar o aluno para encarar problemas mal-definidos, foi apresentado aos alunos uma simulação desta etapa, apresentando exemplos de problemas mal-definidos e como detectar os pontos críticos para serem esclarecidos com perguntas enviadas ao tutor-cliente.

A Tabela 6 apresenta um exemplo de diálogo entre aluno e tutor-cliente. O apêndice F apresenta um tutorial para guiar o comportamento dos tutores neste contato com os alunos.

Tabela 6 Conversa entre Tutor e Aluno

Para facilitar a interação entre tutores e alunos e o registro dos diálogos, o canal de comunicação utilizado nas atividades da metodologia POPT foi através de um aplicativo de bate-papo. Desta forma os tempos de espera por resposta não ultrapassaram 1 minuto nas atividades realizadas, não comprometendo o desempenho dos alunos.

Respondidas as questões relevantes ao enunciado, o aluno terá condições de elaborar os testes para serem utilizados na ferramenta TestBoot.

Considerando o problema IMC apresentado, podemos citar problemas de enunciado decorrente a ausência de informação sobre o calculo do índice e a grandeza utilizada para o peso (quilograma ou grama) e altura (metro ou centímetro).

3.5.3 Passo 3: Escrever testes no TestBoot

(39)

37

de seleção de testes apresentados de forma simplificada e sem considerar detalhes das definições presentes na literatura de teste de software.

3.5.3.1 Classes de equivalência.

Algumas orientações foram apresentadas para subdividir o conjunto total de testes em categorias. Essa divisão levou em conta não apenas valores válidos de entrada, mas dados inválidos que são freqüentemente negligenciados no desenvolvimento do software.

Foi aconselhado aos alunos em subdividir os testes considerando:

 Intervalo de valores: Caso uma condição de entrada especifica um intervalo de valores, adicione testes considerando um valor abaixo do intervalo, um valor acima do intervalo e um pertencente ao intervalo.  Quantidade de valores: Caso uma condição especifica a entrada de

uma quantidade de valores, adicione testes considerando uma quantidade abaixo do esperado, acima do esperado e uma quantidade válida de valores de entrada.

 Conjunto de valores: Para cada valor, adicionar um teste. Além disso, por fim adicionar um teste para um valor fora do conjunto especificado. Então, se considerarmos o problema do calculo do IMC, logo após as orientações sobre classes de equivalência, a tabela de testes aumentaria para a representação da Tabela 7.

Tabela 7 Testes com entradas inválidas

3.5.3.2 Valores Limites.

(40)

38

entrada. Com isso, novos casos de testes devem ser adicionados, como visto na Tabela 8.

Tabela 8 Testes com valores limites

Também orientamos os alunos para expandir os testes considerando toda as etapas de interação entre usuário e software. Então podemos alterar os testes para considerar etapas de entrada e saída muitas vezes negligenciadas nos testes como observado na Tabela 9.

Tabela 9 Testes com interação completa

3.5.4 Passo 4: Elaborar o código

Criado os testes, o aluno terá um entendimento completo da especificação do problema e assim será capaz de escrever um código para solucionar o problema.

3.5.5 Passo 5: Executar testes no TestBoot

(41)

39

A Figura 11 apresenta uma execução da ferramenta e o resultado, exibindo quais testes falharam decorrentes a erro de execução ou ao limite de processamento excedido.

Figura 11 Execução do TestBoot

Está versão foi utilizada no estudo de caso, mas uma integração maior entre a ferramenta TestBoot e o sistema de submissão foi desenvolvida para permitir a realização de testes submetendo uma planilha escrita em um editor de planilhas comum e o código no sistema de submissão.

3.5.6 Passo 6: Corrigir código

Considerando que TestBoot apresente erros na execução dos testes, o aluno será capaz de modificar o seu código guiado por cada alerta apresentado no passo anterior. Novamente o aluno irá repetir o processo de teste automatizado até passa em todos os seus testes.

3.5.7 Passo 7: Submeter versão do código

(42)

40

3.6 Apresentação das demais etapas de POPT

POPT é composta pelas seguinte etapas: planejamento, preparação, execução e avaliação.

 Planejamento: Etapa na qual o professor deve planejar a aplicação de POP na disciplina introdutória de programação, isto é, deve inseri-la no pinseri-lano de auinseri-la da disciplina. Esta etapa é composta das seguintes atividades:

o definir cronograma da disciplina; o definir critérios de avaliação.

Preparação:Etapa que antecede cada execução de POPT, isto é, etapa que antecede ao ciclo de resolução de problemas de POPT. Esta etapa é composta das seguintes atividades:

o elaborar o problema mal definido que será proposto aos

estudantes;

o listar os requisitos do problema e o conjunto de testes para o

sistema de submissão;

o definir os deadlines;

o definir os recursos para interação dos alunos e tutores; o selecionar e orientar os tutores;

o preparar os alunos para a execução de POPT.

Execução:Etapa na qual há a execução do ciclo de atividades do POPT na disciplina introdutória de programação. Esta etapa foi descrita neste capítulo.

Avaliação:Nesta etapa, o professor tem como atividade avaliar os estudantes e os procedimentos adotados na etapa de execução. Para dar suporte, a ferramenta de submissão registra todas as submissões de código e teste e os tempos.

(43)

41

3.7 Discussões

(44)

42

4 A Ferramenta TestBoot

O objetivo deste capítulo é apresentar a estrutura da ferramenta TestBoot que apóia a abordagem proposta. Uma visão geral da arquitetura é apresentada na seção4.1. As seções seguintes expõem a estrutura de cada componente da ferramenta.

4.1 Arquitetura da TestBoot

A ferramenta TestBoot foi projetada para ser implementada de forma modular e orientada a objetos, na linguagem C++. A Figura 12 ilustra a arquitetura da ferramenta.

(45)

43 4.1.1 Classe Cell

Cada teste é representado por um conjunto de células presentes em uma tabela, assim a classe Cell é responsável pelo armazenamento de cada dado de entrada e saída dos testes.

4.1.2 Classe Test

Este componente é responsável por representar um teste como sendo uma lista de objetos da classe Cell. De acordo com a ordem dos dados de entrada e saída do teste, as chamadas dos métodos de atualização de saída (Test.update) e de envio de dado de entrada (Test.getInput), verificam a igualdade com os dados gerados e solicitados pelo código testado que foi convertido para o método Tester.run da classe Tester.

4.1.3 Classe TestList

Este componente é responsável por gerenciar uma lista de testes, construindo cada objeto da classe Test a partir de um arquivo de testes.

4.1.4 Classe Executor

Este componente permite que o método Executor.run seja executado numa thread independente. Está característica é fundamental para que os testes sejam executados separadamente do processo principal do sistema.

4.1.5 Classe Tester

Este componente herda da classe Executor os recursos de thread independente e sobrescreve o método Executor.run, realizando uma chamada do método Tester.main que foi construído com o código-alvo que será testado.

4.1.6 Classe Parser

(46)

44 4.1.7 Classe Build

Este componente solicita a transformação do código-alvo para a classe Parser, recompila a classe Tester com o novo método Tester.run definido pela classe Parser para as realizações dos testes pela classe TestBoot.

4.2 Como as classes interagem para execução dos testes

Nesta seção serão apresentados alguns diagramas de seqüência para explicar o comportamento do sistema na criação dos testes de acordo com a tabela de testes e execução dos mesmos a partir do código-alvo.

4.3 Lendo os Dados de Entrada da Tabela

Para que o programa do aluno possa, ao invés de receber dados da saída padrão, receba dados de entrada da tabela, uma transformação no código do aluno precisou ser realizada, conforme ilustrado na Figura 13.

Figura 13 Transformação do código

(47)

45

Figura 14 Diagrama de sequência Build

Build recompila a classe Tester (passo 2) e realiza uma chamada de sistema para execução de TestBoot (passo 3), que realizará a sequência de testes com um novo “testador” compilado.

4.4 Executando Múltiplos Testes

(48)

46

Figura 15 Diagrama de sequência TestBoot

(49)

47

Figura 16 Diagrama de sequência Tester

Finalizado a execução, Tester informa o fim do teste para a classe Test para finalização dos dados para um teste bem sucedido, caso tenha concluído com êxito a simulação.

4.5 Interface da Ferramenta

Com o objetivo de facilitar o registro das submissões de versões e validação através da execução dos testes por parte dos alunos foi criado um sistema Web utilizando linguagem PHP para realizar um simples cadastro de testadores e oferece acesso a uma lista de problemas POPT e não-POPT.

(50)

48

cadastro (checkRegister.php), acesso (checkEnter.php) e submissão de código e teste (result.php).

Figura 17 Arquitetura do sistema de submissão

(51)

49

Figura 18 Base de dados TestBoot

Como pode ser observado, cada problema pode ser classificado como POPT e não-POPT pelo atributo POPT da entidade problema que pode receber quaisquer quantidade de respostas dos testadores. A entidade resposta além de possui atributos para armazenamento do código e planilha de testes registra a data e hora para posterior análise de tempo decorrido entre as versões enviadas.Segue-se uma lista de figuras que apresentam as principais telas de interação com o sistema Web.

Figura 19 opening.php - página inicial

(52)

50

Figura 21 register.php - página de cadastro

Figura 22 homePage.php - lista de problemas POPT e não-POPT

(53)

51

(54)

52

5 Estudo de Caso

Este capítulo apresenta um estudo de caso que foi realizado para avaliar a eficácia da abordagem proposta. Na seção 5.1apresentamos o contexto em que o estudo foi realizado. Na seção5.2, descrevemos a sistemática do estudo e seus resultados. Por fim, na seção 5.4realizamos o fechamento do capítulo.

5.1 Organização do Estudo

De acordo com o processo proposto por Wohlin et al. (2000), o objetivo do nosso estudo pode ser definido de acordo com o modelo GQM, como segue:

Comparar às abordagens POPT e a abordagem de teste cego,no contexto de disciplinas de introdução a programação, com relação: ao tempo gasto para implementar os programas; a qualidade de cada programa (i.e número de testes que passam na execução do programa) e o esforço para identificar e corrigir falhas antes de submeter versões.

A partir do objetivo definido anteriormente, podemos derivar as seguintes perguntas e métricas associadas:

 RQ1. POPT pode ajudar os alunos a obter implementações mais corretas do que a abordagem tradicional baseada em teste cego?  Métrica: # TP - O número de casos de teste (definido pelo professor)

que passou contra o programa submetido pelo aluno na ferramenta de teste cego.

 RQ2. Os alunos que adotaram POPT desprendem mais esforço para identificar e corrigir falhas antes de submeter versões?

 Métrica: # VS - Número de versões submetidas por aluno.

 RQ3. Os programadores POPT gastam mais tempo para entregar a implementação do que os programadores tradicionais?

(55)

53 5.1.1 Participantes

Este estudo foi realizado em uma turma iniciante do curso de Ciência da Computação da Universidade Federal do Rio Grande do Norte, durante o primeiro Semestre de 2012. Os alunos foram divididos em dois grupos, e apenas um grupo foi exposto aos novos conceitos de POPT e TestBoot. Ambos os grupos receberam um problema mal definido e desenvolveram uma solução para ele. Eles poderiam enviar várias versões do código, dentro de um período previamente estabelecido.

Como em nosso estudo, foi necessário comparar duas metodologias de ensino (ou seja POPT contra Teste Cego), optou-se por dividir aleatoriamente os alunos em dois grupos. A fim de avaliar a experiência de cada grupo, foi aplicado um questionário em anexo no apêndice G. Os resultados mostraram que ambos os grupos de alunos iniciantes tinham experiência equivalente. Um total de 30 alunos foi inicialmente previsto para participar neste estudo, mas como o estudo de caso foi conduzido em dias de aula regulares, alguns alunos não assistiram às aulas em que o estudo foi realizado. Resultando em 12 alunos do grupo POPT e oito alunos do grupo de testes cego efetivamente participaram do estudo. Na seção 5.3 discutiremos as conseqüências desta diferença de participantes em cada grupo.

5.1.2 Problema Alvo

Uma decisão importante sobre a definição do estudo de caso foi o desenvolvimento do problema alvo. Ele deve estar no mesmo nível de complexidade que os alunos foram submetidos e não deve requer qualquer conhecimento específico para ser resolvido. O problema alvo escolhido foi o seguinte: Tendo em conta a altura e peso de uma pessoa, o programa deve calcular e retornar o Índice de Massa Corporal (IMC) e com base no IMC calculado e a categoria no MixedMartialArts (MMA) que a pessoa pode tomar parte. Uma especificação mal definida para este programa omitiu como o Índice de Massa Corporal (IMC) deve ser calculado e as categorias de peso.

(56)

54

propusemos um problema que poderia ser resolvido em tal quantidade de tempo. Para determinar esse tempo, três alunos (com habilidades equivalentes aos alunos participantes do estudo) foram convidados a resolver o problema antes da experiência, e levaram aproximadamente 2hs para resolvê-lo.

Considerando o tempo dos alunos convidados para avaliação do problema alvo, foi estabelecido um período total de 3hs para resolução do problema.

5.1.3 Casos de Teste

Neste estudo dois conjuntos de casos de teste foram considerados: (i) o conjunto de testes definido por alunos POPT, e (ii) o conjunto de testes definido pelo professor para avaliar a qualidade externa dos programas submetidos pelos alunos POPT e não-POPT.

Para avaliar a qualidade das soluções implementadas pelos os alunos a este problema, foi desenvolvido um conjunto de testes funcionais. Para construir o conjunto de testes foi aplicado o particionamento de equivalência e a analise dos valores limites. Estes critérios foram usado para selecionar casos de teste representativos do problema, tentando cobrir os requisitos funcionais da especificação. Como resultado obteve-se 52 casos de teste (especificado como uma tabela de entrada e saída esperados para a ferramenta TestBoot como ilustrado no capitulo 2).

Como já referido, os alunos POPT foram estimulados a construir os casos de teste, a fim de esclarecer a especificação mal definida do programa. Como o objetivo principal do desenvolvimento de testes é o de melhorar a qualidade final do produto, independentemente do número de ensaios desenvolvidos, e uma vez que os alunos utilizando a abordagem de teste cego não desenvolveram testes, medimos a eficácia de POPT considerando os testes desenvolvidos pelo professor contra cada versão submetida pelos alunos. Embora seja também interessante

(57)

55

quantidade de testes submetidos juntos com a última versão e a quantidade de códigos que tiveram erros detectados por cada uma das tabelas de testes submetidas pelos alunos para os 10 programas mutantes.

Tabela 10 Quantidade de testes e códigos com erros detectados

Podemos observar que nem sempre uma maior quantidade garante uma maior cobertura para avaliação de código. Pois o aluno a25 possui um total de 18 testes que detectaram falhas em apenas 4 códigos mutantes em relação à tabela de testes do aluno a26 que detectou falhas em todos os 10 códigos mutantes.

O único aluno que não detectou falha em nenhum código mutante foi o aluno a34, este resultado refletiu diretamente no resultado negativo no código submetido pelo aluno que passou em apenas 1 teste.

Desta forma, apesar dos alunos terem realizados testes com algum certo grau de qualidade, é perceptível a necessidade de realizar atividades para elaborar tabelas de testes para adquirir habilidades de um testador.

5.2 Resultados do Estudo

(58)

56

primeira, a segunda, a terceira, e a última versão, e a percentagem de Testes que passaram (ver coluna % PT) para auxiliar a análise. As Tabelas 11 e 12 referem-se a alunos POPT enquanto que as tabelas 13 e 14 referem-se aos alunos não-POPT.

Tabela 11 POPT: tempo x testes.

(59)

57

Tabela 13 POPT: versões x testes x tempo

Tabela 14 Não-POPT: versões x testes x tempo

As Tabelas 13 e 14 também mostram a percentagem de Testes que passaram para cada versão - tais testes são os definidos pelo professor e cegamente executados depois o envio de cada versão. Estas tabelas também ilustram o número de versões submetidas por todos os alunos (ver coluna # SV). A média e a mediana relacionada com as versões submetidas são mostrados na Tabela 15.

(60)

58

Tabela 15 Versões: POPT x Não-POPT

Nas próximas seção,elaboramos respostas para as questões de pesquisa indicados anteriormente por meio da análise dos dados recolhidos durante este estudo. Resultados de medição adicionais a respeito dos testes desenvolvidos por alunos estão disponíveis nos anexos.

5.3 Discussões

A. Pode POPT ajudar os alunos a obter implementações mais corretas do que a abordagem tradicional baseada em teste cego?

Se considerarmos apenas a primeira versão submetida, que elimina o efeito do feedback fornecido pela ferramenta de teste cego, podemos observar que implementações POPT alcançaram em média, mais que o dobro de qualidade do que implementações não-POPT (considerando-se o número de testes que passaram como uma métrica para qualidade). Em média, 60,74% dos testes passaram quando executados contra as primeiras submissões POPT, enquanto apenas, em média, 24,49% dos testes passaram quando executados contra as primeiras submissões não-POPT.

(61)

59

Figura 25 Testes x Tempo: (a) primeira versão (b) última versão

Para nossa surpresa, na última versão dos programas, os alunos não-POPT conseguiram uma qualidade ligeiramente superior (expressa pelo número de testes que passaram) quando comparados aos alunos POPT. No entanto, essa qualidade só pode ser alcançada, porque eles estiveram usando a ferramenta teste cego como uma forma de estar constantemente avaliando a qualidade do seu código. Podemos perceber que este foi um problema ocasionado pelo design do estudo que permitiu aos alunos receberem feedback da ferramenta de submissão para qualquer versão submetida. Esta característica levou a um comportamento inesperado (alunos realizando um número excessivo de submissões, em média 16 versões) que não havia sido contemplado durante a fase de design: alguns alunos utilizaram a ferramenta de teste cego para descobrir se seus programas estavam corretos.

(62)

60

alunos POPT, estes tinham as suas próprias tabelas de testes para orientar o desenvolvimento de sua solução. Como resultado, pudemos observar que os alunos faziam mudanças sem qualquer raciocínio por trás deles, fazendo com que o percentual de testes que passava entre uma versão e outra declinasse bruscamente. A Figura 26 ilustra a forma como a percentagem dos testes que passavam evolui ao longo do tempo. Podemos ver que, em alguns casos, as alterações feita por alunos não-POPT causava uma diminuição brusca do número de testes que passavam (esses casos são ilustrados pelo tracejado nas linhas dos alunos não-POPT). No caso mais extremo, um aluno submeteu códigos quase idênticos mais de 15 vezes, na esperança de passar nos testes. Exigir que os alunos criassem seus próprios testes poderia evitar ou mesmo reduzir tais erros.

Figura 26 Testes x versão: (a) Não-POPT (b) POPT.

B. Os alunos adotando POPT submetem menos versões do que os que utilizam abordagem tradicional?

(63)

61

submetidas por alunos POPT. Alunos não-POPT submeteram, em média, 13,75 versões (desvio padrão = 5,52), enquanto que os alunos POPT submeteram, em média, 7,08 versões (desvio padrão = 5,37).

Essa observação apóia o argumento que os alunos POPT gastam mais tempo pensando sobre os valores esperados para o programa, a fim de melhor compreender o problema e consequentemente implementar um código de melhor qualidade.

C. Os programadores POPT gastam mais tempo para entregar a

implementação do que programadores tradicionais?

Da Tabela 16, podemos observar que os alunos passam POPT gastam mais tempo para submeter à primeira versão do que os alunos não-POPT. Alunos não-POPT levaram, em média, 45,98 minutos para submeter à primeira versão, enquanto os alunos POPT levaram, em média, 100,51 minutos para submeter à primeira versão. As medianas foram 32,47 minutos e 87,05 minutos para alunos não-POPT e POPT, respectivamente. No entanto, apesar de gastar mais tempo para submeter à primeira versão, os alunos apresentaram maior qualidade nas implementações, tal como apresentado anteriormente.

Tabela 16 Tempo x testes: POPT x Não-POPT

(64)

62

5.4 Discussões e Lições Aprendidas

Apesar de, no final do estudo, os valores finais de qualidade para os dois grupos terem sido equivalentes, além de implementar o programa, cada aluno POPT implementou em média cerca de 16 casos de testes. Além disto, os alunos POPT (i) apresentaram menos versões que alunos não-POPT, e (ii) passaram mais tempo para apresentar a primeira versão, alcançando nesta primeira versão uma maior qualidade quando comparados aos não-POPT. Esta observação leva-nos a crer que POPT estimula os alunos a pensar melhor sobre o problema proposto e sobre a solução. Uma vez que o grupo de controle não pôde desenvolver seus próprios casos de teste, quando o sistema de submissão alertava que o programa submetido continha falhas (ou seja, quando no momento da submissão da versão dos testes do professor eram executados na versão submetida), eles tinham pouca informação sobre a(s) causa(s) da falha. Como conseqüência, como eles não sabiam como os testes foram criados não entendiam por que seus programas não passaram nos testes, portanto, não entendendo como poderiam melhorar a versão submetida. Como resultado, pudemos observar alguns dos alunos não-POPT fazerem alterações sem qualquer raciocínio por trás deles, diminuindo drasticamente o percentual de testes bem sucedidos entre uma versão e outra.

Por outro lado, o grupo POPT pode desenvolver as habilidades de testador dos alunos, estimulando-os a desenvolver entradas e saídas nos casos de teste, o que, conseqüentemente, ajudou-os a desenvolver software de melhor qualidade, já na primeira versão submetida. As habilidades de teste são estimuladas por POPT são ainda mais valiosas quando o aluno enfrenta um verdadeiro cenário de desenvolvimento, em que não há nenhuma ferramenta de teste para confiar.

Apresentamos questões e lições aprendidas durante a realização deste estudo.

(65)

63

estudo de caso, dois alunos foram convidados a implementar um programa para resolvê-lo, e ambos os alunos puderam definir uma primeira versão em menos de 1 hora. Acreditamos que problemas de maior complexidade podem ter maior benefícios no uso de POPT. Um futuro interessante deve ser o de replicar este estudo usando problemas de complexidades diferentes e avaliar o seu efeito sobre as métricas recolhidas.

 A Influência Ferramenta de teste cego:Optamos por utilizar uma ferramenta de teste cego, pois é um método comumente usado para avaliar a qualidade dos programas dos alunos em Cursos de Programação. No entanto, foi possível observar que o uso da ferramenta de teste cego influenciou o número de versões submetidas de ambos os grupos, pois não havia restrição de submissões. Para filtrar o efeito da ferramenta de teste cego nós também analisamos a primeira versão em isolado. Considerando apenas a primeira versão, podemos observar que POPT supera não-POPT, o número de Testes que passaram são significativamente mais elevados para o grupo de POPT.

 O uso de Tabelas FIT para os casos de teste: Este trabalho apresenta um novo uso do tabelas FIT. Estudos têm demonstrado que Tabelas FIT podem ser usados como uma ferramenta para elucidar os requisitos dos usuários (Read,Melnik e Maurer, 2005; Janzen e Saiedian, 2008b). No entanto, nenhum desses estudos investigou o uso pedagógico das Tabelas FIT para apoiar a introdução de conceitos de testes nos cursos de programação introdutórios.

(66)

64

Tabela 17 Ameaças a Validade do Estudo

Imagem

Figura 4 Classes de Equivalência
Figura 5 Modelo V: Atividades de desenvolvimento x Níveis de teste  Uma descrição básica dos níveis de testes é a seguinte:
Figura 6 Arquitetura do JUnit
Figura 7 Código para teste FitNesse
+7

Referências

Documentos relacionados

está construída e ratificada pelo Conselho da Europa, consagrando à Pessoa s/Surda a pertença a uma minoria linguística, ainda que Portugal não a tenha ratificado.

Em medicina humana, o diagnóstico de alergia a veneno de himenópteros é apenas usado em pacientes com história de reações sistémicas à picada, tendo como principais objetivos ver o

A Câmara deliberou aprovar a minuta do Contrato de Delegação de Competências a celebrar entre o Município da Covilhã e a Freguesia de Cantar Galo e Vila do Carvalho,

Outro exemplo poderia ser o caso de dados que estão codificados em um ambiente (por exemplo, o código do fornecedor embute região) e que deverão ser decodificados a

8 the President was visiting the poor communities in the northeast, “to take a good look at poverty” (Em... 2003); and another one about the Consumer Price Index (CPI) of 2002, in

Since this previous case of testing is a very simple procedure, the correspondent Test Table, Test Case 3, includes this and the following procedure which represents the

Design/Methodology/Approach – This paper uses data from the Family Spending Survey to disaggregate the Household column of the Portuguese Input-Output Table in

RESUMO Este trabalho é resultado de uma pesquisa realizada no Instituto de Reabilitação e Prevenção em Saúde Indaiá, teve como objetivos identificar a prevalência de doentes