List Example of Functional Testing¶
The is a real world example of a funtional test. It tests the expected output of a list of FAQ. It shows, that sorting works as expected.
For reasons of simplicity everthing is set up on a single page, the TS root template, the datasets, the HTML output.
The Test¶
<?php
namespace ElmarHinz\Ehfaq\Tests\Functional;
class ListTest extends \TYPO3\CMS\Core\Tests\FunctionalTestCase
{
protected $testExtensionsToLoad = [ 'typo3conf/ext/ehfaq' ];
public function setUp()
{
parent::setUp();
$this->importDataSet(
'typo3conf/ext/ehfaq/Tests/Functional/Fixtures/List.xml');
$this->setUpFrontendRootPage(1, [
'EXT:ehfaq/Tests/Functional/Fixtures/List.ts',
'EXT:ehfaq/Tests/Functional/Fixtures/Trim.ts',
]);
}
/**
* @test
*/
public function listOutput()
{
$expected = <<< HTML
<div class="tx-ehfaq">
<section class="tx-ehfaq-topic">
<header class="tx-ehfaq-topic-header"><h1>Question 1</h1></header>
<div class="tx-ehfaq-topic-body ce-intext"> Answer 1 </div>
</section>
<section class="tx-ehfaq-topic">
<header class="tx-ehfaq-topic-header"><h1>Question 2</h1></header>
<div class="tx-ehfaq-topic-body ce-intext"> Answer 2 </div>
</section>
<section class="tx-ehfaq-topic">
<header class="tx-ehfaq-topic-header"><h1>Question 3</h1></header>
<div class="tx-ehfaq-topic-body ce-intext"> Answer 3 </div>
</section>
</div>
HTML;
$expected = $this->tidy($expected);
$response = $this->getFrontendResponse(1);
$actual = $this->tidy($response->getContent());
$this->assertEquals($expected, $actual);
}
/**
* Tidy string
*
* Trims the string and reduces all whitespace
* to a single blank.
*
* @param string dirty
* @return string cleaned
*/
private function tidy($str)
{
return trim(preg_replace('/\s\s+/', ' ', $str));
}
}
?>
In the TypoScript template I don’t provide parser configuration
lib.parseFunc_RTE
. This causes the RTE field answer
not to be
rendered by the Fluid view helper tag <format.html>
. I get the native
output.
My Fluid templates (or is it the RTE formatter?) create a lot of whitespace, that is ugly to write as expectation. I apply a minimal tidy function before I compare the expected and the actual output string.
The whitespace is of little interest, but I check the order of the tags, the classes and the content strings.
Hint
If the tags would contain multiple attributes, that could appear in arbitrary order, other forms of testing need to be considered, that include parsing into and comparing of DOM.
The Fixtures¶
The DB Fixture¶
The order of the tx_ehfaq_domain_model_faq entries as well as it’s uid differ from the order of the field sorting. By this it can be shown, that the order of output is determined by the field sorting.
<?xml version="1.0" encoding="utf-8"?>
<dataset>
<pages>
<uid>1</uid>
<pid>0</pid>
<title>FAQ</title>
</pages>
<tx_ehfaq_domain_model_faq>
<uid>1</uid>
<pid>1</pid>
<sorting>128</sorting>
<question>Question 2</question>
<answer>Answer 2</answer>
</tx_ehfaq_domain_model_faq>
<tx_ehfaq_domain_model_faq>
<uid>2</uid>
<pid>1</pid>
<sorting>256</sorting>
<question>Question 3</question>
<answer>Answer 3</answer>
</tx_ehfaq_domain_model_faq>
<tx_ehfaq_domain_model_faq>
<uid>3</uid>
<pid>1</pid>
<sorting>64</sorting>
<question>Question 1</question>
<answer>Answer 1</answer>
</tx_ehfaq_domain_model_faq>
</dataset>
The TypoScript Fixture¶
It is quite difficult to test from the point of configuration of a plugin
into tt_content`. This would include a lot of TypooScript
templates
including constants. This would blow up the test and I don’t know a test case
base class, that would prepare this setup as a default.
However, it is easy to test from the point of the call to
TYPO3\CMS\Extbase\Core\Bootstrap->run
.
page = PAGE
page.10 = USER
page.10 {
userFunc = TYPO3\CMS\Extbase\Core\Bootstrap->run
extensionName = Ehfaq
pluginName = Faq
vendorName = ElmarHinz
persistence.storagePid = 1
}
Hint
If I like to show, the Fluid view helper tags <f:format.html>
are
actually working, I add the folling line:
lib.parseFunc_RTE.nonTypoTagStdWrap.encapsLines.nonWrappedTag = P
This will wrap empty lines of the RTE fields into p tags.