Test (gtest) Framework Question.

John Ralls jralls at ceridwen.us
Mon Jan 12 19:31:26 EST 2026


Yes, Googletest is the current preferred testing framework.

No, it’s not doing more than it needs to: The point is to test for a specific log message, not that any random thing got written to the log.

The static global handler_count is OK if you’re planning only one test per file, but otherwise it should be a stack variable in each test so that the tests are completely independent of one another. Pass a pointer to it in the user_data argument of g_log_set_handler() and the logger will pass it on to your handler.

Regards,
John Ralls


> On Jan 12, 2026, at 2:34 PM, Stefan Koch <stefan.koch.micro at gmail.com> wrote:
> 
> On Mon, Jan 12, 2026 at 4:29 PM John Ralls <jralls at ceridwen.us> wrote:
>> 
>> 
>> 
>>> On Jan 12, 2026, at 11:49 AM, Stefan Koch <stefan.koch.micro at gmail.com> wrote:
>>> 
>>> [OLDER STUFF DELETED]
>>> 
>>> The test still passes, but the output is messed up.   Is there a way
>>> to setup the expectation for this assertion failure, and thus hide the
>>> output?  Or should I not worry about this?
>> 
>> There is, but it’s part of Glib’s testing apparatus. The infrastructure for it is in https://github.com/Gnucash/gnucash/blob/stable/common/test-core/unittest-support.c and you can see an example of its use in https://github.com/Gnucash/gnucash/blob/1d9b80f7ff4f53c2e8cdaa79d2be3fe5e0625c95/libgnucash/engine/test/utest-Account.cpp#L470. We set up some logging variables in the first 4 lines, then change the log handlers in lined 482 and 483. The checked handlers count the number of times a particular error is emitted and that’s tested in lines 485 and 487. The default logger is restored in line 489 but the fatal handler isn’t, and there’s one more check at line 492.
>> 
>> I’ve never tried using it in a Googletest test suite, but I can’t think of any reason it wouldn’t work. You’d just change the assert macro from g_assert_cmpint to EXPECT_EQ.
>> 
>> Regards,
>> John Ralls
>> 
>> 
> 
> I looked at that example, I think it looks like it is doing more than
> it really does.  The "test_null_handler" function does not do
> anything, so setting up the "check = test_error_struct_new".  (Maybe
> there are other parts where it matters.  This is what I ended up with.
> It seems to work great.
> 
> // The indicator for how many times test_count_handler has been called.
> static int handler_count = 0;
> 
> // This is the error handler that does nothing but count how many times it is
> // called.  The handler_count is incremented every time.
> static gboolean
> test_count_handler (const char *log_domain, GLogLevelFlags log_level,
>    const gchar *msg, gpointer user_data )
> {
>    handler_count++;
>    return FALSE;
> }
> 
> TEST(QofIDTest, collection_add)
> {
>    auto col = qof_collection_new(QOF_ID_BOOK);
>    auto book = qof_book_new();
>    auto job = gncJobCreate(book);
>    gncJobBeginEdit(job);
> 
>    EXPECT_FALSE(qof_collection_add_entity(NULL, NULL));
>    EXPECT_FALSE(qof_collection_add_entity(col, NULL));
>    EXPECT_FALSE(qof_collection_add_entity(NULL, QOF_INSTANCE(book)));
> 
>    EXPECT_TRUE(qof_collection_add_entity(col, QOF_INSTANCE(book)));
>    EXPECT_FALSE(qof_collection_add_entity(col, QOF_INSTANCE(book)));
>    handler_count = 0;
>    auto oldlogger =
> g_log_set_default_handler((GLogFunc)test_null_handler, NULL);
>    EXPECT_FALSE(qof_collection_add_entity(col, QOF_INSTANCE(job)));
>    EXPECT_EQ(handler_count, 1);
>    g_log_set_default_handler(oldlogger, NULL);
> 
>    gncJobDestroy(job);
>    qof_collection_destroy(col);
> }




More information about the gnucash-devel mailing list