For a HAL interface, there might be multiple implementations. To test each instance for a HAL implementation, the standard way is to write a value-parameterized GTest.
Basic test setup
The GTest must inherit the base class testing::TestWithParam
, of
which the parameter is the name of each instance. In the
SetUp
method, the service can be instantiated based on the
instance name, as shown in the following code snippet.
// 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);
...
}
For each test method, use the macro TEST_P
as shown in the following example:
TEST_P(UsbHidlTest, setCallback) {
...
}
Instantiate the suite with
macro INSTANTIATE_TEST_SUITE_P
, as shown in the following example:
INSTANTIATE_TEST_SUITE_P(
PerInstance, UsbHidlTest,
testing::ValuesIn(android::hardware::getAllHalInstanceNames(IUsb::descriptor)),
android::hardware::PrintInstanceNameToString);
The arguments are:
InstantiationName
, which can be anything that matches your test.PerInstance
is a common name.The test class name.
A collection of instance names, which can be retrieved from the built-in method, for example,
getAllHalInstanceNames
.The method to print the test method name.
PrintInstanceNameToString
is a built-in name you can use to compile a test name based on the instance name and test method name.
Test with multiple inputs
GTest supports tuples for value-parameterized tests. When a
HAL test requires testing with multiple inputs (for example, a test with
multiple interfaces), you can write a GTest with tuple
as the
test parameter. The complete
code can be found in VtsHalGraphicsMapperV2_1TargetTest
.
Compared to the GTest with a single test parameter, this test needs to use
tuple
as the test parameter as shown in the following example:
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())));
…
}
If more complicated parameters are needed, it's recommended to use a
structure and custom GTest ToString
functions.
To instantiate the test suite, the macro INSTANTIATE\_TEST\_CASE\_P
is also
used, with two differences:
- The third argument is a collection of tuples (versus a collection of strings in the basic case).
- The method to compile a test name needs to support
tuple
. You can use the built-in methodPrintInstanceTupleNameToString
, which can handle tuples of strings, as shown in the following example:
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<>);