GoogleTest: Como pular um teste?

119

Usando o Google Test 1.6 (Windows 7, Visual Studio C ++). Como posso desligar um determinado teste? (também conhecido como como posso impedir a execução de um teste). Há algo que eu possa fazer além de comentar todo o teste?

Do utilizador
fonte

Respostas:

177

Os documentos para o Google Test 1.7 sugerem :

"Se você tiver um teste quebrado que não pode corrigir imediatamente, você pode adicionar o prefixo DISABLED_ ao seu nome. Isso irá excluí-lo da execução."

Exemplos:

// Tests that Foo does Abc.
TEST(FooTest, DISABLED_DoesAbc) { ... }

class DISABLED_BarTest : public ::testing::Test { ... };

// Tests that Bar does Xyz.
TEST_F(DISABLED_BarTest, DoesXyz) { ... }
Conta
fonte
1
também encontrei e filtros
Usuário de
@Bill, encontrei um pouco antes de você postar seu comentário ... (e também o coloquei como uma resposta). Eu então removi meu comentário, achando que é obsoleto ... mas essa é uma informação muito boa! +1
Kiril
67

Você também pode executar um subconjunto de testes , de acordo com a documentação:

Executando um Subconjunto de Testes

Por padrão, um programa de teste do Google executa todos os testes que o usuário definiu. Às vezes, você deseja executar apenas um subconjunto dos testes (por exemplo, para depurar ou verificar rapidamente uma alteração). Se você definir a variável de ambiente GTEST_FILTER ou a sinalização --gtest_filter como uma string de filtro, o Google Test executará apenas os testes cujos nomes completos (na forma de TestCaseName.TestName) correspondam ao filtro.

O formato de um filtro é uma lista separada por ':' de padrões de caracteres curinga (chamados de padrões positivos), opcionalmente seguida por um '-' e outra ':' - lista de padrões separados (chamados de padrões negativos). Um teste corresponde ao filtro se e somente se ele corresponder a qualquer um dos padrões positivos, mas não corresponder a nenhum dos padrões negativos.

Um padrão pode conter '*' (corresponde a qualquer string) ou '?' (corresponde a qualquer caractere único). Por conveniência, o filtro '* -NegativePatterns' também pode ser escrito como '-NegativePatterns'.

Por exemplo:

./foo_test Has no flag, and thus runs all its tests.
./foo_test --gtest_filter=* Also runs everything, due to the single match-everything * value.
./foo_test --gtest_filter=FooTest.* Runs everything in test case FooTest.
./foo_test --gtest_filter=*Null*:*Constructor* Runs any test whose full name contains either "Null" or "Constructor".
./foo_test --gtest_filter=-*DeathTest.* Runs all non-death tests.
./foo_test --gtest_filter=FooTest.*-FooTest.Bar Runs everything in test case FooTest except FooTest.Bar. 

Não é a solução mais bonita, mas funciona.

Kiril
fonte
24

Agora você pode usar a GTEST_SKIP()macro para pular condicionalmente um teste em tempo de execução. Por exemplo:

TEST(Foo, Bar)
{
    if (blah)
        GTEST_SKIP();

    ...
}

Observe que este é um recurso muito recente, portanto, pode ser necessário atualizar sua biblioteca do GoogleTest para usá-lo.

Peter Bloomfield
fonte
Este recurso ainda não foi lançado. É improvável que ele seja incluído em um branch 1.8.x, uma vez que apenas correções são aceitas lá. 1.9 ainda não está disponível, nem mesmo anunciado neste momento.
ocroquette
2
GTEST_SKIP()está disponível a partir de 1.10.0.
mattdibi
Infelizmente, a documentação ainda é escassa em torno disso. Parece que também GTEST_SKIP_("some message")(observe o sublinhado à direita)
Matthäus Brandl,
19

Esta é a expressão para incluir testes cujos nomes tenham as strings foo1 ou foo2 e excluir os testes cujos nomes tenham as strings bar1 ou bar2:

--gtest_filter=*foo1*:*foo2*-*bar1*:*bar2*
Ashutosh
fonte
10

Eu prefiro fazer em código:

// Run a specific test only
//testing::GTEST_FLAG(filter) = "MyLibrary.TestReading"; // I'm testing a new feature, run something quickly

// Exclude a specific test
testing::GTEST_FLAG(filter) = "-MyLibrary.TestWriting"; // The writing test is broken, so skip it

