ASSERT_TRUE and EXPECT_TRUE do not provide a boolean context

7,190 views
Skip to first unread message

David Wilcox

unread,
Oct 28, 2013, 12:14:45 PM10/28/13
to googletes...@googlegroups.com
ASSERT_TRUE and EXPECT_TRUE do not provide a boolean context.

This can be manifest in the following way:

std::shared_ptr<int> foo(new int(5));
ASSERT_TRUE(foo); // this does not compile.

Strangely, ASSERT_FALSE and EXPECT_FALSE *do* provide a boolean context.

std::shared_ptr<int> foo;
ASSERT_FALSE(foo); // this compiles.

This change is a breaking change from gtest 1.6. gtest 1.6 provided a boolean context for ASSERT_TRUE and EXPECT_TRUE.

I attach a patch that should provide a fix for the problem. The patch makes ASSERT_TRUE and EXPECT_TRUE provide a boolean context so that explicit bool operators will be invoked.

gtest-out.txt

Gregor Jasny

unread,
Feb 1, 2016, 4:11:14 PM2/1/16
to Google C++ Testing Framework
I created a PR with that patch:
https://github.com/google/googletest/pull/700

Zhanyong Wan (λx.x x)

unread,
Feb 2, 2016, 12:31:39 PM2/2/16
to Gregor Jasny, Google C++ Testing Framework
Thanks, Gregor.

It was a conscious decision for ASSERT_TRUE/EXPECT_TRUE to not provide a Boolean context, as we feel that

  ASSERT_TRUE(some_non_bool_expression);

can be misleading/confusing.  Instead of

  ASSERT_TRUE(some_int);
  EXPECT_TRUE(some_pointer);

it's more intent-revealing to write

  ASSERT_NE(some_int, 0);
  EXPECT_TRUE(some_pointer != nullptr);

Thanks.

On Sun, Jan 31, 2016 at 3:15 PM, Gregor Jasny <gja...@googlemail.com> wrote:
I created a PR with that patch:
https://github.com/google/googletest/pull/700

--

---
You received this message because you are subscribed to the Google Groups "Google C++ Testing Framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to googletestframe...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

--




--
Zhanyong

Billy Donahue

unread,
Feb 2, 2016, 3:30:58 PM2/2/16
to Zhanyong Wan (λx.x x), Gregor Jasny, Google C++ Testing Framework
On Tue, Feb 2, 2016 at 12:31 PM, 'Zhanyong Wan (λx.x x)' via Google C++ Testing Framework <googletes...@googlegroups.com> wrote:
Thanks, Gregor.

It was a conscious decision for ASSERT_TRUE/EXPECT_TRUE to not provide a Boolean context, as we feel that

  ASSERT_TRUE(some_non_bool_expression);

can be misleading/confusing.  Instead of

  ASSERT_TRUE(some_int);
  EXPECT_TRUE(some_pointer);

it's more intent-revealing to write

  ASSERT_NE(some_int, 0);

Requires an exemplar 'false' value.
 
  EXPECT_TRUE(some_pointer != nullptr);

That doesn't print some_pointer.

I think it's still up to the user here. We have a lot of new bool-convertible types now and soon, like std::experimental::optional, std::function, and fancy smartpointers.

Zhanyong Wan (λx.x x)

unread,
Feb 2, 2016, 3:46:02 PM2/2/16
to Billy Donahue, Gregor Jasny, Google C++ Testing Framework
On Tue, Feb 2, 2016 at 12:30 PM, Billy Donahue <billyd...@google.com> wrote:


On Tue, Feb 2, 2016 at 12:31 PM, 'Zhanyong Wan (λx.x x)' via Google C++ Testing Framework <googletes...@googlegroups.com> wrote:
Thanks, Gregor.

It was a conscious decision for ASSERT_TRUE/EXPECT_TRUE to not provide a Boolean context, as we feel that

  ASSERT_TRUE(some_non_bool_expression);

can be misleading/confusing.  Instead of

  ASSERT_TRUE(some_int);
  EXPECT_TRUE(some_pointer);

it's more intent-revealing to write

  ASSERT_NE(some_int, 0);

Requires an exemplar 'false' value.

Why would this be a bad thing?
 
  EXPECT_TRUE(some_pointer != nullptr);

That doesn't print some_pointer.

If this fails, you know that some_pointer is nullptr already, so there's no need to print it.

In any case, this is just an example.  You can write the assertion in a way that it prints the pointer if you want. 

I think it's still up to the user here. We have a lot of new bool-convertible types now and soon, like std::experimental::optional, std::function, and fancy smartpointers.

The code should be close to the language people think in.  Most people don't think "this integer is true".  They think "this integer is not zero".

If needed we could provide an AsBool(m) matcher for evaluating the argument in a bool context, e.g.

ASSERT_THAT(some_pointer, AsBool(true));

The idea is to make the use of the bool context explicit.

--
Zhanyong

Brandon Kohn

unread,
Apr 13, 2018, 2:29:23 PM4/13/18
to Google C++ Testing Framework
I realize this thread is very old, but I just wanted to say that I don't really agree with the reasoning for not applying a boolean context in this case. For one, the language is C++, and as such I think it's reasonable to expect the same semantics inside:

EXPECT_TRUE(bool_expr)

as one would from:

if( bool_expr )

The macro name is EXPECT_TRUE. The boolean context is even implied in the name. Yes it's easy enough to go through the code and fix breaking tests for pointers and boost::optional instances, but I'm not sure what has been gained is really worth what has been lost. Maybe rethink this? 

Samuel Benzaquen

unread,
Apr 13, 2018, 2:41:30 PM4/13/18
to brandon...@gmail.com, Google C++ Testing Framework
afaik, this is already the case for some time now.
EXPECT_TRUE et al will accept anything that converts to bool implicitly or explicitly.
Is this still failing for you with a recent version of gTest?

Brandon Kohn

unread,
Apr 13, 2018, 5:00:32 PM4/13/18
to Google C++ Testing Framework
On Friday, April 13, 2018 at 2:41:30 PM UTC-4, Samuel Benzaquen wrote:
afaik, this is already the case for some time now.
EXPECT_TRUE et al will accept anything that converts to bool implicitly or explicitly.
Is this still failing for you with a recent version of gTest?

You're right, I just tested this against the master head. Someone at work told me they had an issue with using boost::optional<T> and I rushed out looking and found this before verifying. 

Apologies for the noise...
Reply all
Reply to author
Forward
0 new messages