Как проверить вывод логгера ускорения в модульном тестировании?

Мое приложение использует BOOST_LOG_TRIVIAL для регистрации сообщений. Я подумал, что хорошо проверить в тесте (gtest), что там написаны правильные сообщения в заданных сценариях.

Есть ли способ каким-то образом получить доступ к тому, что было написано там после вызова кода? Или сначала надо как-то поиздеваться?

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
1 356
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

В вашем тестовом пакете Google вы можете использовать возможности boost::log в каждый тестовый пример для перенаправления сообщений BOOST_LOG_TRIVIAL в файл. После записи сообщения (сообщений) BOOST_LOG_TRIVIAL, которое вы хотите, вы можете очистите файл, откройте его и убедитесь, что в нем есть ожидаемое содержимое. Например:

gtester.cpp

#include <gtest/gtest.h>
#include <boost/shared_ptr.hpp>
#include <boost/log/sinks/sync_frontend.hpp>
#include <boost/log/sinks/text_file_backend.hpp>
#include <boost/log/utility/setup/file.hpp>
#include <boost/log/trivial.hpp>
#include <string>
#include <fstream>

using sink_t = boost::log::sinks::synchronous_sink<boost::log::sinks::text_file_backend>;

struct boost_log_tester : ::testing::Test {
    void SetUp() {
        file_sink = boost::log::add_file_log("boost.log");
    }
    void TearDown() {
        boost::log::core::get()->remove_sink(file_sink);
        file_sink.reset();
    }
protected:
    boost::shared_ptr<sink_t> file_sink;
};

TEST_F(boost_log_tester,info_msg)
{
    std::string msg = "An informational severity message";
    BOOST_LOG_TRIVIAL(info) << msg;
    file_sink->flush();
    std::ifstream captured_cout("boost.log");
    ASSERT_TRUE(captured_cout.good()) << "Failure executing test: Could not open `boost.log` for reading";
    std::string cout_str;
    std::getline(captured_cout,cout_str);
    EXPECT_NE(cout_str.find(msg),std::string::npos);
}

TEST_F(boost_log_tester,error_msg)
{
    std::string msg = "An error severity message";
    BOOST_LOG_TRIVIAL(error) << msg;
    file_sink->flush();
    std::ifstream captured_cerr("boost.log");
    ASSERT_TRUE(captured_cerr.good()) << "Failure executing test: Could not open `boost.log` for reading";
    std::string cerr_str;
    std::getline(captured_cerr,cerr_str);
    EXPECT_NE(cerr_str.find(msg),std::string::npos);
}

int main(int argc, char **argv) {
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

Скомпилируйте и свяжите:

$ g++ -Wall -Wextra -DBOOST_LOG_DYN_LINK -c gtester.cpp
$ g++ -o gtester gtester.o -lboost_log -lboost_thread -lboost_system -lgtest -pthread

И это работает так:

$ ./gtester 
[==========] Running 2 tests from 1 test case.
[----------] Global test environment set-up.
[----------] 2 tests from boost_log_tester
[ RUN      ] boost_log_tester.info_msg
[       OK ] boost_log_tester.info_msg (0 ms)
[ RUN      ] boost_log_tester.error_msg
[       OK ] boost_log_tester.error_msg (2 ms)
[----------] 2 tests from boost_log_tester (2 ms total)

[----------] Global test environment tear-down
[==========] 2 tests from 1 test case ran. (2 ms total)
[  PASSED  ] 2 tests.

Спасибо, Майк. Работает очень хорошо, но я вижу только обратную сторону этого решения в том, что оно требует создания файла.

Konrad 20.11.2018 13:14

Следуя ответу Майка, в котором я думаю, что необходимость создания файла является недостатком, я провел небольшое исследование и нашел такой способ использования вместо этого строкового потока:

class boost_logger_test : public testing::Test
{
    typedef boost::log::sinks::synchronous_sink<boost::log::sinks::text_ostream_backend> sink_t;
    boost::shared_ptr<sink_t> streamSink;
    std::stringstream ss;

public:
    virtual void SetUp()
    {
        streamSink = boost::log::add_console_log(ss);
    }

    virtual void TearDown()
    {
        boost::log::core::get()->remove_sink(streamSink);
        streamSink.reset();
    }

    std::vector<std::string> getLogMessages()
    {
        std::vector<std::string> messages;
        std::string msg;
        while (std::getline(ss, msg, '\n'))
        {
            messages.push_back(msg);
        }
        return messages;
    }
}

Тогда вы можете легко использовать сообщения в тестах, например:

ASSERT_THAT(getLogMessages(), ElementsAre("Just some log message"));

Собирался повторить то же самое, но вы уже там;)

Mike Kinghan 20.11.2018 21:11

Другие вопросы по теме