Google Test
GoogleTest é um framework open-source baseado em xUnit para escrever testes em C++. GoogleTest busca atender às condições necessárias para testagem efetiva, tais como:
- testes independentes e que podem ser repetidos: cada teste no GoogleTest é feito em um objeto diferente e, se esse teste falhar, pode ser rodado separadamente do conjunto de testes;
- testes bem organizados na estrutura de código: no GoogleTest, é possível organizar testes por "test suites", ou conjuntos de testes, de modo que cada conjunto possa compartilhar dados/métodos e ajudar a manter um padrão de testes;
- testes portáteis e reutilizáveis: GoogleTest roda em diversas plataformas e sistemas operacionais, não sendo dependente de um recurso específico;
- testes que forneçam o máximo possível de informação sobre o erro: se um teste falhar, o GoogleTest pode abortar a execução desse teste e continuar com a execução dos próximos, de modo que a falha de testes não afeta a execução da rotina de testes.
Como instalar GoogleTest na sua máquina
[editar | editar código-fonte]Este tutorial assume que você irá utilizar o GoogleTest em uma máquina com sistema operacional Linux, ou em uma máquina Windows com WSL2 instalado.
Para instalar o GoogleTest em seu computador, abra um terminal e digite:
sudo apt-get install libgtest-dev
Certifique-se de ter também o g++ e o cmake instalado na sua máquina para poder rodar os programas em C++:
sudo apt-get install g++
sudo apt-get install cmake
ASSERT e EXPECT
[editar | editar código-fonte]Em GoogleTest, assertions checam se uma condição é verdadeira ou não. Podem retornar sucesso, falha não fatal ou falha fatal. Os macros ASSERT e EXPECT são os mais simples de serem utilizados dentro do GoogleTest. Ambos são um tipo de assertion, com a diferença de que ASSERT gera erros fatais ao falhar, interrompendo a rotina de testes, enquanto EXPECT gera erros não fatais, e não interrompem a rotina de testes.
Alguns usos de ASSERT e EXPECT podem ser visto na tabela abaixo. Para mais usos, verifique a documentação oficial do GoogleTest.
ASSERT | EXPECT | Explicação |
---|---|---|
ASSERT_TRUE(cond) | EXPECT_TRUE(cond) | Verifica se cond é verdadeira. |
ASSERT_FALSE(cond) | EXPECT_FALSE(cond) | Verifica se cond é falsa. |
ASSERT_EQ(a, b) | EXPECT_EQ(a, b) | Verifica se a == b. |
ASSERT_NE(a, b) | EXPECT_NE(a, b) | Verifica se a != b. |
ASSERT_GT(a, b) | EXPECT_GT(a, b) | Verifica se a > b. |
ASSERT_GE(a, b) | EXPECT_GE(a, b) | Verifica se a >= b. |
ASSERT_LT(a, b) | EXPECT_LT(a, b) | Verifica se a < b. |
ASSERT_LE(a, b) | EXPECT_LE(a, b) | Verifica se a <= b. |
ASSERT_STREQ(s1, s2) | EXPECT_STREQ(s1, s2) | Verifica se a string s1 == string s2. |
ASSERT_STRNE(s1, s2) | EXPECT_STRNE(s1, s2) | Verifica se a string s1 != string s2. |
Como usar GoogleTest no meu programa
[editar | editar código-fonte]Para entender como habilitar o Google Test no nosso código, vamos criar primeiro um arquivo fatorial.h, que define uma função para calcular o fatorial de um número:
// fatorial.h
#ifndef FATORIAL_H
#define FATORIAL_H
int fat(int n);
#endif
Agora, vamos criar um arquivo fatorial.cpp, em que iremos implementar nossa função fatorial:
// fatorial.cpp
#include "fatorial.hpp"
int fat(int n) {
if (n == 0 || n == 1)
return 1;
return n * fat(n - 1);
Por fim, vamos criar um arquivo fat_teste.cpp para escrever nossos testes e nossa main. Mas antes de escrever nosso arquivo de testes, vamos listar alguns casos de teste interessantes:
- n = 0?
- n = 1?
- n = 2?
- n = 5?
Note também que os testes são escritos no seguinte padrão:
TEST (<conjunto-de-teste>, <nome-do-teste>) {
// cada linha deve ter apenas uma chamada de ASSERT... ou EXPECT...
}
Implementando esses casos de testes, nosso arquivo fat_teste.cpp vai ficar assim:
// fat_test.cpp
#include <gtest/gtest.h>
#include "fatorial.h"
// n = 0?
TEST (FatTest, nIguala0) {
EXPECT_EQ(1, fat(0));
}
// n = 1?
TEST (FatTest, nIguala1) {
EXPECT_EQ(1, fat(1));
}
// n = 2?
TEST (FatTest, nIguala2) {
EXPECT_EQ(2, fat(2));
}
// n = 5?
TEST (FatTest, nIguala5) {
EXPECT_EQ(120, fat(5));
}
int main(int argc, char **argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
Como podemos observar no código, para usar o GoogleTest, nosso arquivo de teste deve:
- incluir a biblioteca do GoogleTest na primeira linha do arquivo;
#include <gtest/gtest.h>
- declarar a função main da seguinte forma:
int main(int argc, char **argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
Após escrever nosso arquivo de testes, devemos compilar nosso programa usando as flags -lgtest -lpthread, da seguinte forma:
g++ -o fat_test fat_test.cpp fatorial.cpp -lgtest -lpthread
ATENÇÃO! Note que se seu programa de testes utilizar mais de um arquivo .cpp/.h, o arquivo .cpp deve ser passado no comando de compilação e deve ser feito o include do arquivo .h nas primeiras linhas de código do arquivo de testes.
Após compilar, vamos finalmente executar nosso programa de testes:
./fat_test
E o output em nosso terminal deverá ser parecido com isso, o que significa que todos os testes tiveram sucesso:
lume@LUME:~/mac350/tutorial$ ./fat_test
[==========] Running 4 tests from 1 test suite.
[----------] Global test environment set-up.
[----------] 4 tests from FatTest
[ RUN ] FatTest.nIguala0 # RUN indica que o teste está sendo executado
[ OK ] FatTest.nIguala0 (0 ms) # OK indica que o teste teve sucesso
[ RUN ] FatTest.nIguala1
[ OK ] FatTest.nIguala1 (0 ms)
[ RUN ] FatTest.nIguala2
[ OK ] FatTest.nIguala2 (0 ms)
[ RUN ] FatTest.nIguala5
[ OK ] FatTest.nIguala5 (0 ms)
[----------] 4 tests from FatTest (0 ms total)
[----------] Global test environment tear-down
[==========] 4 tests from 1 test suite ran. (0 ms total)
[ PASSED ] 4 tests. # status final da rotina de testes
lume@LUME:~/mac350/tutorial$
Falha em testes
[editar | editar código-fonte]Para provar ainda mais a robustez de um sistema, às vezes é recomendado escrever testes cujo resultado deve ser sempre uma falha, ou seja, que irão falhar propositalmente. Por exemplo, sabemos que fatorial de 4 é 24, mas vamos escrever um teste que espere que fat(4) devolva 23:
// n = 0?
TEST (FatTest, nIguala4) {
EXPECT_EQ(23, fat(4));
}
Após compilar e executar o programa de testes novamente, temos o seguinte resultado:
lume@LUME:~/mac350/tutorial$ ./fat_test
[==========] Running 5 tests from 1 test suite.
[----------] Global test environment set-up.
[----------] 5 tests from FatTest
[ RUN ] FatTest.nIguala0
[ OK ] FatTest.nIguala0 (0 ms)
[ RUN ] FatTest.nIguala1
[ OK ] FatTest.nIguala1 (0 ms)
[ RUN ] FatTest.nIguala2
[ OK ] FatTest.nIguala2 (0 ms)
[ RUN ] FatTest.nIguala4
fat_test.cpp:22: Failure # as proximas 5 linhas demonstram que
Expected equality of these values: # o teste nIguala4 falhou, bem como o
23 # valor de retorno e o valor esperado
fat(4)
Which is: 24
[ FAILED ] FatTest.nIguala4 (22 ms)
[ RUN ] FatTest.nIguala5 # note que a rotina de testes continua
[ OK ] FatTest.nIguala5 (0 ms) # mesmo apos uma falha -> falha nao fatal
[----------] 5 tests from FatTest (22 ms total)
[----------] Global test environment tear-down
[==========] 5 tests from 1 test suite ran. (22 ms total)
[ PASSED ] 4 tests. # ao fim da rotina de testes, eh indicado
[ FAILED ] 1 test, listed below: # o numero de testes com sucesso, o numero de
[ FAILED ] FatTest.nIguala4 # testes que falharam e o nome dos testes que
1 FAILED TEST # falharam
lume@LUME:~/mac350/tutorial$