Introdução ao CppUTest

Pássaro

14 de mai. de 2017

Email

1 min read

Introdução ao CppUTest

Principais Conclusões

    • CppUTest é um framework de teste leve e ativamente mantido, no estilo xUnit, para C/C++, com uma camada de integração em C que funciona perfeitamente mesmo em bases de código pesadas em C.

    • Você pode instalá-lo através de gerenciadores de pacotes (distribuições Linux, Homebrew) ou clonar o repositório do GitHub.

    • Uma configuração mínima consiste em:

      • um diretório de src/ de produção,

      • um diretório de teste t/,

      • um executor de testes (CommandLineTestRunner), e

      • módulos de teste usando os blocos TEST_GROUP e TEST().

    • CppUTest fornece um MakefileWorker.mk auxiliar que simplifica a construção de testes, a vinculação de bibliotecas e o tratamento de flags.

    • A detecção de vazamentos de memória é ativada por padrão através de sobreposições de malloc/free, capturando vazamentos dentro do código-fonte testado.

    • A cobertura de código via gcov integra-se facilmente habilitando CPPUTEST_USE_GCOV=Y, produzindo relatórios de cobertura completa e resumos em HTML.

    • O framework inclui recursos avançados: simulações, plugins, scripts auxiliares e interoperabilidade direta em C — útil para bases de código empresarial complexas.

Destaques de Perguntas e Respostas

  • O que é CppUTest e por que usá-lo?

    É um framework de testes robusto, estilo xUnit, para C/C++ com uma API limpa, macros de assertiva embutidas, detecção de vazamentos e desenvolvimento ativo — ideal para sistemas legados ou modernos.

  • Como você estrutura um projeto básico usando CppUTest?

    src/
      code/
        code.cpp
        code.h
      main.cpp
    t/
      main.cpp (test runner)
      test.cpp (test suite)
  • Como você executa todos os testes?

    O executor de testes usa:

    return CommandLineTestRunner::RunAllTests(ac, av);
  • Como você cria testes sem configurar manualmente as opções do compilador?

    Use MakefileWorker.mk do CppUTest, que lida automaticamente com bandeiras, vinculação e execução de testes.

  • O CppUTest pode detectar vazamentos de memória automaticamente?

    Sim. Ele substitui malloc/free durante as compilações de teste, relatando:

    • qual teste vazou,

    • onde ocorreu,

    • tamanho do vazamento e conteúdos da memória.

    Exemplo de saída de falha:

    Memory leak(s) found.
    Allocated at: code.c line 6
    Leak size: 1
  • Como eu gero cobertura de código?

    1. Habilitar: CPPUTEST_USE_GCOV=Y

    2. Assegure-se de que filterGcov.sh esteja disponível em $(CPPUTEST_HOME)/scripts/.

    3. Execute: make gcov

      Isso produz .gcov, texto resumo e relatórios de cobertura em HTML.

  • O que mais o CppUTest pode fazer além dos testes básicos?

    • framework de simulação

    • sistema de plugins

    • scripts de automação auxiliares

    • integração nativa com C

    • macros de asserção extensivas

  • Para quem o CppUTest é mais adequado?

    Equipes trabalhando com sistemas embarcados, plataformas C, serviços C++ ou qualquer ambiente onde a confiabilidade e a segurança da memória devem ser continuamente validadas.

No SparkPost, dedicamos muito tempo e esforço para testar nosso código. Nossa plataforma é escrita em C, e recentemente pesquisei a integração com um framework de teste de unidade chamado "CppUTest", que fornece testes no estilo xUnit para C/C++. Este framework é robusto, rico em recursos e está em desenvolvimento ativo, o que o torna uma ótima escolha. Ele também fornece uma camada de integração em C, o que facilitou o uso com nosso código C da plataforma, embora a maior parte do framework seja em C++. Este tutorial aborda como começar a usar o CppUTest em seus próprios projetos.

No SparkPost, dedicamos muito tempo e esforço para testar nosso código. Nossa plataforma é escrita em C, e recentemente pesquisei a integração com um framework de teste de unidade chamado "CppUTest", que fornece testes no estilo xUnit para C/C++. Este framework é robusto, rico em recursos e está em desenvolvimento ativo, o que o torna uma ótima escolha. Ele também fornece uma camada de integração em C, o que facilitou o uso com nosso código C da plataforma, embora a maior parte do framework seja em C++. Este tutorial aborda como começar a usar o CppUTest em seus próprios projetos.

No SparkPost, dedicamos muito tempo e esforço para testar nosso código. Nossa plataforma é escrita em C, e recentemente pesquisei a integração com um framework de teste de unidade chamado "CppUTest", que fornece testes no estilo xUnit para C/C++. Este framework é robusto, rico em recursos e está em desenvolvimento ativo, o que o torna uma ótima escolha. Ele também fornece uma camada de integração em C, o que facilitou o uso com nosso código C da plataforma, embora a maior parte do framework seja em C++. Este tutorial aborda como começar a usar o CppUTest em seus próprios projetos.

