functional tests with typo3

25
Functional tests with TYPO3 » Introduction » How to start » Running functional tests

Upload: cpsitgmbh

Post on 13-Aug-2015

368 views

Category:

Internet


0 download

TRANSCRIPT

0Nicole Cordes, T3DD15, CPS-IT Mehr Wert im Netz

Functional tests with TYPO3

» Introduction

» How to start

» Running functional tests

1Nicole Cordes, T3DD15, CPS-IT Mehr Wert im Netz

INTRODUCTION„What is (functional) testing about?“

» test a part of your software

» not about testing your functions or classes, but processes

» from a user's point of view

» for quality assurance (QA)

„Why do I need functional tests?“

» Unit Tests don't ensure a correct workflow

» manual tests take a lot of time

» encapsulated system (database) without site-effects or dependencies

2Nicole Cordes, T3DD15, CPS-IT Mehr Wert im Netz

HOW TO START„First you need a test case!“

<?php

namespace IchHabRecht\ExampleExtension\Tests\Functional;

class FirstFunctionalTest extends \TYPO3\CMS\Core\Tests\FunctionalTestCase {

}

3Nicole Cordes, T3DD15, CPS-IT Mehr Wert im Netz

HOW TO START„Ensure your extension is loaded!“

/**

* @var array

*/

protected $testExtensionsToLoad = array(

'typo3conf/ext/example_extension',

'typo3conf/ext/example_extension/Tests/Functional/Fixtures/Extensions/test_extension',

);

/**

* @var array

*/

protected $coreExtensionsToLoad = array(

'workspaces',

);

4Nicole Cordes, T3DD15, CPS-IT Mehr Wert im Netz

HOW TO START„Add additional files!“

/**

* @var array

*/

protected $pathsToLinkInTestInstance = array(

'typo3conf/ext/example_extension/Tests/Functional/Fixtures/AdditionalConfiguration.php' =>

'typo3conf/AdditionalConfiguration.php',

);

5Nicole Cordes, T3DD15, CPS-IT Mehr Wert im Netz

HOW TO START„Overwrite LocalConfiguration settings!“

/**

* @var array

*/

protected $configurationToUseInTestInstance = array(

'BE' => array(

'debug' => TRUE,

),

'FE' => array(

'debug' => TRUE,

),

);

6Nicole Cordes, T3DD15, CPS-IT Mehr Wert im Netz

HOW TO START„Initialize your infrastructure!“

protected function setUp() {

parent::setUp();

}

test folder in typo3temp is created

core is linked into test folder

test extensions are linked into typo3conf/ext

paths and files are linked

LocalConfiguration.php is written

PackageStates.php is written

bootstrap is initialized

database is created

database scheme is imported

7Nicole Cordes, T3DD15, CPS-IT Mehr Wert im Netz

HOW TO START„If you need a backend user!“

protected function setUp() {

parent::setUp();

$this->setUpBackendUserFromFixture(1); // Import and log-in a default backend user

}

8Nicole Cordes, T3DD15, CPS-IT Mehr Wert im Netz

HOW TO START„Import your data set!“

protected function setUp() {

parent::setUp();

$this->importDataSet(ORIGINAL_ROOT . 'typo3/sysext/core/Tests/Functional/Fixtures/pages.xml');

// Import own fixtures

$fixturePath = ORIGINAL_ROOT . 'typo3conf/ext/example_extension/Tests/Functional/Fixtures';

$this->importDataSet($fixturePath . 'pages.xml'); // Import database records from the xml file

}

Fixtures, shipped by the core:

be_users.xml

pages.xml

pages_language_overlay.xml

sys_file_storage.xml

sys_language.xml

tt_content.xml

9Nicole Cordes, T3DD15, CPS-IT Mehr Wert im Netz

HOW TO START„Import your data set!“

typo3/sysext/core/Tests/Functional/Fixtures/pages.xml

