Problem/Motivation

Many developers still use the Simpletest UI and it is already possible to run PHPUnit-based browser tests there. We want to print out the list of pages a browser test visited in the result of a browser test run in the UI. We want to provide developers with a similar experience as with Simpletest where they get the verbose output of pages in a test run.

We also want to improve the output of phpunit with nl2br() so that the fail messages of PHPUnit are more readable.

Proposed resolution

Run phpunit from the UI with a proper printerClass to catch the verbose output and improve the output in the HTML table with nl2br() or similar.

Before:
UI before

After:
UI after

Remaining tasks

Patch.

User interface changes

More verbose output in the Simpletest UI when PHPUnit browser tests are run.

API changes

none.

Data model changes

none.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

klausi created an issue. See original summary.

klausi’s picture

Title: Integrate PHPUnit output in Simpletest UI » Integrate PHPUnit verbose output in Simpletest UI
Mile23’s picture

klausi’s picture

Status: Active » Needs review
FileSize
2.09 KB

That was fairly easy.

Now we have proper verbose output from phpunit browser tests in the Simpletest UI.

klausi’s picture

Issue summary: View changes
FileSize
40.31 KB
79.37 KB

Adding screenshots to issue summary.

Mile23’s picture

Status: Needs review » Needs work
Issue tags: +Needs tests

Could use a test or two... There's Drupal\simpletest\Tests\SimpleTestTest which might help with test-ception.

I was unable to repro the effect but I think it has more to do with my machine configuration than the patch.

Mile23’s picture

klausi’s picture

Status: Needs work » Needs review
FileSize
4.46 KB
3.05 KB

Now with a Simpletest that runs a browser test and then asserts the output is correct.

Mile23’s picture

Status: Needs review » Needs work

