Unexpected behavior of assertEqual?

Discussion of testing theory and practice, including methodologies (such as TDD, BDD, DDD, Agile, XP) and software - anything to do with testing goes here. (Formerly "The Testing Side of Development")

Moderator: General Moderators

matthijs
DevNet Master
Posts: 3360
Joined: Thu Oct 06, 2005 3:57 pm

Unexpected behavior of assertEqual?

Post 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?
User avatar
arjan.top
Forum Contributor
Posts: 305
Joined: Sun Oct 14, 2007 4:36 am
Location: Hoče, Slovenia

Re: Unexpected behavior of assertEqual?

Post by arjan.top »

everything not zero is true, not just in php
User avatar
Ambush Commander
DevNet Master
Posts: 3698
Joined: Mon Oct 25, 2004 9:29 pm
Location: New Jersey, US

Re: Unexpected behavior of assertEqual?

Post 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)
matthijs
DevNet Master
Posts: 3360
Joined: Thu Oct 06, 2005 3:57 pm

Re: Unexpected behavior of assertEqual?

Post by matthijs »

Yeah, I now changed all of them by assertIdentical. Luckily I kept the green bar
LBmtb
Forum Newbie
Posts: 23
Joined: Wed May 14, 2008 11:14 am

Re: Unexpected behavior of assertEqual?

Post 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. :banghead: :drunk:
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Re: Unexpected behavior of assertEqual?

Post 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.
User avatar
Ollie Saunders
DevNet Master
Posts: 3179
Joined: Tue May 24, 2005 6:01 pm
Location: UK

Re: Unexpected behavior of assertEqual?

Post 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.
User avatar
Benjamin
Site Administrator
Posts: 6935
Joined: Sun May 19, 2002 10:24 pm

Re: Unexpected behavior of assertEqual?

Post 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.
User avatar
Ambush Commander
DevNet Master
Posts: 3698
Joined: Mon Oct 25, 2004 9:29 pm
Location: New Jersey, US

Re: Unexpected behavior of assertEqual?

Post 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".
User avatar
Benjamin
Site Administrator
Posts: 6935
Joined: Sun May 19, 2002 10:24 pm

Re: Unexpected behavior of assertEqual?

Post 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.
User avatar
Ambush Commander
DevNet Master
Posts: 3698
Joined: Mon Oct 25, 2004 9:29 pm
Location: New Jersey, US

Re: Unexpected behavior of assertEqual?

Post 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
User avatar
Benjamin
Site Administrator
Posts: 6935
Joined: Sun May 19, 2002 10:24 pm

Re: Unexpected behavior of assertEqual?

Post by Benjamin »

Any reason why it shouldn't convert the int to a string instead of doing the opposite?
User avatar
Ambush Commander
DevNet Master
Posts: 3698
Joined: Mon Oct 25, 2004 9:29 pm
Location: New Jersey, US

Re: Unexpected behavior of assertEqual?

Post 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.
User avatar
Ollie Saunders
DevNet Master
Posts: 3179
Joined: Tue May 24, 2005 6:01 pm
Location: UK

Re: Unexpected behavior of assertEqual?

Post by Ollie Saunders »

This is why using === and type casts are nicer, you know what is going on then.
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Re: Unexpected behavior of assertEqual?

Post by Chris Corbyn »

I love this one:

Code: Select all

if (false < -1) {
  echo "False is LESS THAN -1\n";
}
Post Reply