Parametrisierter gtest für HAL-Tests

Für eine HAL-Schnittstelle kann es mehrere Implementierungen geben. Um jede Instanz für eine HAL-Implementierung zu testen, besteht die Standardmethode darin, einen wertparametrisierten gtest zu schreiben.

Grundlegender Testaufbau

Der gtest muss die Basisklasse testing::TestWithParam erben, deren Parameter der Name jeder Instanz ist. In der SetUp Methode kann der Dienst basierend auf dem Instanznamen instanziiert werden, wie im folgenden Codeausschnitt gezeigt.

// 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);
...
 }

Verwenden Sie für jede Testmethode das Makro TEST_P , wie im folgenden Beispiel gezeigt.

TEST_P(UsbHidlTest, setCallback) {
...
}

Instanziieren Sie die Suite mit dem Makro INSTANTIATE_TEST_SUITE_P , wie im folgenden Beispiel gezeigt.

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

Die Argumente sind:

  1. InstantiationName , der alles sein kann, was zu Ihrem Test passt. PerInstance ist ein gebräuchlicher Name.

  2. Der Name der Testklasse.

  3. Eine Sammlung von Instanznamen, die von der integrierten Methode abgerufen werden können, zum Beispiel getAllHalInstanceNames .

  4. Die Methode zum Drucken des Testmethodennamens. PrintInstanceNameToString ist ein integrierter Name, den Sie zum Kompilieren eines Testnamens basierend auf dem Instanznamen und dem Namen der Testmethode verwenden können.

Testen Sie mit mehreren Eingaben

gtest unterstützt Tupel für wertparametrisierte Tests. Wenn ein HAL-Test Tests mit mehreren Eingaben erfordert (z. B. ein Test mit mehreren Schnittstellen), können Sie einen gtest mit tuple als Testparameter schreiben. Den vollständigen Code finden Sie in VtsHalGraphicsMapperV2_1TargetTest .

Im Vergleich zum gtest mit einem einzelnen Testparameter muss dieser Test tuple als Testparameter verwenden, wie im folgenden Beispiel gezeigt.

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())));
…
}

Wenn kompliziertere Parameter benötigt werden, empfiehlt es sich, eine Struktur und benutzerdefinierte gtest ToString Funktionen zu verwenden.

Um die Testsuite zu instanziieren, wird auch das Makro INSTANTIATE\_TEST\_CASE\_P verwendet, mit zwei Unterschieden:

  • Das dritte Argument ist eine Sammlung von Tupeln (im Gegensatz zu einer Sammlung von Zeichenfolgen im Grundfall).
  • Die Methode zum Kompilieren eines Testnamens muss tuple unterstützen. Sie können die integrierte Methode PrintInstanceTupleNameToString verwenden, die Tupel von Zeichenfolgen verarbeiten kann, wie im folgenden Beispiel gezeigt.
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<>);