Posso comentar ambas as linhas para executar todos os testes, descomentar a primeira linha para testar um único recurso que estou investigando / trabalhando ou descomentar a segunda linha se um teste não funcionar, mas quero testar todo o resto.
Você também pode testar / excluir um conjunto de recursos usando curingas e escrevendo uma lista, "MyLibrary.TestNetwork *" ou "-MyLibrary.TestFileSystem *".

Pilkch
fonte
Esta é uma otima soluçao. Eu o uso para excluir alguns testes por padrão se o filtro estiver em branco. Eles podem ser ativados com export GTEST_FILTER='*'.
Timmmm
Na verdade, isso não funciona porque o padrão é " *" não "". Em vez disso, vou apenas usar outra variável de ambiente que substitui o filtro.
Timmmm
Onde você definiu o "filtro"? É uma corda?
beasone
Eu não o defino, então acho que deve ser um global incluído em gtest / gtest.h?
pilkch de
6

Se mais de um teste for necessário, será ignorado

--gtest_filter=-TestName.*:TestName.*TestCase
Vijay C
fonte
4

Para outra abordagem, você pode agrupar seus testes em uma função e usar verificações condicionais normais em tempo de execução para executá-los apenas se desejar.

#include <gtest/gtest.h>

const bool skip_some_test = true;

bool some_test_was_run = false;

void someTest() {
   EXPECT_TRUE(!skip_some_test);
   some_test_was_run = true;
}

TEST(BasicTest, Sanity) {
   EXPECT_EQ(1, 1);
   if(!skip_some_test) {
      someTest();
      EXPECT_TRUE(some_test_was_run);
   }
}

Isso é útil para mim, pois estou tentando executar alguns testes apenas quando um sistema oferece suporte a IPv6 de pilha dupla.

Tecnicamente, esse material de pilha dupla não deve ser um teste de unidade, pois depende do sistema. Mas eu não posso realmente fazer nenhum teste de integração até que eu teste se eles funcionam de qualquer maneira e isso garante que ele não relatará falhas quando não for a falha dos códigos.

Quanto ao teste, tenho objetos stub que simulam o suporte de um sistema para dualstack (ou falta de) por meio da construção de soquetes falsos.

A única desvantagem é que a saída do teste e o número de testes mudarão, o que pode causar problemas com algo que monitora o número de testes bem-sucedidos.

Você também pode usar ASSERT_ * em vez de EQUAL_ *. Afirme a vontade sobre o resto do teste se ele falhar. Impede que muitas coisas redundantes sejam despejadas no console.

David C. Bishop
fonte
4

Eu tinha a mesma necessidade de testes condicionais e descobri uma boa solução alternativa. Eu defini uma macro TEST_C que funciona como uma macro TEST_F, mas ela possui um terceiro parâmetro, que é uma expressão booleana, avaliada em runtime em main.cpp ANTES dos testes serem iniciados. Os testes que avaliam falso não são executados. A macro é feia, mas parece:

#pragma once
extern std::map<std::string, std::function<bool()> >* m_conditionalTests;
#define TEST_C(test_fixture, test_name, test_condition)\
class test_fixture##_##test_name##_ConditionClass\
{\
    public:\
    test_fixture##_##test_name##_ConditionClass()\
    {\
        std::string name = std::string(#test_fixture) + "." + std::string(#test_name);\
        if (m_conditionalTests==NULL) {\
            m_conditionalTests = new std::map<std::string, std::function<bool()> >();\
        }\
        m_conditionalTests->insert(std::make_pair(name, []()\
        {\
            DeviceInfo device = Connection::Instance()->GetDeviceInfo();\
            return test_condition;\
        }));\
    }\
} test_fixture##_##test_name##_ConditionInstance;\
TEST_F(test_fixture, test_name)

Além disso, em seu main.cpp, você precisa desse loop para excluir os testes que avaliam falso:

// identify tests that cannot run on this device
std::string excludeTests;
for (const auto& exclusion : *m_conditionalTests)
{
    bool run = exclusion.second();
    if (!run)
    {
        excludeTests += ":" + exclusion.first;
    }
}

// add the exclusion list to gtest
std::string str = ::testing::GTEST_FLAG(filter);
::testing::GTEST_FLAG(filter) = str + ":-" + excludeTests;

// run all tests
int result = RUN_ALL_TESTS();
Jiri Zbranek
fonte
Como você definiu "filtro" em std :: string str = :: testing :: GTEST_FLAG (filter) ;?
beasone