PHPUnit "No Tests Executed" if I enable test string comparison - php

I have a couple of really basic tests written in PHPUnit and for some reason when I enable one of the assertions, I get "No Tests Executed."
I'm not a skilled unit tester, so it's clearly something I'm doing wrong, but I'm having a hard time tracking down a solution.
I'm testing for a string coming back from a Soap server it's either "true" or "false."
In my unit test if I write this
$hasErrors = 'false';
$this->assertTrue('true' == $hasErrors);
I get "No tests executed!"
If I do the following - I know it's not the same test but it is successful and PHPUnit reports it as successful - I'm just curious why this one runs the tests, while that previous doesn't just show a failure but says no test are executed.
$hasErrors = 'false';
$this->assertFalse('true' == $hasErrors);
I would like the failure to fail rather say "No tests executed."
The same thing happens if I use assertNotEquals rather than assertFalse.
More information. I might have stumbled across a phpunit bug when dealing with a text string "true." I think php unit is wanting to treat it as a boolean rather than a string. So I made some code changes to work with booleans.
$result = $xmlresponse->xpath('//result');
$hasErrors = (string) $result[0]->hasErrors;
if ($hasErrors == 'true') {
$errors = TRUE;
} else {
$errors = FALSE;
}
$this->assertFalse($errors);
Now I get.
PHP Fatal error: Uncaught Failed asserting that true is false.
Why do I need to "catch" this failed asserting? Shouldn't phpunit just report that the test failed?
I'm executing phpunit like this from cli.
phpunit --verbose --debug --configuration testSuite.xml
testSuite.xml looks like this:
<phpunit>
<testsuites>
<testsuite name="connector">
<file>TestNewAccount.class.php</file>
<file>TestModifyAccount.class.php</file>
</testsuite>
</testsuites>
</phpunit>
Update
So I guess my expectations of what PHPunit does out the box are not valid. I expected that phpunit would run the tests, report success and failures and that's that. But apparently it reports successes and throws fatal exceptions on an assertion failure. I don't understand why it's so heavy handed with failures and why it doesn't simply report the failure without me having to catch exceptions in my tests and handle it on my own.
I'm sure I'm still missing something, but for now, I'm not super impressed with phpunit out of the box. I guess it works but it seems to make me work harder than I want to in order to write a few simple tests and assertions.
Update 2
So I'm getting the response from phpunit that I was originally expecting. Now the failures are reporting as failures. I'm not sure what I'm doing differently now than I was before. Now I feel like I'm just cluttering up Stackoverflow with my own senseless rambling. Thanks for the help.

It's good practice to use a quite specific test - assertNotEquals('x', 'y') rather than assertFalse('x'=='y') - having to think about one thing is better than having to then also translate that to a different condition.
When I create a new test class, I tend to put a couple of sanity-checks in, to make sure the test itself is being run, something as simple and obviously failing as 'assertTrue(false)'. If that doesn't fail - then there is something very wrong going on. I've often found it to be name (even upper/lower-case) related.
To debug what is going on, I'd try to get down to the simplest, smallest possible that that does not do what you expect. Debug it from there, or have someone else take a look. The "other person" could equally be a Rubber Duck that you talk it through to, step, by step.

