Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Testen mit TYPO3 für Fortgeschrittene
Search
Oliver Klee
May 30, 2018
Technology
230
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Testen mit TYPO3 für Fortgeschrittene
Oliver Klee
May 30, 2018
More Decks by Oliver Klee
See All by Oliver Klee
Generative KI, Ethik und Nachhaltigkeit
oliverklee
0
92
Gewaltfreie Kommunikation: ein Crashkurs
oliverklee
0
130
Team-Management-Plattform
oliverklee
0
94
Vertrauen in Teams & Führung
oliverklee
0
320
Software-Qualität von TYPO3-Extensions automatisieren
oliverklee
0
61
Vertrauen in Teams & Führung
oliverklee
0
180
Testing von TYPO3-Extensions
oliverklee
0
110
Software-Qualität von Extensions automatisieren
oliverklee
1
66
Content-Synchronisierung
oliverklee
0
200
Other Decks in Technology
See All in Technology
bet_ai_day_2026_session02
agenticsec
2
1.3k
Jetpack Compose で挑む新聞紙面UI ─ 複合ジェスチャー・ポリゴン記事領域・適応的ページ構成という3つの壁/droidkaigi2026
nikkei_engineer_recruiting
0
240
多層防御と最⼩権限で実現する、安全なAIエージェント設計パターン
lycorptech_jp
PRO
0
210
AI 駆動 Terraform 開発/SRE_BizReach_MIXI_2
visional_engineering_and_design
2
1.9k
Redmine 7.0で私が開発した新機能の狙いと背景
vividtone
1
110
AIで仕事のやり方を変える
matsu7874
1
960
PM領域でのAI Agentの活用
lycorptech_jp
PRO
0
280
Bet AI Day 2026丨Production-Ready AI Agents — エンタープライズの実務を任せるための設計と運用
layerx
PRO
4
2.6k
『止めない』を設計する — 制約の中で、事業の根幹を支える判断
hiroyaterui
0
220
Nav2、Nav3 ... はたまた自作?〜 作って理解する Nav3 の設計意図 〜 / Nav2, Nav3 ... or Build Your Own? — Understanding Nav3's design intent by building it from scratch
yanzm
0
260
推論の観測、できていますか? 〜 Google Cloud Gemini Enterprise Agent Platformで 3つの Gemini モデルを実測して踏んだ、評価の罠 〜
shukob
PRO
0
160
2026-09-10 【Snowflake World Tour Tokyo 2026】dbt Core と Snowflake で実現する多層的なデータガバナンス / Multi-Layered Data Governance Powered by dbt Core and Snowflake
civitaspo
0
140
Featured
See All Featured
技術選定の審美眼(2025年版) / Understanding the Spiral of Technologies 2025 edition
twada
PRO
120
120k
How to build an LLM SEO readiness audit: a practical framework
nmsamuel
1
890
Digital Ethics as a Driver of Design Innovation
axbom
PRO
1
410
A designer walks into a library…
pauljervisheath
211
25k
Building Flexible Design Systems
yeseniaperezcruz
330
41k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
10
1.3k
Become a Pro
speakerdeck
PRO
31
6.2k
Marketing Yourself as an Engineer | Alaka | Gurzu
gurzu
0
290
How People are Using Generative and Agentic AI to Supercharge Their Products, Projects, Services and Value Streams Today
helenjbeal
1
310
How to build a perfect <img>
jonoalderson
1
6k
Effective software design: The role of men in debugging patriarchy in IT @ Voxxed Days AMS
baasie
0
510
Stop Working from a Prison Cell
hatefulcrawdad
274
21k
Transcript
Testen mit TYPO3 (advanced) Oliver Klee, 2018-05 @oliklee |
[email protected]
Cartoon: www.fuchskind.de
Test-Level http://filipdefar.com/2015/06/tested-be-thy-name.html
Unit-Tests sind klein und schnell
Integrationstests testen das Zusammenspiel von Komponenten in TYPO3: „Functional Tests“
Systemtests testen das große Ganze
Test-Typen
Blackbox-Tests testen das nach außen Sichtbare
Whitebox-Tests wie genau es innen funktioniert testen,
Functional Tests
Akzeptanztests
Anti- Zombie- Tests-
Regressionstests
Smoketests
Smoketests
Story-Tests für Behavior-Driven Development (BDD)
None
Was bisher geschah
None
Deprecated seit PHPUnit 5.4.0 $this->backEndUser = $this->getMock( BackendUserAuthentication::class ); Empfohlen
seit PHPUnit 5.4.0 $this->backEndUser = $this->createMock( BackendUserAuthentication::class ); Änderungen bei Mocks $this->backEndUser = $this->getMockBuilder( BackendUserAuthentication::class )->disableOriginalConstructor() ->disableOriginalClone();
Prophecy: Empfohlen für Stubs (vollständige Mocks) Änderungen bei Mocks $this->viewProphecy
= $this->prophesize(TemplateView::class); $this->view = $this->viewProphecy->reveal(); … $this->viewProphecy->assign('tea', $tea)->shouldBeCalled(); PHPUnit-Mocks: Weiterhin empfohlen für partielle Mocks $this->controller = $this->getMockBuilder(TeaController::class) ->setMethods(['forward', 'redirect']);
Testing-Frameworks Testing-Framework der PHPUnit-Extension typo3/testing-framework nimut/testing-framework
Testing-Frameworks Testing-Framework der PHPUnit-Extension typo3/testing-framework nimut/testing-framework erhält keine neuen Features
mehr kompatibel bis TYPO3 CMS 8.7 benutzt eine echte TYPO3-Instanz
Testing-Frameworks Testing-Framework der PHPUnit-Extension typo3/testing-framework nimut/testing-framework läuft auf Linux und
Mac, nicht unter Windows API variiert zwischen TYPO3-Versionen wird vom Core-Team gepflegt
Testing-Frameworks Testing-Framework der PHPUnit-Extension typo3/testing-framework nimut/testing-framework läuft auf Linux, Mac
und Windows API ist identisch zwischen TYPO3-Versionen wird von Nicole und Helmut gepflegt
Testing-Frameworks Testing-Framework der PHPUnit-Extension typo3/testing-framework nimut/testing-framework nicht für neue Projekte
benutzen für Projekte unter genau einer TYPO3-Version für Extensions über mehrere TYPO3-Versionen
PhantomJS ist tot stattdessen empfohlen: Chromedriver Änderungen bei Akzeptanztests PHPUnit-Selenium
wird nicht mehr brauchbar gewartet hat keine aktuelle Dokumentation Benutzung ist weiterhin umständlich Codeception bietet High-Level-Browser-Tests mit und ohne Selenium unterstützt u.a. Chromedriver und PhpBrowser
None
Infrastruktur
https://github.com/oliverklee/tea
composer.json "require-dev": { "typo3/cms-fluid-styled-content": "^7.6.23 || ^8.7.10", "helhum/typo3-composer-setup": "^0.5.1", "helmich/typo3-typoscript-lint":
"^1.4.4", "nimut/testing-framework": "^3.0", "roave/security-advisories": "dev-master" },
Konfiguration in PhpStorm
Konfiguration in PhpStorm Unit-Tests Funktionale Tests
None
Funktionale Repository- Tests
TeaRepositoryTest.php class TeaRepositoryTest extends FunctionalTestCase { /** * @var string[]
*/ protected $testExtensionsToLoad = ['typo3conf/ext/tea'];
TeaRepositoryTest.php protected function setUp() { parent::setUp(); $this->persistenceManager = GeneralUtility::makeInstance(PersistenceManager::class); /**
@var ObjectManager $objectManager */ $objectManager = GeneralUtility::makeInstance(ObjectManager::class); $this->subject = $objectManager->get(TeaRepository::class); } /** * @test */ public function findAllForNoRecordsReturnsEmptyContainer() { $container = $this->subject->findAll(); static::assertCount(0, $container); }
TeaRepositoryTest.php /** * @test */ public function findAllWithRecordsFindsRecordsFromAllPages() { $this->importDataSet(
__DIR__ . '/../Fixtures/Product/Tea.xml' ); $container = $this->subject->findAll(); static::assertGreaterThanOrEqual(1, \count($container)); }
Fixtures/Product/Tea.xml <?xml version="1.0" encoding="utf-8"?> <dataset> <tx_tea_domain_model_product_tea> <uid>1</uid> <pid>1</pid> <title>Earl Grey</title>
<description>Fresh and hot.</description> </tx_tea_domain_model_product_tea> … <sys_file_reference> <uid>1</uid> <pid>1</pid> <uid_foreign>3</uid_foreign> <tablenames>tx_tea_domain_model_product_tea</tablenames> <fieldname>image</fieldname> <l10n_diffsource></l10n_diffsource> </sys_file_reference> </dataset>
TeaRepositoryTest.php /** * @test */ public function findByUidForExistingRecordReturnsModelWithData() { $this->importDataSet(
__DIR__ . '/../Fixtures/Product/Tea.xml' ); $uid = 1; /** @var Tea $model */ $model = $this->subject->findByUid($uid); static::assertNotNull($model); static::assertSame('Earl Grey', $model->getTitle()); static::assertSame( 'Fresh and hot.’, $model->getDescription() ); }
TeaRepositoryTest.php /** * @test */ public function fillsImageRelation() { $this->importDataSet(
__DIR__ . '/../Fixtures/Product/Tea.xml' ); $uid = 3; /** @var Tea $model */ $model = $this->subject->findByUid($uid); $image = $model->getImage(); static::assertInstanceOf(FileReference::class, $image); static::assertSame(1, $image->getUid()); }
TeaRepositoryTest.php /** * @test */ public function addAndPersistAllCreatesNewRecord() { $title
= 'Godesberger Burgtee'; $model = new Tea(); $model->setTitle($title); $this->subject->add($model); $this->persistenceManager->persistAll(); $databaseRow = $this->getDatabaseConnection() ->selectSingleRow( '*', 'tx_tea_domain_model_product_tea', 'uid = ' . $model->getUid() ); static::assertSame($title, $databaseRow['title']); }
Legacy- Projekte
Wo anfangen?
Ein Test-Grundgerüst schaffen Testing- Framework einbinden Starter-Test assertSame(1,1); Unit-Tests Model-Tests
auf AbstractEntity Functional Tests Repository-Tests für das Laden von Models
„Low-hanging fruit“ pflücken Model-Tests für Getter/Setter (Live-Templates) Utility-Klassen Unit-Tests oder
funktionale Tests Controller-Tests Forwards und Redirects mit partiellen Mocks Repositories funktionale Tests fürs das Mappen von Feldern Controller-Tests Datenfluss: Views <=> Repositories
Wichtige Tests schreiben Hohes Risiko Was darf auf gar keinen
Fall kaputtgehen? Fragilität Was geht öfter mal kaputt? Beweglichkeit Welchen Code verändern wir oft?
Wenn man ohnehin schraubt … Bugfixes neue Features Refactoring Zuerst
Tests schreiben!
None