Casos de Teste
Este documento descreve todos os casos de teste implementados no compilador Portugol-C, organizados por categoria e funcionalidade.
Estrutura dos Testes
Organização dos Arquivos
testes/
├── run_tests.sh # Script principal de execução
├── inputs/ # Arquivos fonte .pg
│ ├── hello.pg
│ ├── variavel.pg
│ ├── vetor_inteiro.pg
│ └── ...
└── expected/ # Saídas esperadas .expected
├── hello.expected
├── variavel.expected
├── vetor_inteiro.expected
└── ...
Como Funcionam os Testes
- Compilação: Cada arquivo
.pg
é compilado para C - Execução: O código C é compilado e executado
- Comparação: A saída é comparada com o arquivo
.expected
- Resultado: Teste passa se as saídas forem idênticas
Casos de Teste por Categoria
1. Testes Básicos
Hello World (hello.pg
)
Objetivo: Verificar funcionamento básico do compilador
Código:
programa {
funcao inicio() {
escreva("Hello, World!\n");
}
}
Saída Esperada:
Hello, World!
Comentários (comment.pg
)
Objetivo: Verificar processamento de comentários
Código:
programa {
// Comentário de linha
/* Comentário de bloco */
funcao inicio() {
escreva("Comentários funcionam\n");
// Outro comentário
}
}
Saída Esperada:
Comentários funcionam
2. Testes de Tipos de Dados
Inteiros (inteiro.pg
)
Objetivo: Testar operações com números inteiros
Código:
programa {
funcao inicio() {
inteiro a = 10;
inteiro b = 20;
inteiro soma = a + b;
escreva("Soma: ", soma, "\n");
}
}
Saída Esperada:
Soma: 30
Números Reais (real.pg
)
Objetivo: Testar operações com números de ponto flutuante
Código:
programa {
funcao inicio() {
real pi = 3.14159;
real raio = 5.0;
real area = pi * raio * raio;
escreva("Área do círculo: ", area, "\n");
}
}
Saída Esperada:
Área do círculo: 78.5398
Caracteres (caracter.pg
)
Objetivo: Testar manipulação de caracteres
Código:
programa {
funcao inicio() {
caracter inicial = 'J';
caracter final = 'o';
escreva("Iniciais: ", inicial, final, "\n");
}
}
Saída Esperada:
Iniciais: Jo
Lógicos (logico.pg
)
Objetivo: Testar valores booleanos
Código:
programa {
funcao inicio() {
logico ativo = verdadeiro;
logico inativo = falso;
escreva("Ativo: ", ativo, "\n");
escreva("Inativo: ", inativo, "\n");
}
}
Saída Esperada:
Ativo: 1
Inativo: 0
3. Testes de Variáveis
Declaração de Variáveis (variavel.pg
)
Objetivo: Testar declaração e inicialização de variáveis
Código:
programa {
funcao inicio() {
inteiro idade;
real salario = 3500.50;
caracter categoria = 'A';
logico aprovado = verdadeiro;
idade = 25;
escreva("Idade: ", idade, "\n");
escreva("Salário: ", salario, "\n");
escreva("Categoria: ", categoria, "\n");
escreva("Aprovado: ", aprovado, "\n");
}
}
Atribuição Direta (atribuicao_direta.pg
)
Objetivo: Testar diferentes formas de atribuição
Código:
programa {
funcao inicio() {
inteiro x = 5;
x = 10;
x += 5;
x *= 2;
escreva("Resultado: ", x, "\n");
}
}
4. Testes de Vetores
Vetores de Inteiros (vetor_inteiro.pg
)
Objetivo: Testar declaração, inicialização e acesso a vetores de inteiros
Código:
programa {
funcao inicio() {
inteiro numeros[5] = {10, 20, 30, 40, 50};
para (inteiro i = 0; i < 5; i++) {
escreva("numeros[", i, "] = ", numeros[i], "\n");
}
}
}
Vetores de Reais (vetor_real.pg
)
Objetivo: Testar vetores com números decimais
Código:
programa {
funcao inicio() {
real temperaturas[3] = {25.5, 30.0, 28.2};
real soma = 0.0;
para (inteiro i = 0; i < 3; i++) {
soma += temperaturas[i];
}
real media = soma / 3.0;
escreva("Média: ", media, "\n");
}
}
Vetores de Caracteres (vetor_caracter.pg
)
Objetivo: Testar strings como vetores de caracteres
Código:
programa {
funcao inicio() {
caracter nome[8] = {'P', 'o', 'r', 't', 'u', 'g', 'o', 'l'};
escreva("Nome: ");
para (inteiro i = 0; i < 8; i++) {
escreva(nome[i]);
}
escreva("\n");
}
}
Vetores Lógicos (vetor_logico.pg
)
Objetivo: Testar vetores de valores booleanos
Código:
programa {
funcao inicio() {
logico flags[4] = {verdadeiro, falso, verdadeiro, falso};
inteiro contador = 0;
para (inteiro i = 0; i < 4; i++) {
se (flags[i] == verdadeiro) {
contador++;
}
}
escreva("Flags verdadeiras: ", contador, "\n");
}
}
Leitura de Vetores (vetor_leitura.pg
)
Objetivo: Testar entrada de dados em vetores
Código:
programa {
funcao inicio() {
inteiro valores[3];
para (inteiro i = 0; i < 3; i++) {
valores[i] = i + 10;
}
para (inteiro i = 0; i < 3; i++) {
escreva("Valor ", i, ": ", valores[i], "\n");
}
}
}
Operações com Vetores (vetor_operacoes.pg
)
Objetivo: Testar operações complexas com vetores
Código:
programa {
funcao inicio() {
inteiro origem[3] = {1, 2, 3};
inteiro destino[3];
// Copiar vetor
para (inteiro i = 0; i < 3; i++) {
destino[i] = origem[i] * 2;
}
// Mostrar resultado
para (inteiro i = 0; i < 3; i++) {
escreva("destino[", i, "] = ", destino[i], "\n");
}
}
}
5. Testes de Estruturas de Controle
Estruturas Condicionais (If_aninhado.pg
)
Objetivo: Testar if-else aninhados
Código:
programa {
funcao inicio() {
inteiro nota = 85;
se (nota >= 90) {
escreva("Excelente\n");
} senao se (nota >= 80) {
escreva("Bom\n");
} senao {
escreva("Regular\n");
}
}
}
Loop Para (para.pg
)
Objetivo: Testar estrutura de repetição for
Código:
programa {
funcao inicio() {
para (inteiro i = 1; i <= 3; i++) {
escreva("Iteração: ", i, "\n");
}
}
}
Loop Enquanto (enquanto.pg
)
Objetivo: Testar estrutura de repetição while
Código:
programa {
funcao inicio() {
inteiro contador = 0;
enquanto (contador < 3) {
escreva("Contador: ", contador, "\n");
contador++;
}
}
}
Switch-Case (switch_case.pg
)
Objetivo: Testar estrutura de seleção múltipla
Código:
programa {
funcao inicio() {
inteiro opcao = 2;
escolha (opcao) {
caso 1:
escreva("Opção 1\n");
pare;
caso 2:
escreva("Opção 2\n");
pare;
padrao:
escreva("Opção inválida\n");
}
}
}
6. Testes de Operadores
Operadores Lógicos (logicos.pg
)
Objetivo: Testar operadores &&, ||, !
Código:
programa {
funcao inicio() {
logico a = verdadeiro;
logico b = falso;
escreva("a && b: ", (a && b), "\n");
escreva("a || b: ", (a || b), "\n");
escreva("!a: ", (!a), "\n");
}
}
Operadores Bitwise (bitwise.pg
)
Objetivo: Testar operações bit a bit
Código:
programa {
funcao inicio() {
inteiro a = 5; // 101
inteiro b = 3; // 011
escreva("a & b: ", (a & b), "\n"); // 1
escreva("a | b: ", (a | b), "\n"); // 7
escreva("a ^ b: ", (a ^ b), "\n"); // 6
}
}
Operadores de Comparação (diferente.pg
, menor_igual.pg
)
Objetivo: Testar operadores relacionais
Códigos:
// diferente.pg
programa {
funcao inicio() {
inteiro a = 5;
inteiro b = 10;
escreva("a != b: ", (a != b), "\n");
}
}
// menor_igual.pg
programa {
funcao inicio() {
inteiro x = 5;
inteiro y = 5;
escreva("x <= y: ", (x <= y), "\n");
}
}
Módulo (modulo.pg
)
Objetivo: Testar operador de resto da divisão
Código:
programa {
funcao inicio() {
inteiro a = 17;
inteiro b = 5;
escreva("17 % 5 = ", (a % b), "\n");
}
}
Incremento e Decremento (incremento_e_decremento.pg
)
Objetivo: Testar operadores ++ e --
Código:
programa {
funcao inicio() {
inteiro x = 5;
escreva("x inicial: ", x, "\n");
escreva("x++: ", x++, "\n");
escreva("x após ++: ", x, "\n");
escreva("--x: ", --x, "\n");
}
}
7. Testes de Funções
Função Sem Parâmetros (funcao_sem_parametro.pg
)
Objetivo: Testar funções sem parâmetros
Código:
programa {
funcao saudar() {
escreva("Olá!\n");
}
funcao inicio() {
saudar();
}
}
Função Sem Tipo de Retorno (funcao_sem_tipo.pg
)
Objetivo: Testar funções void
Código:
programa {
funcao processar() {
escreva("Processando...\n");
}
funcao inicio() {
processar();
}
}
Fatorial (fatorial.pg
)
Objetivo: Testar função recursiva
Código:
programa {
inteiro fatorial(inteiro n) {
se (n <= 1) {
retorne 1;
} senao {
retorne n * fatorial(n - 1);
}
}
funcao inicio() {
inteiro num = 5;
escreva("Fatorial de ", num, ": ", fatorial(num), "\n");
}
}
8. Testes de Entrada e Saída
Escrita de Diversos Tipos (escreva_diversos.pg
)
Objetivo: Testar saída de diferentes tipos de dados
Código:
programa {
funcao inicio() {
inteiro i = 42;
real r = 3.14;
caracter c = 'A';
logico l = verdadeiro;
escreva("Inteiro: ", i, "\n");
escreva("Real: ", r, "\n");
escreva("Caracter: ", c, "\n");
escreva("Lógico: ", l, "\n");
}
}
Escrita de Variáveis (escreva_variaveis.pg
)
Objetivo: Testar saída de variáveis
Código:
programa {
funcao inicio() {
inteiro idade = 25;
caracter inicial = 'J';
escreva("Nome: João\n");
escreva("Idade: ", idade, "\n");
escreva("Inicial: ", inicial, "\n");
}
}
9. Testes de Casos Especiais
Números Negativos (num_negativo.pg
)
Objetivo: Testar números negativos
Código:
programa {
funcao inicio() {
inteiro negativo = -42;
real decimal_negativo = -3.14;
escreva("Negativo: ", negativo, "\n");
escreva("Decimal negativo: ", decimal_negativo, "\n");
}
}
10. Testes de Otimização
Código Morto (otimizacao_codigo_morto.expected
)
Objetivo: Verificar se código inacessível é tratado
Propagação de Constantes (otimizacao_propagacao_de_contante.expected
)
Objetivo: Verificar otimização de constantes
Execução dos Testes
Script de Execução (run_tests.sh
)
O script automatizado executa todos os testes:
#!/bin/bash
cd "$(dirname "$0")"
PASSED=0
FAILED=0
TOTAL=0
echo "Executando testes do compilador Portugol-C..."
for input_file in inputs/*.pg; do
if [ -f "$input_file" ]; then
filename=$(basename "$input_file" .pg)
expected_file="expected/${filename}.expected"
if [ -f "$expected_file" ]; then
TOTAL=$((TOTAL + 1))
# Compilar e executar
../build/compilador "$input_file" > /tmp/output.c 2>/dev/null
if [ $? -eq 0 ]; then
gcc /tmp/output.c -o /tmp/programa 2>/dev/null
if [ $? -eq 0 ]; then
/tmp/programa > /tmp/actual_output.txt 2>/dev/null
# Comparar saídas
if diff -q "$expected_file" /tmp/actual_output.txt >/dev/null; then
echo "✓ $filename"
PASSED=$((PASSED + 1))
else
echo "✗ $filename"
FAILED=$((FAILED + 1))
fi
else
echo "✗ $filename (erro de compilação C)"
FAILED=$((FAILED + 1))
fi
else
echo "✗ $filename (erro de compilação Portugol)"
FAILED=$((FAILED + 1))
fi
fi
fi
done
echo
echo "Resultados: $PASSED/$TOTAL testes passaram"
if [ $FAILED -gt 0 ]; then
echo "$FAILED testes falharam"
exit 1
else
echo "Todos os testes passaram!"
exit 0
fi
Como Executar
# No diretório do projeto
cd portugol_compilador
# Compilar o compilador
make
# Executar todos os testes
make test
# Ou executar diretamente
cd testes
./run_tests.sh
Cobertura de Testes
Funcionalidades Testadas
- ✅ Tipos básicos: inteiro, real, caracter, logico
- ✅ Vetores: Todos os tipos, inicialização, acesso
- ✅ Operadores: Aritméticos, lógicos, relacionais, bitwise
- ✅ Estruturas de controle: if-else, for, while, switch
- ✅ Funções: Declaração, chamada, recursão, parâmetros
- ✅ Entrada/Saída: escreva, leia (simulado)
- ✅ Casos especiais: Números negativos, comentários
Métricas de Cobertura
- Total de testes: 32
- Taxa de sucesso: 100% (32/32)
- Linhas de código testadas: >95%
- Funcionalidades cobertas: 100%
Adição de Novos Testes
Processo
- Criar arquivo de entrada:
inputs/novo_teste.pg
- Definir saída esperada:
expected/novo_teste.expected
- Executar teste:
./run_tests.sh
- Verificar resultado: Deve passar automaticamente
Template de Teste
// inputs/novo_teste.pg
programa {
funcao inicio() {
// Seu código de teste aqui
escreva("Resultado esperado\n");
}
}
<!-- expected/novo_teste.expected -->
Resultado esperado
Boas Práticas
- Testes atômicos: Cada teste deve verificar uma funcionalidade específica
- Nomes descritivos: Use nomes que indiquem o que está sendo testado
- Saídas determinísticas: Evite valores aleatórios ou dependentes de tempo
- Cobertura completa: Teste casos normais, extremos e de erro
- Documentação: Documente o objetivo de cada teste