I figured this out. It had nothing to do with PHPUnit as I began to suspect. There's just no way this is only happening to me and it be PHPUnit's fault. I'm doing anything remarkable with PHPUnit.
The problem was that I am making curl calls that had too short of a timeout set. The timeout was set to 10 seconds, but the service I was hitting needed like 2 minute wait times from time-to-time (it's a machine-to-machine sort of thing, so not a huge deal). The short timeout was being hit and PHPUnit would report No Tests Executed!

Related

Get trace call list of PHP eval or override it manually

I am investigating a still undiscovered zero day exploit in Revive Adserver. An attack happen on one location and the attacker was able to invoke an eval which was already in the development and production version of Revive Adserver code base.
I have investigated the access_logs and they indicate the user was doing a POST attack on delivery script fc.php but the payload of POST still remains unclear.
The code base of Revive Adserver is very mixed, old and weird at times. There are lots of points where an eval is called in the code, and one might find something like:
$values = eval(substr(file_get_contents(self::$file), 6));
Which is actually a Smarty template thing, but it looks really scary.
As mentioned, lots and lots of eval appearances are throughout the code and it would take a whole lot time to go through each one at this time.
Is there a possibility to override eval function in PHP to display some trace information, i.e. from which file it was called, on which line did it occur?
If not, is it possible to do this by modifying PHP's C/C++ source code and recompiling it altogether?
Or is there a PHP extension or some tool which can trace all eval callbacks throughout a script?
And if there's no such thing, it would be great if someone would develop it since it would speed up investigating malicious code containing eval's.
is there a possibility to override eval function in PHP to display some trace information, i.e. from which file it was called, on which line did it occur?
Sort of.
You can add eval to disable_functions in php.ini. Then when you call eval you'll get the fatal error function eval not found or such.
Then with a custom error handler.
set_error_handler(function($errno, $errstr, $errfile, $errline){
if(false !== strpos($errstr,'eval')){
throw new Exception();
}else{
return false; //see below
}
//debug_print_backtrace() - I prefer exceptions as they are easier to work with, but you can use this arcane thing too.
});
Or something like that (untested).
Unfortunately you cannot redefine eval as your own function. Eval is not really a function, its a language construct like isset, empty, include etc... For example function_exists('empty') is always false. Some are just more "function" like then others.
In any case you'll probably have to disable eval, I cant really think of a way around that.
Tip
Don't forget you can do this:
try{
throw new \Exception;
}catch(\Exception $e){
echo $e->getTraceAsString();
}
Which both suppresses the exception (so execution continues), and gives you a nice stacktrace.
Tip
http://php.net/manual/en/function.set-error-handler.php
It is important to remember that the standard PHP error handler is completely bypassed for the error types specified by error_types unless the callback function returns FALSE
So given the above, you can/should return false for all other errors. Then PHP will report them. I am not sure it really matters much in this case, as this isn't really meant to be in production code, but I felt it worth mentioning.
Hope it helps.

PHPUnit test always succeeds, even when I'm calling fail()

I'm currently trying to write some basic unit tests for a php application, unfortunately the test always succeed, even if i want them to fail. I googled for many hours, but without success. Below you can find the code which succeeds on every call:
public function testCreateArticle()
{
$articleRepository = RepositoryFactory::getArticleRepository();
$this->fail();
}
Test succeeds.
If I switch the statements (fail() first) the test fails, but since I need the articleRepository, I can't do any asserts at all. It just seems to return a success after the first line.
Does anyone have a clue what could be wrong?

PHPUnit test passes when it should fail

I am writing a PHPUnit test suite and have run into a bit of a problem.
Here is the test:
public function testSomething(){
$stub = $this->getMockForAbstractClass('\core\classes\ImportedFile');
$stub->expects($this->exactly(4))
->method('thismethoddoesntexist');
$this->markTestIncomplete('not finished implementing');
}
For some reason this test is not failing. It should because the method does not exist and is therefore not called even once, let alone 4 times. It doesn't matter what I put in there, even if I put in a method name that does exist and say that I'm expecting it to run 100,000 times it still passes when this is obviously wrong.
I find this very strange since I have similar checks in previous tests which work properly.
Has anyone else experienced problems like this?
markTestIncomplete throw special exception, witch end the test. Checks for 'expects' in mocks are skipped.
public static function markTestIncomplete($message = '')
{
throw new PHPUnit_Framework_IncompleteTestError($message);
}
Found the cause of the problem. It seems to be caused by the call to $this->markTestIncomplete(). For some reason having this in the test causes it not to fail, at least in this case, even when it should.
Removing the call to markTestIncomplete makes it behave normally and fail when it should. I tend to leave the markTestIncomplete method in a test until it is 100% complete, and assume that if I run the test, even in its incomplete state, it should fail if an expectation is not met. Is this not a fair assumption to make? Is this a bug in PHPUnit?

Cannot call a command with multiple method arguments

Every time I attempt to use one of the basic PHPUnit Selenium assertions, the tests errors out and displays this message:
Exception: You cannot call a command with multiple method arguments.
On http://phpunit.de/manual/3.7/en/selenium.html, it shows the usage to be:
void assertElementValueEquals(string $locator, string $text)
Be when I call it with
$this->assertElementValueEquals( 'id=date_1_formatted', '2013-01-01' );
the test produces the above error every time even though this same format seems to be working for others such as in the question Using PHPUnit with Selenium, how can I test that an element contains exactly something?
assertElementValueEquals is not implemented in Selenium2TestCase. On your link it mentioned for SeleniumTestCase (Selenium RC version).
Moreover, you used correct structure with $this->byXPath like here https://github.com/sebastianbergmann/phpunit-selenium/blob/master/Tests/Selenium2TestCaseTest.php
Also you can use $this->byId():
$element = $this->byId('date_1_formatted');
$this->assertEquals('2013-01-01', $element->value());
P. S.: If you are familiar with Selenium IDE, you can try this command line tool.
Walked into this one too, in my case it was my own custom method, so I thought it was a line off.
Turns out I was using a different "buffer" class between the test class and the phpunit than I thought. But because it uses __call() a Lot, it gave ↑ that error instead of "undefined method".

UnitTests fail, manual test passes

There is something weird going on in my code so i have to ask.
I have a part of a test:
public function testGetAddresses()
{
//$this->markTestIncomplete('Not implemented yet');
$this->assertTrue($this->_prs->getAddresses() instanceof Crm_Collection);
}
This test fails.
But when I do this:
if ($entity->getAddresses() instanceof Crm_Collection) {
echo "TRUE!";
} else {
echo "FALSE!";
}
It outputs TRUE!
Anybody knows what is going on or might this be a bug in phpunit?
Thanks!
I doubt this is a PHPUnit's bug.
Since you call getAddresses() method on two different objects I guess that in test that fails this method really returns something which is not Crm_Collection.
Is there a chance that getAddresses() method could return null or throw an exception?
Why vadimbelyaev said:
I don't think it's an issue with phpunit, doublecheck your code.
Additionally you can use:
$this->assertType("Classname", $object)
so you get a nice error in case it fails.
(Phpunit will tell you "expected class, got null" instead of "expected true, got false" with helps a lot while debugging :) )
Are other tests OK? Do you run the tests from a browser?
When you run PHP code from commandline I strongly recommend to set a correct path to php.ini. Otherwise PHP will use default values which might be different from your current php.ini
Not sure if this will solve your trouble but it's good to know. Once I spend couple of hours before I found this out.
php -c "c:/program files/apache software foundation/Apache2.2/" -f /path/to/your/script.php

Categories