Macros e asserts

A macro TEST_CASE

Na macro TEST_CASE, fica a escrita do caso de teste em si. Isto é, as chamadas as macros de ASSERT.

O primeiro argumento passado a TEST_CASE, é o nome do caso de teste e o segundo argumento (opcional) é o nome da classe do caso de teste. Se não quiser informar, o caso de teste é vinculado a classe de nome "default" e, a virgula após o nome do caso de teste é obrigatória, mesmo que, após a virgula, não seja definido o nome da classe do caso de testes. Veja o exemplo abaixo:

TEST_CASE( primeiroTeste, MeusTestes ) {
    ASSERT_EQUALS( 1, 1, )
}

As macros de assert

As macros de assert suportam uma mensagem personalizada a ser mostrada no caso do assert falhar e não precisam ser finalizadas com ponto e vírgula.

No caso da macro ser chamada, por exemplo, dentro de um if/else sem blóco de código, é obrigatório não colocar o ponto e virgula no final da macro. Exemplo:

bool condicao = true;
    if ( condicao )
        ASSERT_EQUALS( 1, 1, );
    else ASSERT_EQUALS( 1, 2, )

O exemplo acima está errado porque há um ponto e virgula após a macro de assert, e antes do else do if. O correto é retirar o ponto e virgula como a seguir:

bool condicao = true;
    if ( condicao )
        ASSERT_EQUALS( 1, 1, )
    else ASSERT_EQUALS( 1, 2, )

A macro ASSERT_EQUALS

A macro de assert pode ser utilizada para testar se dois valores são iguais. Exemplos:

ASSERT_EQUALS( 1, 1, )

int a = 1;
int b = 1;
string c = "teste";
string d = "teste";

ASSERT_EQUALS( a, b, )
ASSERT_EQUALS( c, d, As strings não são iguais! )

No exemplo acima, são comparadas duas variáveis inteiras e duas variáveis tipo string. Perceba que no último assert, é passada como terceiro argumento, uma mensagem. Essa mensagem é mostrada, apenas se o assert falhar. Perceba que a mensagem não está entre aspas duplas. As aspas duplas não são necessárias. Caso contrário, as aspas duplas também são impressas.

Perceba também que, os asserts sem a mensagem a ser mostrada em caso de falha, têm uma virgula após os parâmetros e antes do fecha parenteses. Essa virgula é necessária, mesmo que o terceiro argumento não seja informado. Isso vale para todas as macros de assert e a macro TEST_CASE.


A macro ASSERT_NOT_EQUALS

É o contrário da macro ASSERT_EQUALS. Isto é, falha se os valores forem iguais. Exemplo:

string str1 = "teste";
string str2 = "teste2";

ASSERT_NOT_EQUALS( str1, str2, )

A macro ASSERT_EQUALS_ARRAYS

A macro ASSERT_EQUALS_ARRAYS pode ser utilizada para testar se dois arrays são iguais. Exemplo:

int arr1[] = { 1, 2, 3 };
int arr2[] = { 1, 2, 3 };

ASSERT_EQUALS_ARRAYS( arr1, arr2, 3, )

Os asserts de arrays recebem um terceiro parâmetro adicional: o tamanho do array. No exemplo acima, os arrays têm 3 elementos cada.


A macro ASSERT_NOT_EQUALS_ARRAYS

A macro ASSERT_NOT_EQUALS_ARRAYS pode ser utilizada para testar se dois arrays são diferentes. Exemplo:

int arr1[] = { 1, 2, 3 };
int arr2[] = { 3, 2, 1 };

ASSERT_EQUALS_ARRAYS( arr1, arr2, 3, )

A macro ASSERT_EQUALS_VECTORS

A macro ASSERT_EQUALS_VECTORS pode ser utilizada para testar se dois vectors são iguais. Exemplo:

vector vect1 = { 1, 2, 3 };
vector vect2 = { 1, 2, 3 };

ASSERT_EQUALS_VECTORS( vect1, vect2, )

A macro ASSERT_NOT_EQUALS_VECTORS

A macro ASSERT_NOT_EQUALS_VECTORS pode ser utilizada para testar se dois vectors são diferentes. Exemplo:

vector vect1 = { 1, 2, 3 };
vector vect2 = { 3, 2, 1 };

ASSERT_NOT_EQUALS_VECTORS( vect1, vect2, )

Atenção

Você pode desabilitar, ou habilitar, a impressão dos vetores no caso de falha no assert. Isso é útil para evitar impressão de vetores, caso eles tenham muitos elementos, por exemplo.

Para habilitar, ou desabilitar a impressão de vetores (ou arrays) na falha do assert, utilize a seguinte função:

xutest::set_print_vectors( true ); // Para habilitar
xutest::set_imp_vectors( false );  // para desabilitar

