Page 1 of 2
Unexpected behavior of assertEqual?
Posted: Wed May 28, 2008 2:20 am
by matthijs
I was using assertEqual($x, $y) to test if a database query returns the correct amount of rows. But then I discovered something weird
Code: Select all
function testSomeQuery(){
// some db code here..
// get the result from the db
$result = $stmt->execute(); // this returns TRUE or FALSE
// by my mistake I assumed the above returned the amount of rows, so I tested for that
$this->assertEqual($result, '2'); // and this gives a green bar!
}
The above example should be obvious. I did some db interaction and my assumption was that it would return the amount of rows from the db, in this specific case 2. Testing for that with assertEqual() gave a green bar so I thought that was that. But apparently the $result was not a row number at all but true or false. But still the assertEqual() passed as green.
There's also the test method assertIdentical(), which is the one I should have used.
Thinking some more about it I realized that in PHP
Code: Select all
'2' == TRUE returns true
2 == TRUE returns true
2 === TRUE returns false
so that was my mistake.
Still an easy mistake to make, isn't it?
Re: Unexpected behavior of assertEqual?
Posted: Wed May 28, 2008 5:14 am
by arjan.top
everything not zero is true, not just in php
Re: Unexpected behavior of assertEqual?
Posted: Sat May 31, 2008 8:26 am
by Ambush Commander
In general, I always use assertIdentical() because it helps pre-empt bugs like these. For example, did you know 2 == '2a'? (The string gets cast to an int, and when they're compared they're equivalent)
Re: Unexpected behavior of assertEqual?
Posted: Sat May 31, 2008 9:24 am
by matthijs
Yeah, I now changed all of them by assertIdentical. Luckily I kept the green bar
Re: Unexpected behavior of assertEqual?
Posted: Wed Jun 25, 2008 10:01 am
by LBmtb
Don't feel bad. I'm sure a lot of us have been tripped up by that before, I know it used to trip me up. One particular one that used to get me was something like
Code: Select all
if (strpos($string, 'isIn?')) {
// excecute code if our needle was in the haystack
}
To check if the $string had my needle. Of course sometimes if the needle was in the 0 position, that would equate to false.

Re: Unexpected behavior of assertEqual?
Posted: Sat Jun 28, 2008 11:01 pm
by Chris Corbyn
One of the only things which can trip even an exprienced programmer up occassionally in PHP is the way it treats boolean values as equal to just about anything. Anything with a value is true except for a few things.
Re: Unexpected behavior of assertEqual?
Posted: Thu Jul 10, 2008 12:52 pm
by Ollie Saunders
Chris Corbyn wrote:One of the only things which can trip even an exprienced programmer up occassionally in PHP is the way it treats boolean values as equal to just about anything. Anything with a value is true except for a few things.
Yeah, loose typing is convenient some times but confusing other times. Unfortunately you pretty much just have to commit the
type comparison tables to memory. I had them printed out on my desk for a while a few years back.
Re: Unexpected behavior of assertEqual?
Posted: Thu Jul 10, 2008 12:59 pm
by Benjamin
Chris Corbyn wrote:One of the only things which can trip even an exprienced programmer up occassionally in PHP is the way it treats boolean values as equal to just about anything. Anything with a value is true except for a few things.
I can understand how a non-zero value can evaluate as equal to boolean true, however consider this code.
Code: Select all
// outputs true
echo ('yes' == 0) ? 'true' : 'false';
// outputs true
echo ('yes') ? 'true' : 'false';
How can yes be equal to zero and true at the same time?
Without knowing the reasoning behind this behavior, I would be inclined to call it a bug.
Re: Unexpected behavior of assertEqual?
Posted: Thu Jul 10, 2008 1:07 pm
by Ambush Commander
Easy.
PHP has a really stupid string to integer algorithm. The gist of it is read letters from the beginning of the string until you hit a non-numeric one, and turn that into an integer.
So:
"23" == 23
"23in" == 23
"0f" == 0
"f" == 0
"true" == 0
However, "true" != false, because all strings except "" and "0" are true. Including "false".
Re: Unexpected behavior of assertEqual?
Posted: Thu Jul 10, 2008 1:17 pm
by Benjamin
You know, I was figuring it had something to do with PHP casting the string to an int rather than casting the int to a string.
Looks like what is actually happening is even worse.
Re: Unexpected behavior of assertEqual?
Posted: Thu Jul 10, 2008 1:28 pm
by Ambush Commander
No, you're exactly correct. == will
always cast a string to an integer if compared with an integer. Furthermore, if your strings are numeric, they will be cast to integers and compared, so "1" == "01"
Ya know, this is all in the manual:
http://docs.php.net/manual/en/language. ... arison.php
Re: Unexpected behavior of assertEqual?
Posted: Thu Jul 10, 2008 1:34 pm
by Benjamin
Any reason why it shouldn't convert the int to a string instead of doing the opposite?
Re: Unexpected behavior of assertEqual?
Posted: Thu Jul 10, 2008 1:37 pm
by Ambush Commander
PHP deals mostly with strings from web inputs, even if it is numeric. I suppose when they first made PHP they thought this behavior would be more convenient.
Re: Unexpected behavior of assertEqual?
Posted: Thu Jul 10, 2008 1:43 pm
by Ollie Saunders
This is why using === and type casts are nicer, you know what is going on then.
Re: Unexpected behavior of assertEqual?
Posted: Sun Jul 13, 2008 3:36 am
by Chris Corbyn
I love this one:
Code: Select all
if (false < -1) {
echo "False is LESS THAN -1\n";
}