gtest parametrizado para teste HAL

Para uma interface HAL, pode haver várias implementações. Para testar cada instância para uma implementação de HAL, a maneira padrão é escrever um gtest parametrizado por valor .

Configuração básica de teste

O gtest deve herdar a classe base testing::TestWithParam , cujo parâmetro é o nome de cada instância. No método SetUp , o serviço pode ser instanciado com base no nome da instância, conforme mostrado no trecho de código a seguir.

// The main test class for the USB hidl HAL
class UsbHidlTest : public testing::TestWithParam<std::string> {

 virtual void SetUp() override {
   usb = IUsb::getService(GetParam());
   ASSERT_NE(usb, nullptr);
...
 }

Para cada método de teste, use a macro TEST_P conforme mostrado no exemplo abaixo.

TEST_P(UsbHidlTest, setCallback) {
...
}

Instancie a suíte com a macro INSTANTIATE_TEST_SUITE_P , conforme mostrado no exemplo abaixo.

INSTANTIATE_TEST_SUITE_P(
       PerInstance, UsbHidlTest,
       testing::ValuesIn(android::hardware::getAllHalInstanceNames(IUsb::descriptor)),
       android::hardware::PrintInstanceNameToString);

Os argumentos são:

  1. InstantiationName , que pode ser qualquer coisa que corresponda ao seu teste. PerInstance é um nome comum.

  2. O nome da classe de teste.

  3. Uma coleção de nomes de instância, que podem ser recuperados do método integrado, por exemplo, getAllHalInstanceNames .

  4. O método para imprimir o nome do método de teste. PrintInstanceNameToString é um nome interno que você pode usar para compilar um nome de teste com base no nome da instância e no nome do método de teste.

Teste com várias entradas

gtest suporta tuplas para testes com parâmetros de valor. Quando um teste HAL requer testes com várias entradas (por exemplo, um teste com várias interfaces), você pode escrever um gtest com tuple como parâmetro de teste. O código completo pode ser encontrado em VtsHalGraphicsMapperV2_1TargetTest .

Comparado ao gtest com um único parâmetro de teste, este teste precisa usar tuple como parâmetro de teste, conforme mostrado no exemplo abaixo.

class GraphicsMapperHidlTest
   : public ::testing::TestWithParam<std::tuple<std::string, std::string>> {
 protected:
   void SetUp() override {
       ASSERT_NO_FATAL_FAILURE(mGralloc = std::make_unique<Gralloc>(std::get<0>(GetParam()),
                                                                    std::get<1>(GetParam())));
…
}

Se forem necessários parâmetros mais complicados, é recomendável usar uma estrutura e funções gtest ToString personalizadas.

Para instanciar a suíte de testes, também é utilizada a macro INSTANTIATE\_TEST\_CASE\_P , com duas diferenças:

  • O terceiro argumento é uma coleção de tuplas (versus uma coleção de strings no caso básico).
  • O método para compilar um nome de teste precisa suportar tuple . Você pode usar o método interno PrintInstanceTupleNameToString , que pode manipular tuplas de strings, conforme mostrado no exemplo abaixo.
INSTANTIATE_TEST_CASE_P(
       PerInstance, GraphicsMapperHidlTest,
       testing::Combine(
               testing::ValuesIn(
                       android::hardware::getAllHalInstanceNames(IAllocator::descriptor)),
           testing::ValuesIn(android::hardware::getAllHalInstanceNames(IMapper::descriptor))),
       android::hardware::PrintInstanceTupleNameToString<>);