<?xml version="1.0" encoding="utf-8"?>

<dataset>

<pages>

<uid>1</uid>

<pid>0</pid>

<title>Root</title>

<deleted>0</deleted>

<perms_everybody>15</perms_everybody>

</pages>

<pages>

<uid>2</uid>

<pid>1</pid>

<title>Dummy 1-2</title>

<deleted>0</deleted>

<perms_everybody>15</perms_everybody>

</pages>

</dataset>

10Nicole Cordes, T3DD15, CPS-IT Mehr Wert im Netz

HOW TO START„Set up the frontend!“

protected function setUp() {

parent::setUp();

$this->setUpFrontendRootPage(

1, // page id

array( // array of TypoScript files which should be included

'typo3/sysext/core/Tests/Functional/Fixtures/Frontend/JsonRenderer.ts'

)

);

}

11Nicole Cordes, T3DD15, CPS-IT Mehr Wert im Netz

HOW TO START„Set up the frontend!“

JsonRenderer.ts

config {

}

page = PAGE

page {

}

[globalVar = GP:L = 1]

config.sys_language_uid = 1

[end]

12Nicole Cordes, T3DD15, CPS-IT Mehr Wert im Netz

HOW TO START„Set up the frontend!“

JsonRenderer.ts – config.watcher

Defines tables and fields which should be collected to be returned

config.watcher {

tableFields {

pages = uid,_ORIG_uid,pid,sorting,title

sys_category = uid,_ORIG_uid,_LOCALIZED_UID,pid,sys_language_uid,title,parent,items,sys_language_uid

sys_file = uid,_ORIG_uid,_LOCALIZED_UID,pid,title,sys_language_uid

sys_file_reference = uid,_ORIG_uid,_LOCALIZED_UID,title,description,alternative,link,downloadname,

missing,identifier,file,pid,sys_language_uid,title,parent,items,sys_language_uid,uid_local,

uid_foreign,tablenames,fieldname,table_local

tt_content = uid,_ORIG_uid,_LOCALIZED_UID,pid,sorting,sys_language_uid,header,categories

}

}

13Nicole Cordes, T3DD15, CPS-IT Mehr Wert im Netz

HOW TO START„Set up the frontend!“

JsonRenderer.ts – page

page = PAGE

