What is the difference between expect(something).toBe(true)
, expect(something).toBeTruthy()
and expect(something).toBeTrue()
?
Note that toBeTrue()
is a custom matcher introduced in jasmine-matchers
among other useful and handy matchers like toHaveMethod()
or toBeArrayOfStrings()
.
The question is meant to be generic, but, as a real-world example, I'm testing that an element is displayed in protractor
. Which matcher should I use in this case?
expect(elm.isDisplayed()).toBe(true);
expect(elm.isDisplayed()).toBeTruthy();
expect(elm.isDisplayed()).toBeTrue();
I know everybody loves an easy-to-read list:
toBe(<value>)
- The returned value is the same as<value>
toBeTrue()
- Checks if the returned value istrue
toBeTruthy()
- Check if the value, when cast to a boolean, will be a truthy valueTruthy values are all values that aren't
0
,''
(empty string),false
,null
,NaN
,undefined
or[]
(empty array)*.* Notice that when you run
!![]
, it returnstrue
, but when you run[] == false
it also returnstrue
. It depends on how it is implemented. In other words:(!![]) === ([] == false)
On your example,
toBe(true)
andtoBeTrue()
will yield the same results.In javascript there are trues and truthys. When something is true it is obviously true or false. When something is truthy it may or may not be a boolean, but the "cast" value of is a boolean.
Examples.
This can make things simpler if you want to check if a string is set or an array has any values.
And as stated.
expect(something).toBe(true)
andexpect(something).toBeTrue()
is the same. Butexpect(something).toBeTruthy()
is not the same as either of those.There are a lot many good answers out there, i just wanted to add a scenario where the usage of these expectations might be helpful. Using
element.all(xxx)
, if i need to check if all elements are displayed at a single run, i can perform -Reason being
.all()
returns an array of values and so all kinds of expectations(getText
,isPresent
, etc...) can be performed withtoBeTruthy()
when.all()
comes into picture. Hope this helps.What I do when I wonder something like the question asked here is go to the source.
toBe()
expect().toBe()
is defined as:It performs its test with
===
which means that when used asexpect(foo).toBe(true)
, it will pass only iffoo
actually has the valuetrue
. Truthy values won't make the test pass.toBeTruthy()
expect().toBeTruthy()
is defined as:Type coercion
A value is truthy if the coercion of this value to a boolean yields the value
true
. The operation!!
tests for truthiness by coercing the value passed toexpect
to a boolean. Note that contrarily to what the currently accepted answer implies,== true
is not a correct test for truthiness. You'll get funny things likeWhereas using
!!
yields:(Yes, empty or not, an array is truthy.)
toBeTrue()
expect().toBeTrue()
is part of Jasmine-Matchers (which is registered on npm asjasmine-expect
after a later project registeredjasmine-matchers
first).expect().toBeTrue()
is defined as:The difference with
expect().toBeTrue()
andexpect().toBe(true)
is thatexpect().toBeTrue()
tests whether it is dealing with aBoolean
object.expect(new Boolean(true)).toBe(true)
would fail whereasexpect(new Boolean(true)).toBeTrue()
would pass. This is because of this funny thing:At least it is truthy:
Which is best suited for use with
elem.isDisplayed()
?Ultimately Protractor hands off this request to Selenium. The documentation states that the value produced by
.isDisplayed()
is a promise that resolves to aboolean
. I would take it at face value and use.toBeTrue()
or.toBe(true)
. If I found a case where the implementation returns truthy/falsy values, I would file a bug report.