Как правильно использовать GTest для многократного повторения многопоточного теста? - PullRequest
1 голос
/ 19 июня 2020

Используя Google Test , я хочу проверить поведение метода ClientListener.AcceptRequest:

class ClientListener {
public:
    // Clients can call this method, want to test that it works
    Result AcceptRequest(const Request& request) {
        queue_.Add(request);
        ... blocks waiting for result ...
        return result;
    }
private:
    // Executed by the background_thread_;
    void ProcessRequestsInQueue() {
        while (true) {
            Process(queue_.PopEarliest());
        }
    }

    MyQueue queue_;
    std::thread background_thread_ = thread([this] {ProcessRequestsInQueue();});
};

Метод принимает клиентский запрос, ставит его в очередь, блокирует ожидание результата , возвращает результат, если доступен.

Результат доступен, когда фоновый поток обрабатывает соответствующий запрос из очереди.

У меня есть тест, который выглядит следующим образом:

TEST(ListenerTest, TwoRequests) {
    ClientListener listener;
    Result r1 = listener.AcceptClientRequest(request1);
    Result r2 = listener.AcceptClientRequest(request2);
    ASSERT_EQ(r1, correctResultFor1);
    ASSERT_EQ(r2, correctResultFor2);
}

Поскольку реализация класса ClientListener включает в себя несколько потоков, этот тест может пройти одну попытку, но потерпеть неудачу в другой. Чтобы увеличить вероятность обнаружения ошибки, я запускаю тест несколько раз:

TEST_P(ListenerTest, TwoRequests) {
  ... same as before ...
}
INSTANTIATE_TEST_CASE_P(Instantiation, ListenerTest, Range(0, 100));

Но теперь команда make test обрабатывает каждый параметризованный экземпляр как отдельный тест, а в журналах я вижу 100 тестов:

Test 1: Instantiation/ListenerTest.TwoRequests/1
Test 2: Instantiation/ListenerTest.TwoRequests/2
...
Test 100: Instantiation/ListenerTest.TwoRequests/100

Учитывая, что я не использую значение параметра, существует ли способ переписать тестовый код таким образом, чтобы команда make test регистрировала один тест, выполненный 100 раз, а не 100 тесты ?

1 Ответ

2 голосов
/ 22 июня 2020

Простой ответ: используйте --gtest_repeat при выполнении тестов (по умолчанию 1).

Более длинный ответ: модульные тесты не должны использоваться для такого рода тестов. GTest является потокобезопасным по своей конструкции (как указано в их README ), но это не значит, что это хороший инструмент для выполнения таких тестов. Возможно, это хорошая отправная точка для начала работы над реальными интеграционными тестами, я действительно рекомендую для этой цели Python фреймворк.

...