How to make symfony display exceptions in functional testing with phpunit - symfony

When I run unit tests with PhpUnit in console all exceptions are display immediately there. However when I moved to functional testing I cannot see exceptions which occur.
First I tried symfony WebTestCase as it was said here. So I called $client with needed parameters and I have a response. But it took time to me to understand that this behaviour is just like I manually open a page I want to test. And a response from $client->request contains text (html). Yes errors are show there but there are pretty much html and it is really hard to find the exception. Yes, I can use $crawler->filter('.text-exception')->first()->text() but I want so that exception was visible like in unit test. When I tested commands exceptions are shown by PhpUnit as well as normal.
I tried to copy code from web/app_dev.php to test case. But it is the same. I have only html response.
So how can I make it so that PhpUnit display exceptions in functional testing like in unit testing?

You can use profiler to do it:
$client->enableProfiler();
$client->request('GET', '/');
$profile = $client->getProfile();
$exceptionProfile = $profile->getCollector('exception');
if ($exceptionProfile->hasException()) {
$message = sprintf(
"No exception was expected but got '%s' with message '%s'. Trace:\n%s",
get_class($exceptionProfile->getException()),
$exceptionProfile->getMessage(),
$exceptionProfile->getException()->getTraceAsString()
);
throw new AssertionFailedError($message);
}

Related

Symfony Cache TagAwareAdapter problem with saving and then getting cacheItem

Symfony's FilesystemTagAwareAdapter() lets me get, assign a value to, and save a cacheItem, and then retrieve the saved item with another get. But if I also tag the new item before saving, I cannot retrieve the saved item with another get.
when I run the following:
$this->cache = new \Symfony\Component\Cache\Adapter\FilesystemTagAwareAdapter();
$thingItem = $this->cache->getItem('thing');
$thingItem->set('thingValue');
// $thingItem->tag('msc');
$this->cache->save($thingItem);
$retrieved = $this->cache->getItem('thing')->get();
The value of $retrieved is "thingValue".
If I uncomment the "$thingItem->tag('msc');" line and run the code again, the value of $retrieved is null.
I would expect the value of "$retrieved" to be "thingValue" in both cases.
Can anyone explain the inconsistent behavior?
Edit:
This is on php 8.1 and windows 10.
The inconsistent behavior occurs in a phpunit TestCase test in a Symfony project I am working on.
I find that the inconsistent behavior does not occur in a function test using Symfony's KernetTestCase with $this->cache = static::getContainer()->get('cache.app.taggable');
Solved!
It appears that the cache.app.taggable that symfony creates in a Windows environment is not a FilesystemTagAwareAdapter. It is a TagAwareAdapter wrapped around a TraceableAdapter wrapped around a FilesystemAdapter().
So if I create my cache this way:
$this->cache = new TagAwareAdapter(new TraceableAdapter(new FilesystemAdapter());
The code works as expected in a phpunit test!

How can I use PHPUnit to make certain there are no debug print statements in the code?

In Symfony 4, I have an API function that returns a JSON response. It works, and all my tests pass. BUT, I had a print statement in the code, and so the React side of things wasn't happy with the extra print statement and blew an error.
So, I put in a test to make sure my function was returning valid json, expecting that the extra character would make that fail.
$content = $this->client->getResponse()->getContent();
$json = json_decode($content);
if (json_last_error() === JSON_ERROR_NONE) {
$content = $json;
}
Nope. Still passes. Is there any test I can do on the PHP side to make sure there are no random print statements left in the code?
You assert that your code isn't supposed to output anything:
$this->expectOutputString('');
Otherwise, a task like this might be more suited to a code sniffer that forbids debugging functions like var_dump, print_r, etc.

Wordpress plugin + phpunit testing

I am new in wordpress developement, I have my own custom wordpress plugin which allows admin to click multiple author and save all meta tag in the database on post. It works fine. But i want to generate test case for that. I installed phpunit but I don't know how to write test case.
public function testOne()
{
$this->factory->post->create();
}
I tried this but not understand how it works.
It's not difficult but it's definitely not trivial. You'll need to set up a test Wordpress database just for PHPUnit to run tests
I found these guides really useful:
https://codesymphony.co/writing-wordpress-plugin-unit-tests/
https://engineering.hmn.md/guides/writing-code/writing-tests/
In order to get the files that PHPUnit needs to set up a WordPress testing environment, I had to get a new WordPress directory:
https://core.trac.wordpress.org/browser/trunk?order=name
And I was stymied for a while by MySQLi failing as soon as my unit tests started, but fixed it with a setting change after reading this:
https://core.trac.wordpress.org/ticket/39327
And now I can actually fix the bugs that the Unit Testing found :).
First of all, you should use the WordPress modules for Codeception, which includes the PHPunit WPTestCase and many other tools.
There are two basic approaches to testing something like this in WordPress:
You can test it with a browser. This is called an acceptance test. You list all the actions that prove the concept you are testing, and you run a browser [or browser simulator] to do the task step by step. You can look into the database for the artifacts you expect to see as a result, and prove it happens correctly. In your case, you might want to setup some posts, click the multiple authors, and then check the database for the meta tags you expect. It might look something like:
$I = /*am a */ new AcceptanceTester($scenario);
$I->loginAsAdmin();
$I->amOnPage("/wp-admin/post-new.php");
$I->fillField('#content', "lorum ipsum");
$I->click('#publish');
The other approach is to encapsulate your action in an OOP class, and test it using the WPUnit test tools. Codeception uses the same PHPUnit library the WordPress core teams uses, plus a bunch of other tools. The WPUnit approach loads a database into memory, and can do things like setup dummy posts for your plugin to work on. So in your case, you might have a class:
class SystemActionSaveMetaTags{
public function doSaveMetaTags()
}
You might have a test called
itShouldSaveMetaTags(){
$id = wp_insert_post();
$SystemActionSaveMetaTags = new SystemActionSaveMetaTags;
$SystemActionSaveMetaTags->doSaveMetaTags($id);
$this->assertTrue($this->checkForCorrectMetaTags($id));
}
Here is a tutorial on the subject, as it relates to WordPress:
https://wp-bdd.com/wp-codeception-tutorial/