Interessado em saber mais?

Este é apenas a ponta do iceberg quando se trata de todos os recursos contidos nesta ferramenta. Além dos conceitos básicos discutidos aqui, ela também possui uma estrutura de simulação, uma camada de integração direta com C e uma estrutura de plugin, para citar alguns dos mais significativos. O repositório também contém um diretório inteiro de scripts auxiliares que podem ajudar a automatizar algumas das partes rotineiras de trabalho com a estrutura.

Espero que as informações aqui ajudem você a melhorar a qualidade do seu código C/C++ com esta ótima ferramenta!

Este é apenas a ponta do iceberg quando se trata de todos os recursos contidos nesta ferramenta. Além dos conceitos básicos discutidos aqui, ela também possui uma estrutura de simulação, uma camada de integração direta com C e uma estrutura de plugin, para citar alguns dos mais significativos. O repositório também contém um diretório inteiro de scripts auxiliares que podem ajudar a automatizar algumas das partes rotineiras de trabalho com a estrutura.

Espero que as informações aqui ajudem você a melhorar a qualidade do seu código C/C++ com esta ótima ferramenta!

Este é apenas a ponta do iceberg quando se trata de todos os recursos contidos nesta ferramenta. Além dos conceitos básicos discutidos aqui, ela também possui uma estrutura de simulação, uma camada de integração direta com C e uma estrutura de plugin, para citar alguns dos mais significativos. O repositório também contém um diretório inteiro de scripts auxiliares que podem ajudar a automatizar algumas das partes rotineiras de trabalho com a estrutura.

Espero que as informações aqui ajudem você a melhorar a qualidade do seu código C/C++ com esta ótima ferramenta!

Baixando CppUTest

A página do projeto CppUTest está disponível no site oficial, e o repositório está no github. Também está incluído nos repositórios de gerenciamento de pacotes de muitas distribuições Linux, além de homebrew no Mac OS. Os exemplos a seguir foram executados no Mac OS X, mas são derivados de código escrito para Red Hat, o sistema operacional em que nossa plataforma funciona.

Os conceitos básicos estão bem documentados na página inicial do CppUTest. Vamos passar rapidamente por isso e chegar a alguns dos recursos mais interessantes.

A página do projeto CppUTest está disponível no site oficial, e o repositório está no github. Também está incluído nos repositórios de gerenciamento de pacotes de muitas distribuições Linux, além de homebrew no Mac OS. Os exemplos a seguir foram executados no Mac OS X, mas são derivados de código escrito para Red Hat, o sistema operacional em que nossa plataforma funciona.

Os conceitos básicos estão bem documentados na página inicial do CppUTest. Vamos passar rapidamente por isso e chegar a alguns dos recursos mais interessantes.

A página do projeto CppUTest está disponível no site oficial, e o repositório está no github. Também está incluído nos repositórios de gerenciamento de pacotes de muitas distribuições Linux, além de homebrew no Mac OS. Os exemplos a seguir foram executados no Mac OS X, mas são derivados de código escrito para Red Hat, o sistema operacional em que nossa plataforma funciona.

Os conceitos básicos estão bem documentados na página inicial do CppUTest. Vamos passar rapidamente por isso e chegar a alguns dos recursos mais interessantes.

Colocando a Base

Primeiro as coisas, vamos escrever algum código!

Nosso projeto de teste terá um arquivo ‘main’ e incluirá uma biblioteca utilitária chamada ‘code’. A biblioteca fornecerá uma função simples que retornará 1 (por enquanto). Os arquivos serão organizados assim:

├── src
├── code
├── code.cpp
└── code.h
└── main.cpp
└── t
    ├── main.cpp
    └── test.cpp

Vamos começar escrevendo os arquivos src/

// src/main.cpp
#include <stdlib.h>
#include <stdio.h>
#include "code.h"
int main(void) {
    test_func();
    printf("hello world!\n");
    exit(0);
}


// src/code/code.cpp
#include <stdlib.h>
#include "code.h"
int test_func() {
    return 1;
}


// src/code/code.h
#ifndef __code_h__
#define __code_h__
int test_func();
#endif

Agora, vamos fazer os testes, que estarão no diretório t/.  A primeira coisa a fazer é configurar um runner de testes que executará nossos arquivos de teste. Esta também é a função ‘main’  que será executada uma vez que tudo esteja compilado:

// t/main.cpp
#include "CppUTest/CommandLineTestRunner.h"
int main(int ac, char** av) {
return CommandLineTestRunner::RunAllTests(ac, av);
}

Agora podemos escrever nosso primeiro módulo de teste:

// t/test.cpp
#include "CppUTest/TestHarness.h"
#include "code.h"
TEST_GROUP(AwesomeExamples)
{
};
TEST(AwesomeExamples, FirstExample)
{
    int x = test_func();
    CHECK_EQUAL(1, x);
}

Em seguida, precisamos escrever makefiles.  Precisaremos de dois: um para os arquivos do projeto sob src/, e um para os testes.

Primeiro as coisas, vamos escrever algum código!

Nosso projeto de teste terá um arquivo ‘main’ e incluirá uma biblioteca utilitária chamada ‘code’. A biblioteca fornecerá uma função simples que retornará 1 (por enquanto). Os arquivos serão organizados assim:

├── src
├── code
├── code.cpp
└── code.h
└── main.cpp
└── t
    ├── main.cpp
    └── test.cpp

Vamos começar escrevendo os arquivos src/

// src/main.cpp
#include <stdlib.h>
#include <stdio.h>
#include "code.h"
int main(void) {
    test_func();
    printf("hello world!\n");
    exit(0);
}


// src/code/code.cpp
#include <stdlib.h>
#include "code.h"
int test_func() {
    return 1;
}


// src/code/code.h
#ifndef __code_h__
#define __code_h__
int test_func();
#endif

Agora, vamos fazer os testes, que estarão no diretório t/.  A primeira coisa a fazer é configurar um runner de testes que executará nossos arquivos de teste. Esta também é a função ‘main’  que será executada uma vez que tudo esteja compilado:

// t/main.cpp
#include "CppUTest/CommandLineTestRunner.h"
int main(int ac, char** av) {
return CommandLineTestRunner::RunAllTests(ac, av);
}

Agora podemos escrever nosso primeiro módulo de teste:

// t/test.cpp
#include "CppUTest/TestHarness.h"
#include "code.h"
TEST_GROUP(AwesomeExamples)
{
};
TEST(AwesomeExamples, FirstExample)
{
    int x = test_func();
    CHECK_EQUAL(1, x);
}

Em seguida, precisamos escrever makefiles.  Precisaremos de dois: um para os arquivos do projeto sob src/, e um para os testes.

Primeiro as coisas, vamos escrever algum código!

Nosso projeto de teste terá um arquivo ‘main’ e incluirá uma biblioteca utilitária chamada ‘code’. A biblioteca fornecerá uma função simples que retornará 1 (por enquanto). Os arquivos serão organizados assim:

├── src
├── code
├── code.cpp
└── code.h
└── main.cpp
└── t
    ├── main.cpp
    └── test.cpp

Vamos começar escrevendo os arquivos src/

// src/main.cpp
#include <stdlib.h>
#include <stdio.h>
#include "code.h"
int main(void) {
    test_func();
    printf("hello world!\n");
    exit(0);
}


// src/code/code.cpp
#include <stdlib.h>
#include "code.h"
int test_func() {
    return 1;
}


// src/code/code.h
#ifndef __code_h__
#define __code_h__
int test_func();
#endif

Agora, vamos fazer os testes, que estarão no diretório t/.  A primeira coisa a fazer é configurar um runner de testes que executará nossos arquivos de teste. Esta também é a função ‘main’  que será executada uma vez que tudo esteja compilado:

// t/main.cpp
#include "CppUTest/CommandLineTestRunner.h"
int main(int ac, char** av) {
return CommandLineTestRunner::RunAllTests(ac, av);
}

Agora podemos escrever nosso primeiro módulo de teste:

// t/test.cpp
#include "CppUTest/TestHarness.h"
#include "code.h"
TEST_GROUP(AwesomeExamples)
{
};
TEST(AwesomeExamples, FirstExample)
{
    int x = test_func();
    CHECK_EQUAL(1, x);
}

Em seguida, precisamos escrever makefiles.  Precisaremos de dois: um para os arquivos do projeto sob src/, e um para os testes.

Makefile do Projeto

O makefile do projeto estará no mesmo nível que os diretórios ‘src’ e ‘t’ na raiz do projeto. Deve parecer assim:

# Makefile

SRC_DIR = ./src
CODE_DIR = $(SRC_DIR)/code
OUT = example
TEST_DIR = t

test:
make -C $(TEST_DIR)

test_clean:
make -C $(TEST_DIR) clean

code.o:
gcc -c -I$(CODE_DIR) $(CODE_DIR)/code.cpp -o $(CODE_DIR)/code.o

main: code.o
gcc -I$(CODE_DIR) $(CODE_DIR)/code.o $(SRC_DIR)/main.cpp -o $(OUT)

all: test main