Nice. Here's a basic review.

  1. +++ b/core/modules/simpletest/src/Tests/UiPhpUnitOutputTest.php
    @@ -0,0 +1,43 @@
    +    $phpunit_junit_file = \Drupal::service('file_system')->realpath('public://phpunit_junit.xml');
    ...
    +    \Drupal::service('file_system')->mkdir('public://simpletest');
    

    Use $this->container instead of \Drupal

  2. +++ b/core/tests/Drupal/Tests/Listeners/SimpletestUiPrinter.php
    @@ -0,0 +1,26 @@
    +/**
    + * Defines a class for providing html output links in the Simpletest UI.
    + */
    +class SimpletestUiPrinter extends HtmlOutputPrinter {
    

    Add @see for UiPhpUnitOutputTest.

The last submitted patch, 8: simpletest-ui-2809117-8.patch, failed testing.

klausi’s picture

Status: Needs work » Needs review
FileSize
4.64 KB
1.67 KB

Fixed that, not sure why the testbot is failing. Trying some debugging.

@see should only be on a test, we don't refer to tests from the implementation class I think?

dawehner’s picture

I really like the idea!

+++ b/core/modules/simpletest/simpletest.module
@@ -331,6 +331,7 @@ function simpletest_phpunit_run_command(array $unescaped_test_classnames, $phpun
+    putenv('BROWSERTEST_OUTPUT_DIRECTORY=' . \Drupal::service('file_system')->realpath('public://simpletest'));

Are we sure we want to add this also for the case of running it via the command line?

Status: Needs review » Needs work

The last submitted patch, 11: simpletest-ui-2809117-11.patch, failed testing.

fgm’s picture

One other issue we found out with @klausi when trying this patch : the user-customized version of the phpunit.xml is used by default, which can make or break the UI behavior. For the UI tests, it is apparently necesssary to use phpunit -c phpunit.xml.dist to force use of the default, hopefully non-customized version of the PHUnit config file, instead of relying on the standard behavior which gives precedence to the customized version, likely not to be appropriate for the UI-run tests.

jhodgdon’s picture

@klausi asked on #2750461: Remove Simpletest UI because we don't want to maintain a graphical test runner if someone would test this patch on, for instance, a failing version of ColorSafePreviewTest and see what happens. As someone who has been affected by this bug, I was glad to oblige. :)

I tested this in 8.2.x that was updated a while back in the dev cycle, so the patch encountered some "fuzz" to apply, but I didn't have a 8.3.x environment handy, so I hope that is OK.

So, what I did was change the line in ColorSafePreviewTest::testColorPreview() that says

     $this->assertRaw('<h2>TEST COLOR PREVIEW</h2>');

to

     $this->assertRaw('<h2>TEST COLOR PREVIEW with additional text</h2>');

so that the test would fail.

The output I got was pretty much exactly like the "before" picture in the issue summary. I did not get HTML verbose output like in the "after" picture. Do I need to do something else to make that happen? I do have the verbose setting in Simpletest turned on. Or do I need to be running 8.3.x or a more updated 8.2.x?

klausi’s picture

You should use 8.3.x, which has more and better logging committed.

fgm had the same problem, do you have a custom phpunit.xml file copied already?

In the next iteration of this patch we will try to always use the shipped phpunit.xml.dist file.

jhodgdon’s picture

I did not have a custom phpunit.xml file to my knowledge. Where would that be? I mean, if some script created one when I first ran a PHP Unit test, it is possible I have an old one lying around...

fgm’s picture

Typically, you get to create one by copying core/phpunit.xml.dist to core/phpunit.xml when configuring your site to run tests on the CLI, and you then edit that file to customize the Simpletest DB URI and other things.

klausi’s picture

I tried a couple of variants with a copied phpunit.xml in place, but my patch always still worked as advertised. I also tried it in 8.2.x and it worked there as well. I would assume file permission problems at this point, do you have a public files directory the webserver can write to? But then the web tests from simpletest should also fail if the webserver cannot write ...

marcoscano’s picture

FileSize
85.92 KB

Also volunteering to test.

My environment is 8.3.x (not the latest, from some weeks ago) and a customized phpunit.xml. The patch applied cleanly and the output I have is:

Verbose errors

The links at the bottom are not shown as links, but the URLs work and show the correct snapshots of each step.

fgm’s picture

Test done with Klausi sunday:

  • I have a custom phpunit.xml
  • On 8.3.x HEAD
  • with the custom phpunit.xml, patch produces no visible result
  • when removing the phpunit.xml from core/, patch works as expected
  • when replacing the custom phpunit.xml in core/, patch again produces no visible result

The important line causing a change seems like it could be adding the custom output plugin.

klausi’s picture

Status: Needs work » Needs review
Issue tags: -Needs tests
FileSize
5.44 KB
2.17 KB

Interesting, the testbot has the same problem as @marcoscano and does not see proper link tags and br tags. Doing some more debugging on the testbot, this will still fail.

Status: Needs review » Needs work

The last submitted patch, 22: simpletest-ui-2809117-22.patch, failed testing.

Mile23’s picture

Some of the way this works might be altered by #2810083: Duplicate test results per fail/exception which helps fix a testbot issue.

klausi’s picture

Status: Needs work » Needs review
FileSize
5.5 KB
468 bytes

So it looks like my new SimpletestUiPrinter class is never used. Adding some debug statements to it.

Status: Needs review » Needs work

The last submitted patch, 25: simpletest-ui-2809117-25.patch, failed testing.

klausi’s picture

Status: Needs work » Needs review
FileSize
4.52 KB
2.56 KB

Found the problem, the URL regex did not catch "http://localhost/" on the testbot *facepalm*. Simplified it.

This should be good to go now.

dawehner’s picture

+++ b/core/tests/Drupal/Tests/Listeners/SimpletestUiPrinter.php
@@ -0,0 +1,26 @@
+  public function write($buffer) {
+    $buffer = Html::escape($buffer);
+    // Turn HTML output URLs into clickable link <a> tags.
+    $url_pattern = '@(http)(s)?(://)?([^\s]+)@';
+    $buffer = preg_replace($url_pattern, '<a href="http$2://$4" target="_blank" title="$0">$0</a>', $buffer);
+    // Make the output readable in HTML by breaking up lines properly.
+    $buffer = nl2br($buffer);
+
+    print $buffer;

Conceptually this is the same as \_filter_url isn't it? I'm wondering whether moving this int its own component would be worth doing.

klausi’s picture

Since it is only 2 lines of code I think it is not worth having in a component. _filter_url() is way more complex and does stuff we don't care about here.

dawehner’s picture

Status: Needs review » Reviewed & tested by the community

In general we could probably improve that more and more. This is a good start for now.

Since it is only 2 lines of code I think it is not worth having in a component. _filter_url() is way more complex and does stuff we don't care about here.

Fair

xjm’s picture

Sorry for the delay in reviewing this -- it looks great. About to test it manually but meanwhile I have one small nitpick:

+++ b/core/tests/Drupal/Tests/Listeners/SimpletestUiPrinter.php
@@ -0,0 +1,26 @@
+    $url_pattern = '@(http)(s)?(://)?([^\s]+)@';

Is the (://)? grouping really optional? Under what circumstance is a URL without it but starting with http going to be correct?

xjm’s picture

Status: Reviewed & tested by the community » Needs review

A followup for the filtering question might be worthwhile. I'm okay with hardcoding the parsing and filtering in this initial patch (and maybe always, but it is worth discussing later).

Also it's not clear to me if this was actually tested again with a custom phpunit.xml after @klausi's fixes. And a test-only patch for a failing browser test, separately and then rolled with this one, might be helpful to show how it's being reported on DrupalCI (or that it's not changing on DrupalCI if that's the case).

Setting NR to see if those suggestions make sense. Thanks! I'll keep an eye on this issue so it doesn't get stuck in a backlog again.

dawehner’s picture

Here is the phpunit.xml file I use:

  <php>
    <!-- Set error reporting to E_ALL. -->
    <ini name="error_reporting" value="32767"/>
    <!-- Do not limit the amount of memory tests take to run. -->
    <ini name="memory_limit" value="-1"/>
    <!-- Example SIMPLETEST_BASE_URL value: http://localhost -->
    <env name="SIMPLETEST_BASE_URL" value="http://d8.dev"/>
    <env name="SIMPLETEST_DB" value="mysql://root@localhost/loc_d8"/>
    <!-- Example BROWSERTEST_OUTPUT_DIRECTORY value: /path/to/webroot/sites/simpletest/browser_output -->
  </php>

Without patch: https://www.drupal.org/files/issues/Screen%20Shot%202016-11-14%20at%2008...

With patch (and no custom phpunit.xml): https://www.drupal.org/files/issues/Screen%20Shot%202016-11-14%20at%2009...

With patch (and custom phpunit.xml): https://www.drupal.org/files/issues/Screen%20Shot%202016-11-14%20at%2009...

dawehner’s picture

Status: Needs review » Reviewed & tested by the community

Oh I wanted to RTBC it

The last submitted patch, 33: 2809117-fail-with.patch, failed testing.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 33: 2809117-fail-without.patch, failed testing.

dawehner’s picture

Status: Needs work » Reviewed & tested by the community

So we see the verbose output:

fail: [Other] Line 0 of sites/default/files/simpletest/phpunit-940.xml:
PHPunit Test failed to complete; Error: PHPUnit 4.8.27 by Sebastian Bergmann and contributors.

F

Time: 14.76 seconds, Memory: 2.75Mb

There was 1 failure:

1) Drupal\Tests\help\Functional\ExperimentalHelpTest::testExperimentalHelp
Failed asserting that true is false.

/var/www/html/core/tests/Drupal/KernelTests/AssertLegacyTrait.php:43
/var/www/html/core/modules/help/tests/src/Functional/ExperimentalHelpTest.php:54

FAILURES!
Tests: 1, Assertions: 9, Failures: 1.

HTML output was generated
http://localhost/checkout/sites/simpletest/browser_output/Drupal_Tests_help_Functional_ExperimentalHelpTest-1-70400662.html
http://localhost/checkout/sites/simpletest/browser_output/Drupal_Tests_help_Functional_ExperimentalHelpTest-2-70400662.html
http://localhost/checkout/sites/simpletest/browser_output/Drupal_Tests_help_Functional_ExperimentalHelpTest-3-70400662.html
http://localhost/checkout/sites/simpletest/browser_output/Drupal_Tests_help_Functional_ExperimentalHelpTest-4-70400662.html
http://localhost/checkout/sites/simpletest/browser_output/Drupal_Tests_help_Functional_ExperimentalHelpTest-5-70400662.html
http://localhost/checkout/sites/simpletest/browser_output/Drupal_Tests_help_Functional_ExperimentalHelpTest-6-70400662.html

but well, that's of course not accessible to the outer world. I think the feedback of @xjm got addressed.

xjm’s picture

Status: Reviewed & tested by the community » Needs review

Thanks @dawehner, that looks great!

The point from #31 is still not addressed I think. I think this:
$url_pattern = '@(http)(s)?(://)?([^\s]+)@';
should be this:
$url_pattern = '@(http)(s)?(://)([^\s]+)@';

Otherwise it would match httpwww.example.com.

But this is a really minor thing.

xjm’s picture

Issue tags: +Needs followup

Oh also, do we need a followup?

A followup for the filtering question might be worthwhile. I'm okay with hardcoding the parsing and filtering in this initial patch (and maybe always, but it is worth discussing later).

From #32 about #28:

Conceptually this is the same as \_filter_url isn't it? I'm wondering whether moving this int its own component would be worth doing.

xjm’s picture

dawehner’s picture

Issue tags: -Needs followup

Otherwise it would match httpwww.example.com.

Good point, let's change that. Well ideally we would use a protocol relative URL and be done with it.

Well, I don't think its important to actually use _filter_url. Its a different usecase, as in full text. We have a limited subset of HTML here, to be honest. Its good here IMHO to not share code. At the end its just a random testing UI.

klausi’s picture

Simplified the URL regex as requested. _filter_url() is way more complex and does stuff we don't care about here.

dawehner’s picture

Status: Needs review » Reviewed & tested by the community

Cool, tests are still passing

  • xjm committed ac5428e on 8.3.x
    Issue #2809117 by klausi, dawehner, marcoscano, Mile23, xjm, fgm,...
xjm’s picture

Status: Reviewed & tested by the community » Fixed
Issue tags: +8.3.0 release notes

Ah yes, that's much simpler.

Committed and pushed to 8.3.x. Thanks!

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.