Console Clear - Symfony Console Component

I'm writing a console app using Symfony 2 Console Component, and I want to run a console clear command before (or as) the first line of my app.
I have done some research and am struggling to find if this is possible.
I have been looking for similar functionality. There is nothing built-in to the symfony console that can clear the screen as far as I can tell, but you can still achieve the clear behavior by using the escape code for resetting the terminal like so:
$output->write(sprintf("\033\143"));
See the post "Clear the Ubuntu bash screen for real" and "What commands can I use to reset and clear my terminal?" for a more extensive explanation of the codes, and this symfony console pull request, where I got the code from, that attempted to emulate the clear functionality.
As the doc says, you can use something like this:
$kernel = $this->getContainer()->get('kernel');
$application = new Application($kernel);
$application->setAutoExit(false);
$input = new ArrayInput(array(
'command' => 'cache:clear',
));
// You can use NullOutput() if you don't need the output
$output = new BufferedOutput();
$application->run($input, $output);
// return the output, don't use if you used NullOutput()
$content = $output->fetch();
As your are using a command, your command must extends ContainerAwareCommand so you can access the container and your services.

assertTextPresent equivalent in phpunit

I'm trying to test for the presence of a string somewhere in a long webpage. Using PHPUnit's assertRegExp if the string is not found it prints out the entire page and then finishes with matches PCRE pattern "/xxxxxx/". According to the documentation I should be able to specify a message a third that will be printed out if the test fails. That message is printed, followed by the full page source. What I'd like to do is just print the message. Using Selenium in my previous apps I used assertTextPresent and it would just print out confirmation that the text was/was not found, without filling my screen.
I have tried wrapping the assertRegExp in a try-catch but it didn't change anything.
You could try assertContains() instead of assertRegexp().
PHPUnit is responsible for printing out the failed text, and this differs from one assert method to another. It just might work.
If it does not, open an issue at PHPUnit's issue tracker about PHPUnit printing too much out.
I am using the getBodyText() method to get all page content and than I use assertTextPresent() to check the presence of pattern.
$this->assertTextPresent($this->getBodyText(), 'text to find');
The solution has been positivly tested with latest phpunit 4.7.
I use assertTrue(stripos($haystack, $needle) !== false, 'Failed assertion message');

Resources