clean: test_clean
rm $(SRC_DIR)/*.o $(CODE_DIR)/*.o $(OUT)

Note que isso usa ‘make -C’  para os alvos de teste – o que significa que chamará ‘make’  novamente usando o makefile no diretório de teste.

Neste ponto, podemos compilar o código ‘src’ com o makefile e ver que funciona:

[]$ make main
gcc -c -I./src/code ./src/code/code.cpp -o ./src/code/code.o
gcc -I./src/code ./src/code/code.o ./src/main.cpp -o example
[]$ ./example
hello world

O makefile do projeto estará no mesmo nível que os diretórios ‘src’ e ‘t’ na raiz do projeto. Deve parecer assim:

# Makefile

SRC_DIR = ./src
CODE_DIR = $(SRC_DIR)/code
OUT = example
TEST_DIR = t

test:
make -C $(TEST_DIR)

test_clean:
make -C $(TEST_DIR) clean

code.o:
gcc -c -I$(CODE_DIR) $(CODE_DIR)/code.cpp -o $(CODE_DIR)/code.o

main: code.o
gcc -I$(CODE_DIR) $(CODE_DIR)/code.o $(SRC_DIR)/main.cpp -o $(OUT)

all: test main

clean: test_clean
rm $(SRC_DIR)/*.o $(CODE_DIR)/*.o $(OUT)

Note que isso usa ‘make -C’  para os alvos de teste – o que significa que chamará ‘make’  novamente usando o makefile no diretório de teste.

Neste ponto, podemos compilar o código ‘src’ com o makefile e ver que funciona:

[]$ make main
gcc -c -I./src/code ./src/code/code.cpp -o ./src/code/code.o
gcc -I./src/code ./src/code/code.o ./src/main.cpp -o example
[]$ ./example
hello world

O makefile do projeto estará no mesmo nível que os diretórios ‘src’ e ‘t’ na raiz do projeto. Deve parecer assim:

# Makefile

SRC_DIR = ./src
CODE_DIR = $(SRC_DIR)/code
OUT = example
TEST_DIR = t

test:
make -C $(TEST_DIR)

test_clean:
make -C $(TEST_DIR) clean

code.o:
gcc -c -I$(CODE_DIR) $(CODE_DIR)/code.cpp -o $(CODE_DIR)/code.o

main: code.o
gcc -I$(CODE_DIR) $(CODE_DIR)/code.o $(SRC_DIR)/main.cpp -o $(OUT)

all: test main

clean: test_clean
rm $(SRC_DIR)/*.o $(CODE_DIR)/*.o $(OUT)

Note que isso usa ‘make -C’  para os alvos de teste – o que significa que chamará ‘make’  novamente usando o makefile no diretório de teste.

Neste ponto, podemos compilar o código ‘src’ com o makefile e ver que funciona:

[]$ make main
gcc -c -I./src/code ./src/code/code.cpp -o ./src/code/code.o
gcc -I./src/code ./src/code/code.o ./src/main.cpp -o example
[]$ ./example
hello world

Testes Makefile

Para os testes, as coisas são um pouco mais envolvidas, uma vez que precisamos carregar e integrar corretamente com a biblioteca CppUTest.

O repositório CppUTest fornece um arquivo chamado “MakefileWorker.mk”. Ele oferece muita funcionalidade que torna a compilação com o CppUTest simples. O arquivo está localizado no diretório “build” no repositório git. Para este tutorial, vamos assumir que ele foi copiado para o diretório ‘t/’. Ele pode ser usado da seguinte forma:

# we don’t want to use relative paths, so we set these variables
PROJECT_DIR=/path/to/project
SRC_DIR=$(PROJECT_DIR)/src
TEST_DIR=$(PROJECT_DIR)/t

# specify where the source code and includes are located
INCLUDE_DIRS=$(SRC_DIR)/code
SRC_DIRS=$(SRC_DIR)/code

# specify where the test code is located
TEST_SRC_DIRS=$(TEST_DIR)

# what to call the test binary
TEST_TARGET=example

# where the cpputest library is located
CPPUTEST_HOME=/usr/local

# run MakefileWorker.mk with the variables defined here
include MakefileWorker.mk

Note que CPPUTEST_HOME deve ser definido para onde quer que o CppUTest tenha sido instalado. Se você instalou um pacote de distribuição, isso estará tipicamente sob /usr/local em um sistema linux/mac. Se você fez o checkout do repositório por conta própria, está onde aquele checkout está.

Essas opções estão todas documentadas em MakefileWorker.mk.

MakefileWorker.mk também adiciona alguns alvos de makefile, incluindo os seguintes:

  1. todos – compila os testes indicados pelo makefile

  2. limpar – remove todos os arquivos objeto e gcov gerados para os testes

  3. limpar tudo – remove qualquer arquivo objeto ou gcov em toda a árvore de diretórios

  4. bandeiras – lista todas as bandeiras configuradas usadas para compilar os testes

  5. depurar – lista todos os arquivos fonte, objetos, dependências e ‘coisas a limpar’


Componente

Finalidade

Arquivos Chave / Bandeiras

Notas

Makefile do Projeto

Compila o código-fonte principal

Makefile de nível raiz usando make -C

Compila src/ e delega testes a t/

Makefile de Testes

Compila e vincula testes com o CppUTest

t/Makefile referenciando MakefileWorker.mk

Gerencia compilação de teste, vinda e bandeiras de biblioteca

MakefileWorker.mk

Fornece lógica de construção reutilizável

Localizado no diretório /build do CppUTest

Adiciona alvos: todos, limpar, limpar tudo, bandeiras, depurar

Integração GCov

Habilita relatórios de cobertura de código

CPPUTEST_USE_GCOV=Y

Produz arquivos .gcov, relatórios HTML

Detecção de Vazamento de Memória

Detecta vazamentos de malloc/free

CPPUTEST_USE_MEM_LEAK_DETECTION

Ativado por padrão; pode ser desativado com =N

Executor de Testes

Executa grupos de testes

CommandLineTestRunner

Ponto de entrada principal necessário para executar testes

Para os testes, as coisas são um pouco mais envolvidas, uma vez que precisamos carregar e integrar corretamente com a biblioteca CppUTest.

O repositório CppUTest fornece um arquivo chamado “MakefileWorker.mk”. Ele oferece muita funcionalidade que torna a compilação com o CppUTest simples. O arquivo está localizado no diretório “build” no repositório git. Para este tutorial, vamos assumir que ele foi copiado para o diretório ‘t/’. Ele pode ser usado da seguinte forma:

# we don’t want to use relative paths, so we set these variables
PROJECT_DIR=/path/to/project
SRC_DIR=$(PROJECT_DIR)/src
TEST_DIR=$(PROJECT_DIR)/t

# specify where the source code and includes are located
INCLUDE_DIRS=$(SRC_DIR)/code
SRC_DIRS=$(SRC_DIR)/code

# specify where the test code is located
TEST_SRC_DIRS=$(TEST_DIR)

# what to call the test binary
TEST_TARGET=example

# where the cpputest library is located
CPPUTEST_HOME=/usr/local

# run MakefileWorker.mk with the variables defined here
include MakefileWorker.mk

Note que CPPUTEST_HOME deve ser definido para onde quer que o CppUTest tenha sido instalado. Se você instalou um pacote de distribuição, isso estará tipicamente sob /usr/local em um sistema linux/mac. Se você fez o checkout do repositório por conta própria, está onde aquele checkout está.

Essas opções estão todas documentadas em MakefileWorker.mk.

MakefileWorker.mk também adiciona alguns alvos de makefile, incluindo os seguintes:

  1. todos – compila os testes indicados pelo makefile

  2. limpar – remove todos os arquivos objeto e gcov gerados para os testes

  3. limpar tudo – remove qualquer arquivo objeto ou gcov em toda a árvore de diretórios

  4. bandeiras – lista todas as bandeiras configuradas usadas para compilar os testes

  5. depurar – lista todos os arquivos fonte, objetos, dependências e ‘coisas a limpar’


Componente

Finalidade

Arquivos Chave / Bandeiras

Notas

Makefile do Projeto

Compila o código-fonte principal

Makefile de nível raiz usando make -C

Compila src/ e delega testes a t/

Makefile de Testes

Compila e vincula testes com o CppUTest

t/Makefile referenciando MakefileWorker.mk

Gerencia compilação de teste, vinda e bandeiras de biblioteca

MakefileWorker.mk

Fornece lógica de construção reutilizável

Localizado no diretório /build do CppUTest

Adiciona alvos: todos, limpar, limpar tudo, bandeiras, depurar

Integração GCov

Habilita relatórios de cobertura de código

CPPUTEST_USE_GCOV=Y

Produz arquivos .gcov, relatórios HTML

Detecção de Vazamento de Memória

Detecta vazamentos de malloc/free

CPPUTEST_USE_MEM_LEAK_DETECTION

Ativado por padrão; pode ser desativado com =N

Executor de Testes

Executa grupos de testes

CommandLineTestRunner

Ponto de entrada principal necessário para executar testes

Para os testes, as coisas são um pouco mais envolvidas, uma vez que precisamos carregar e integrar corretamente com a biblioteca CppUTest.

O repositório CppUTest fornece um arquivo chamado “MakefileWorker.mk”. Ele oferece muita funcionalidade que torna a compilação com o CppUTest simples. O arquivo está localizado no diretório “build” no repositório git. Para este tutorial, vamos assumir que ele foi copiado para o diretório ‘t/’. Ele pode ser usado da seguinte forma:

# we don’t want to use relative paths, so we set these variables
PROJECT_DIR=/path/to/project
SRC_DIR=$(PROJECT_DIR)/src
TEST_DIR=$(PROJECT_DIR)/t

# specify where the source code and includes are located
INCLUDE_DIRS=$(SRC_DIR)/code
SRC_DIRS=$(SRC_DIR)/code

# specify where the test code is located
TEST_SRC_DIRS=$(TEST_DIR)

# what to call the test binary
TEST_TARGET=example

# where the cpputest library is located
CPPUTEST_HOME=/usr/local

# run MakefileWorker.mk with the variables defined here
include MakefileWorker.mk

Note que CPPUTEST_HOME deve ser definido para onde quer que o CppUTest tenha sido instalado. Se você instalou um pacote de distribuição, isso estará tipicamente sob /usr/local em um sistema linux/mac. Se você fez o checkout do repositório por conta própria, está onde aquele checkout está.

Essas opções estão todas documentadas em MakefileWorker.mk.

MakefileWorker.mk também adiciona alguns alvos de makefile, incluindo os seguintes:

  1. todos – compila os testes indicados pelo makefile

  2. limpar – remove todos os arquivos objeto e gcov gerados para os testes

  3. limpar tudo – remove qualquer arquivo objeto ou gcov em toda a árvore de diretórios

  4. bandeiras – lista todas as bandeiras configuradas usadas para compilar os testes

  5. depurar – lista todos os arquivos fonte, objetos, dependências e ‘coisas a limpar’


Componente

Finalidade

Arquivos Chave / Bandeiras

Notas

Makefile do Projeto

Compila o código-fonte principal

Makefile de nível raiz usando make -C

Compila src/ e delega testes a t/

Makefile de Testes

Compila e vincula testes com o CppUTest

t/Makefile referenciando MakefileWorker.mk

Gerencia compilação de teste, vinda e bandeiras de biblioteca

MakefileWorker.mk

Fornece lógica de construção reutilizável

Localizado no diretório /build do CppUTest

Adiciona alvos: todos, limpar, limpar tudo, bandeiras, depurar

Integração GCov

Habilita relatórios de cobertura de código

CPPUTEST_USE_GCOV=Y

Produz arquivos .gcov, relatórios HTML

Detecção de Vazamento de Memória

Detecta vazamentos de malloc/free

CPPUTEST_USE_MEM_LEAK_DETECTION

Ativado por padrão; pode ser desativado com =N

Executor de Testes

Executa grupos de testes

CommandLineTestRunner

Ponto de entrada principal necessário para executar testes

Cobertura de Código

Os testes de unidade não estariam completos sem um relatório de cobertura. A ferramenta ideal para isso em projetos que utilizam gcc é gcov, disponível como parte do conjunto padrão de utilitários do gcc. O Cpputest se integra facilmente ao gcov, tudo que você precisa fazer é adicionar esta linha ao arquivo Makefile:

CPPUTEST_USE_GCOV=Y

Em seguida, precisamos garantir que o script filterGcov.sh do este repositório esteja em ‘/scripts/filterGcov.sh’ em relação a onde você definiu ‘CPPUTEST_HOME’. Ele também precisa ter permissões de execução.

No exemplo de Makefile, ele seria implantado em ‘/usr/local/scripts/filterGcov.sh’. Se você estiver executando o CppUTest a partir de uma cópia do repositório, tudo deve funcionar sem modificações.

Com isso em mente, você pode simplesmente executar ‘make gcov’ e a análise será gerada para você. No nosso caso, precisaremos de ‘make -B’ para reconstruir os arquivos objeto com o gcov habilitado:

[]$ make -B gcov
< compilation output >

for d in /Users/ykuperman/code/blogpost/qa/src/code ; do \
    FILES=`ls $d/*.c $d/*.cc $d/*.cpp 2> /dev/null` ; \
    gcov --object-directory objs/$d $FILES >> gcov_output.txt 2>>gcov_error.txt ; \
done

for f in  ; do \
    gcov --object-directory objs/$f $f >> gcov_output.txt 2>>gcov_error.txt ; \
done

/usr/local/scripts/filterGcov.sh gcov_output.txt gcov_error.txt gcov_report.txt example.txt

cat gcov_report.txt
100.00% /Users/ykuperman/code/blogpost/qa/src/code/code.cpp

mkdir -p gcov
mv *.gcov gcov
mv gcov_* gcov

See gcov directory for details

Isso irá gerar vários arquivos em um novo diretório ‘gcov’. Estes são:

  1. code.cpp.gcov – o arquivo ‘gcov’ real para o código sendo testado

  2. gcov_error.txt – um relatório de erro (no nosso caso, deve estar vazio)

  3. gcov_output.txt – a saída real do comando gcov que foi executado

  4. gcov_report.txt – um resumo da cobertura para cada arquivo sob teste

  5. gcov_report.txt.html – uma versão html do gcov_report

Os testes de unidade não estariam completos sem um relatório de cobertura. A ferramenta ideal para isso em projetos que utilizam gcc é gcov, disponível como parte do conjunto padrão de utilitários do gcc. O Cpputest se integra facilmente ao gcov, tudo que você precisa fazer é adicionar esta linha ao arquivo Makefile:

CPPUTEST_USE_GCOV=Y

Em seguida, precisamos garantir que o script filterGcov.sh do este repositório esteja em ‘/scripts/filterGcov.sh’ em relação a onde você definiu ‘CPPUTEST_HOME’. Ele também precisa ter permissões de execução.

No exemplo de Makefile, ele seria implantado em ‘/usr/local/scripts/filterGcov.sh’. Se você estiver executando o CppUTest a partir de uma cópia do repositório, tudo deve funcionar sem modificações.

Com isso em mente, você pode simplesmente executar ‘make gcov’ e a análise será gerada para você. No nosso caso, precisaremos de ‘make -B’ para reconstruir os arquivos objeto com o gcov habilitado:

[]$ make -B gcov
< compilation output >

for d in /Users/ykuperman/code/blogpost/qa/src/code ; do \
    FILES=`ls $d/*.c $d/*.cc $d/*.cpp 2> /dev/null` ; \
    gcov --object-directory objs/$d $FILES >> gcov_output.txt 2>>gcov_error.txt ; \
done

for f in  ; do \
    gcov --object-directory objs/$f $f >> gcov_output.txt 2>>gcov_error.txt ; \
done

/usr/local/scripts/filterGcov.sh gcov_output.txt gcov_error.txt gcov_report.txt example.txt

cat gcov_report.txt
100.00% /Users/ykuperman/code/blogpost/qa/src/code/code.cpp

mkdir -p gcov
mv *.gcov gcov
mv gcov_* gcov

See gcov directory for details

Isso irá gerar vários arquivos em um novo diretório ‘gcov’. Estes são:

  1. code.cpp.gcov – o arquivo ‘gcov’ real para o código sendo testado

  2. gcov_error.txt – um relatório de erro (no nosso caso, deve estar vazio)

  3. gcov_output.txt – a saída real do comando gcov que foi executado

  4. gcov_report.txt – um resumo da cobertura para cada arquivo sob teste

  5. gcov_report.txt.html – uma versão html do gcov_report

Os testes de unidade não estariam completos sem um relatório de cobertura. A ferramenta ideal para isso em projetos que utilizam gcc é gcov, disponível como parte do conjunto padrão de utilitários do gcc. O Cpputest se integra facilmente ao gcov, tudo que você precisa fazer é adicionar esta linha ao arquivo Makefile:

CPPUTEST_USE_GCOV=Y

Em seguida, precisamos garantir que o script filterGcov.sh do este repositório esteja em ‘/scripts/filterGcov.sh’ em relação a onde você definiu ‘CPPUTEST_HOME’. Ele também precisa ter permissões de execução.

No exemplo de Makefile, ele seria implantado em ‘/usr/local/scripts/filterGcov.sh’. Se você estiver executando o CppUTest a partir de uma cópia do repositório, tudo deve funcionar sem modificações.

Com isso em mente, você pode simplesmente executar ‘make gcov’ e a análise será gerada para você. No nosso caso, precisaremos de ‘make -B’ para reconstruir os arquivos objeto com o gcov habilitado:

[]$ make -B gcov
< compilation output >

for d in /Users/ykuperman/code/blogpost/qa/src/code ; do \
    FILES=`ls $d/*.c $d/*.cc $d/*.cpp 2> /dev/null` ; \
    gcov --object-directory objs/$d $FILES >> gcov_output.txt 2>>gcov_error.txt ; \
done

for f in  ; do \
    gcov --object-directory objs/$f $f >> gcov_output.txt 2>>gcov_error.txt ; \
done

/usr/local/scripts/filterGcov.sh gcov_output.txt gcov_error.txt gcov_report.txt example.txt

cat gcov_report.txt
100.00% /Users/ykuperman/code/blogpost/qa/src/code/code.cpp

mkdir -p gcov
mv *.gcov gcov
mv gcov_* gcov

See gcov directory for details

Isso irá gerar vários arquivos em um novo diretório ‘gcov’. Estes são:

  1. code.cpp.gcov – o arquivo ‘gcov’ real para o código sendo testado

  2. gcov_error.txt – um relatório de erro (no nosso caso, deve estar vazio)

  3. gcov_output.txt – a saída real do comando gcov que foi executado

  4. gcov_report.txt – um resumo da cobertura para cada arquivo sob teste

  5. gcov_report.txt.html – uma versão html do gcov_report

Detecção de Vazamento de Memória do Cpputest

Cpputest permite que você detecte automaticamente a memória vazada redefinindo a família de funções padrão "malloc/free" para usar seus próprios wrappers. Isso permite que ele capture rapidamente vazamentos e os relate para cada execução de teste. Isso está habilitado por padrão em MakefileWorker.mk, então já está ativo com os passos descritos até agora.

Para ilustrar, vamos vazar um pouco de memória em test_func() !

Voltando ao código.c, adicionamos um malloc()  à função, assim:

int test_func() {
    malloc(1);
    return 1;
}

Agora, após recompilar, o seguinte erro é produzido:

test.cpp:9: error: Failure in TEST(AwesomeExamples, FirstExample)
Memory leak(s) found.
Alloc num (4)
Leak size: 1
Allocated at: ./code.c and line: 6
Type: "malloc"
Memory: <

Isso mostra qual teste causou o vazamento, onde o vazamento aconteceu no código-fonte e o que estava na memória vazada. Muito útil!

Existem algumas ressalvas com esse recurso:

  1. Cpputest está usando macros de pré-processamento para redefinir dinamicamente todas as chamadas às funções padrão de gerenciamento de memória. Isso significa que funcionará apenas para chamadas no código-fonte sob teste, já que é isso que é compilado com as sobreposições do CppUTest. Vazamentos em bibliotecas vinculadas não serão capturados.

  2. Às vezes, a memória que é alocada para toda a vida do processo não deve ser liberada. Isso pode gerar muitos erros indesejados se você estiver testando um módulo com esse comportamento. Para desativar a detecção de vazamentos, você pode fazer o seguinte:

CPPUTEST_USE_MEM_LEAK_DETECTION=N

Cpputest permite que você detecte automaticamente a memória vazada redefinindo a família de funções padrão "malloc/free" para usar seus próprios wrappers. Isso permite que ele capture rapidamente vazamentos e os relate para cada execução de teste. Isso está habilitado por padrão em MakefileWorker.mk, então já está ativo com os passos descritos até agora.

Para ilustrar, vamos vazar um pouco de memória em test_func() !

Voltando ao código.c, adicionamos um malloc()  à função, assim:

int test_func() {
    malloc(1);
    return 1;
}

Agora, após recompilar, o seguinte erro é produzido:

test.cpp:9: error: Failure in TEST(AwesomeExamples, FirstExample)
Memory leak(s) found.
Alloc num (4)
Leak size: 1
Allocated at: ./code.c and line: 6
Type: "malloc"
Memory: <

Isso mostra qual teste causou o vazamento, onde o vazamento aconteceu no código-fonte e o que estava na memória vazada. Muito útil!

Existem algumas ressalvas com esse recurso:

  1. Cpputest está usando macros de pré-processamento para redefinir dinamicamente todas as chamadas às funções padrão de gerenciamento de memória. Isso significa que funcionará apenas para chamadas no código-fonte sob teste, já que é isso que é compilado com as sobreposições do CppUTest. Vazamentos em bibliotecas vinculadas não serão capturados.

  2. Às vezes, a memória que é alocada para toda a vida do processo não deve ser liberada. Isso pode gerar muitos erros indesejados se você estiver testando um módulo com esse comportamento. Para desativar a detecção de vazamentos, você pode fazer o seguinte:

CPPUTEST_USE_MEM_LEAK_DETECTION=N

Cpputest permite que você detecte automaticamente a memória vazada redefinindo a família de funções padrão "malloc/free" para usar seus próprios wrappers. Isso permite que ele capture rapidamente vazamentos e os relate para cada execução de teste. Isso está habilitado por padrão em MakefileWorker.mk, então já está ativo com os passos descritos até agora.

Para ilustrar, vamos vazar um pouco de memória em test_func() !

Voltando ao código.c, adicionamos um malloc()  à função, assim:

int test_func() {
    malloc(1);
    return 1;
}

Agora, após recompilar, o seguinte erro é produzido:

test.cpp:9: error: Failure in TEST(AwesomeExamples, FirstExample)
Memory leak(s) found.
Alloc num (4)
Leak size: 1
Allocated at: ./code.c and line: 6
Type: "malloc"
Memory: <

Isso mostra qual teste causou o vazamento, onde o vazamento aconteceu no código-fonte e o que estava na memória vazada. Muito útil!

Existem algumas ressalvas com esse recurso:

  1. Cpputest está usando macros de pré-processamento para redefinir dinamicamente todas as chamadas às funções padrão de gerenciamento de memória. Isso significa que funcionará apenas para chamadas no código-fonte sob teste, já que é isso que é compilado com as sobreposições do CppUTest. Vazamentos em bibliotecas vinculadas não serão capturados.

  2. Às vezes, a memória que é alocada para toda a vida do processo não deve ser liberada. Isso pode gerar muitos erros indesejados se você estiver testando um módulo com esse comportamento. Para desativar a detecção de vazamentos, você pode fazer o seguinte:

CPPUTEST_USE_MEM_LEAK_DETECTION=N

Outras notícias

Leia mais desta categoria

A person is standing at a desk while typing on a laptop.

A plataforma completa nativa de IA que escalará com o seu negócio.

© 2025 Pássaro

A person is standing at a desk while typing on a laptop.

A plataforma completa nativa de IA que escalará com o seu negócio.

© 2025 Pássaro