page {

10 = COA

10 {

Store current page in register

1 = LOAD_REGISTER

1.watcher.dataWrap = pages:{field:uid} // pages:1

Add current page data to records and structure array

2 = USER

2.userFunc = TYPO3\CMS\Core\Tests\Functional\Framework\Frontend\Collector->addRecordData

14Nicole Cordes, T3DD15, CPS-IT Mehr Wert im Netz

HOW TO START„Set up the frontend!“

JsonRenderer.ts – lib.watcherDataObject

lib.watcherDataObject = COA

lib.watcherDataObject {

1 = LOAD_REGISTER

1.watcher.dataWrap = |

2 = USER

2.userFunc = TYPO3\CMS\Core\Tests\Functional\Framework\Frontend\Collector->addRecordData

99 = RESTORE_REGISTER

}

15Nicole Cordes, T3DD15, CPS-IT Mehr Wert im Netz

HOW TO START„Set up the frontend!“

JsonRenderer.ts – page.10

Get page sub tree

10 = CONTENT

10 {

stdWrap.required = 1

table = pages

select {

orderBy = sorting

pidInList = this

# prevent sys_language_uid lookup

languageField = 0

}

renderObj < lib.watcherDataObject

renderObj.1.watcher.dataWrap = {register:watcher}|.__pages/pages:{field:uid} // pages:1.__pages/pages:2

}

16Nicole Cordes, T3DD15, CPS-IT Mehr Wert im Netz

HOW TO START„Set up the frontend!“

JsonRenderer.ts – page.10

Get content records

20 = CONTENT

20 {

table = tt_content

select {

orderBy = sorting

where = colPos=0

}

renderObj < lib.watcherDataObject

renderObj.1.watcher.dataWrap = {register:watcher}|.__contents/tt_content:{field:uid} // pages:1.__contents/tt_content:1

17Nicole Cordes, T3DD15, CPS-IT Mehr Wert im Netz

HOW TO START„Set up the frontend!“

JsonRenderer.ts – page.10.20

get additional information (sys_category, sys_file_reference)renderObj.10 = CONTENT

if.isTrue.field = categories

table = sys_category

select {

pidInList = root,-1

selectFields = sys_category.*

join = sys_category_record_mm ON sys_category_record_mm.uid_local = sys_category.uid

where.data = field:_ORIG_uid // field:uid

where.intval = 1

where.wrap = sys_category_record_mm.uid_foreign=|

orderBy = sys_category_record_mm.sorting_foreign

languageField = sys_category.sys_language_uid

}

renderObj < lib.watcherDataObject

renderObj.1.watcher.dataWrap = {register:watcher}|.categories/sys_category:{field:uid}

// pages:1.__contents/tt_content:1.categories/sys_category:1

18Nicole Cordes, T3DD15, CPS-IT Mehr Wert im Netz

HOW TO START„Set up the frontend!“

JsonRenderer.ts – page.10

store collected data for output in a section “Default”

stdWrap.postUserFunc = TYPO3\CMS\Core\Tests\Functional\Framework\Frontend\Collector->attachSection

stdWrap.postUserFunc.as = Default

19Nicole Cordes, T3DD15, CPS-IT Mehr Wert im Netz

HOW TO START„Set up the frontend!“

JsonRenderer.ts – page

return collected sections as json

stdWrap.postUserFunc = TYPO3\CMS\Core\Tests\Functional\Framework\Frontend\Renderer->renderSections

20Nicole Cordes, T3DD15, CPS-IT Mehr Wert im Netz

HOW TO START„Write your test!“

/**

* @test

*/

public function contentIsShown() {

$expectedRecords = array(

…,

);

$response = $this->getFrontendResponse(

1, // page id

0, // language id

0, // backend user id

0, // workspace id

TRUE, // fail on failure

0 // frontend user id

);

$responseContent = json_decode($response->getContent() , TRUE);

$this->assertEquals($expectedRecords, $responseContent['Default']['records']);

$this->assertInRecords($expectedRecords[0], $responseContent['Default']['records']);

}

21Nicole Cordes, T3DD15, CPS-IT Mehr Wert im Netz

RUNNING FUNCTIONAL TESTS„What you need!“

global PHP >= 5.5.0

composer installation of PHPUnit

{

"require-dev": {

"phpunit/phpunit": “~4.7.0",

"mikey179/vfsStream": “1.4.*@dev“

}

}

TYPO3 core source

22Nicole Cordes, T3DD15, CPS-IT Mehr Wert im Netz

RUNNING FUNCTIONAL TESTS„FINALLY RUN!“

go to your TYPO3 root directory

bin/phpunit -c typo3/sysext/core/Build/FunctionalTests.xml typo3conf/ext/example_extension/Tests/Functional

use TYPO3 source (or change the used database)

typo3DatabaseName="yourDatabase" typo3DatabaseUsername="yourUser" \

typo3DatabasePassword="yourPassword" typo3DatabaseHost="localhost" \

TYPO3_PATH_WEB=“/path/to/typo3_root” \

bin/phpunit -c /path/to/typo3_root/typo3/sysext/core/Build/FunctionalTests.xml \

/path/to/typo3_root/typo3conf/ext/example_extension/Tests/Functional

23Nicole Cordes, T3DD15, CPS-IT Mehr Wert im Netz

RUNNING FUNCTIONAL TESTS„PARTY!“

24Nicole Cordes, T3DD15, CPS-IT Mehr Wert im Netz

Thank youfor your attention!