Esta função set_print_vectors está no header "xutest.h" e no namespace xutest. Agora, veja abaixo dois exemplos:

xutest::set_print_vectors( true ); // Para habilitar

vector vect1 = { 1, 2, 3 };
vector vect2 = { 3, 2, 1 };

ASSERT_EQUALS_VECTORS( vect1, vect2, )

Os vetores são impressos, pois, o assert falha e a flag de impressão de vetores está setada para true. Setada através do método set_print_vectors

xutest::set_print_vectors( false ); // Para desabilitar

vector vect1 = { 1, 2, 3 };
vector vect2 = { 3, 2, 1 };

ASSERT_EQUALS_VECTORS( vect1, vect2, ) 

Os vetores não são impressos, pois, apesar de o assert falhar, a flag de impressão de vetores está setada para false.


A macro ASSERT_TRUE

A macro assert true testa se uma condição é verdadeira. Exemplo:

int a = 1;

ASSERT_TRUE( a > 0, )

A macro ASSERT_FALSE

A macro assert false testa se uma condição é falsa. Exemplo:

int a = 1;

ASSERT_FALSE( a == 0, )

A macro ASSERT_NULL

A macro ASSERT_NULL testa se o ponteiro aponta para nullptr ou NULL. Exemplo:

string* strptr = nullptr;

ASSERT_NULL( strptr, )

A macro ASSERT_NOT_NULL

A macro ASSERT_NOT_NULL testa se o ponteiro não aponta, nem para nullptr, nem para NULL. Exemplo:

string* strptr = new string( "abc" );

ASSERT_NOT_NULL( strptr, )

A macro ASSERT_THROWS

A macro ASSERT_THROWS testa se uma determinada exceção foi lançada. Exemplo:

ASSERT_THROWS( runtime_error, {
    // Código qualquer
    throw runtime_error( "XXX" );    // lança uma runtime_error
}, );
A macro ASSERT_NOT_THROWS

A macro ASSERT_THROWS testa se uma determinada exceção não foi lançada. Exemplo:

ASSERT_NOT_THROWS( runtime_error, {
    // Código qualquer
}, );

O assert passa se o código dentro do bloco de código do ASSERT_NOT_THROWS não lançar uma exceção "runtime_error".

As macros BEFORE_ALL e AFTER_ALL

As macros BEFORE_ALL e AFTER_ALL, podem ser usadas para definir um bloco de código que deve ser executado antes de todos os testes da classe, ou, após todos os testes da classe, respectivemante.

A macro BEFORE_ALL

A macro BEFORE_ALL pode ser usada para definir o que deve ser executado antes de todos os testes da classe de casos de teste. Exemplo:

BEFORE_ALL( MeusTestes ) {
    cout << "Iniciando os testes da classe de testes MeusTestes" << endl;
}

TEST_CASE( teste1, MeusTestes ) {
    ASSERT_EQUALS( 1, 1, )
}

TEST_CASE( teste2, MeusTestes ) {
    ASSERT_TRUE( true, )
}

A mensagem do "cout" da definição BEFORE_ALL, é impressa antes de todos os testes da classe MeusTestes.


A macro AFTER_ALL

A macro AFTER_ALL pode ser usada para definir o que deve ser executado depois de todos os testes da classe de casos de teste. Exemplo:

AFTER_ALL( MeusTestes ) {
    cout << "Finalizando os testes da classe de testes MeusTestes" << endl;
}

A mensagem do "cout" da definição AFTER_ALL, é impressa após de todos os testes da classe MeusTestes.

As macros BEFORE_EACH e AFTER_EACH

As macros BEFORE_EACH e AFTER_EACH, podem ser usadas para definir um bloco de código que deve ser executado antes de cada caso de teste da classe, ou, após cada caso de teste da classe, respectivemante.

A macro BEFORE_EACH

A macro BEFORE_EACH pode ser usada para definir o que deve ser executado antes de cada caso de teste da classe de casos de teste. Exemplo:

BEFORE_EACH( MeusTestes ) {
    cout << "Iniciando execução do caso de teste" << endl;
}

A mensagem do "cout" da definição BEFORE_EACH, é impressa antes de cada caso de teste da classe MeusTestes.


A macro AFTER_EACH

A macro AFTER_EACH pode ser usada para definir o que deve ser executado depois de cada caso de teste da classe de casos de teste. Exemplo:

AFTER_EACH( MeusTestes ) {
    cout << "Finalizando a execução do caso de teste" << endl;
}

A mensagem do "cout" da definição AFTER_EACH, é impressa após de cada caso de teste da classe MeusTestes.

Próxima aula

O próxima aula ensina como criar um exemplo completo de uma calculadora.