Webtechnologien
Wintersemester 2024
React Testing & Qualitätssicherung
♯
♫
React Testing & Qualitätssicherung
<section id="react-testing--qualitätssicherung" class="slide cover"><div><h2>React Testing & Qualitätssicherung</h2> </div></section> <section class="slide" id="methoden-zur-qualitätssicherung"><div><h2>Methoden zur Qualitätssicherung</h2> <ul> <li>In diesem Teil geht es allgemein darum, die Qualität der Software hoch zu halten und unsere Konfidenz, Änderungen daran vorzunehmen</li> <li>dabei stehen uns verschiedene Instrumente zur Verfügung, z.B.: <ul> <li>isolierte UI-Entwicklung und niedrigschwellige Inspektion</li> <li>festes Fundament statischer Code-Analyse</li> <li>automatische Tests in verschiedenen Ausprägungen</li> </ul> </li> </ul> <footer> <p>In diesem Teil geht es mir allgemein um Qualität, also die Güte dessen, was wir bauen, nicht strikt um Tests. Das heißt, wir schauen uns neben automatisierten Code-Tests auch Qualitätssicherungstools an, und Möglichkeiten der visuellen QS.</p> </footer> </div></section> <section class="slide" id="ui-entwicklung-mit-storybook"><div><h2>UI-Entwicklung mit Storybook</h2> <ul> <li>Erlaubt es, React-Komponenten isoliert zu entwickeln und in allen möglichen Zuständen zu inspizieren</li> </ul> <pre class="highlight language-sh" data-lang="sh"><code>npx sb init <span class="c"># installs storybook</span> npm run storybook <span class="c"># opens on http://localhost:6006</span> </code></pre> </div></section> <section class="slide" id="statische-code-analyse-und--optimierung"><div><h2>statische Code-Analyse und -Optimierung</h2> <ul> <li>Typisierung: <a href="https://reactjs.org/docs/typechecking-with-proptypes.html">Prop Types</a></li> <li>Formattierung: <a href="https://prettier.io">Prettier</a></li> <li>Linting: <a href="https://eslint.org">ESLint</a>, <a href="https://stylelint.io">stylelint</a></li> </ul> </div></section> <section class="slide" id="entwicklungsabläufe"><div><h2>Entwicklungsabläufe</h2> <ul> <li>Git Hooks mit <a href="https://github.com/typicode/husky">husky</a> (z.B. pre-commit) <ul> <li>Linting (<code class="language-plaintext highlighter-rouge">eslint --fix</code> + prettier rules plugin)</li> <li>Formatting (<code class="language-plaintext highlighter-rouge">prettier --write</code>) (<code class="language-plaintext highlighter-rouge">.prettierrc</code>)</li> <li>Testing (<code class="language-plaintext highlighter-rouge">jest --findRelatedTests</code> – kann produktivitätshemmend wirken, wenn langsam)</li> </ul> </li> <li>Deploy Previews für einfache manuelle Inspekion von PRs</li> </ul> </div></section> <section class="slide" id="test-arten"><div><h2>Test-Arten</h2> <ul> <li><strong>Unit Tests</strong>: testen einzelner Komponenten → meist eher happy paths (Test auf mögliche Korrektheit statt mögliche Fehler, teilweise sinnfreie Tests, um code coverage limit zu treffen)</li> <li><strong>Integration Tests</strong>: Zusammenspiel verschiedener Komponenten zu einem aus Nutzerperspektive mehr oder weniger abgeschlossenen Feature (rendern von Komponenten-Bäumen in vereinfachter Test-Umgebung, um gegen erwartete Ausgabe zu prüfen)</li> <li><strong>End-to-end-tests</strong>: Emulation echter BenutzerInnen und möglichst realer Umgebung. Also Ausführen einer kompletten App in einer realistischen Browser-Umgebung</li> </ul> </div></section> <section class="slide" id="test-verteilung"><div><h2>Test-Verteilung</h2> <ul> <li>Empfehlung <ul> <li>festes Fundament an statischer Testinfrastruktur (Nutzung von Lintern, IDE- und CI-Integration)</li> <li>wenig Unit Tests</li> <li>hauptsächlich Integration Tests: sweet spot / goldilocks zone zwischen Aufwand und Test-Abdeckung / Risikominimierung</li> <li>(wenige) End-to-end-Tests (für kritischen Pfade)</li> </ul> </li> </ul> </div></section> <section class="slide" id="unit-tests-mit-jest"><div><h2>Unit Tests mit <a href="https://jestjs.io">Jest</a></h2> <ul> <li>Tests immer co-locaten (<code class="language-plaintext highlighter-rouge">Foo.js</code>, <code class="language-plaintext highlighter-rouge">Foo.test.js</code>) und nicht in eigenem Verzeichniss (<code class="language-plaintext highlighter-rouge">__tests__</code>)</li> <li>Jest: Test-Runner in Node der Browser emuliert (JSDOM) <ul> <li>watcher</li> <li>spies</li> <li>coverage reports</li> <li>snapshot testing (eher vermeiden)</li> </ul> </li> </ul> </div></section> <section class="slide" id="react-testing-library"><div><h2><a href="https://testing-library.com/docs/react-testing-library/intro/">React Testing Library</a></h2> <ul> <li>Menge von Helpern, mit denen React-Komponenten getestet werden können, ohne deren Implementierungsdetails zu kennen</li> </ul> <pre class="highlight language-sh" data-lang="sh"><code>npm <span class="nb">install</span> @testing-library/react @testing-library/jest-dom </code></pre> </div></section> <section class="slide" id="mocking"><div><h2>Mocking</h2> <ul> <li>Browser APIs: Werden teilweise in JSDOM nicht unterstützt, z.B. <code class="language-plaintext highlighter-rouge">LocalStorage</code></li> <li>Data Fetching: <code class="language-plaintext highlighter-rouge">mws</code> / <a href="https://github.com/mswjs/msw">Mock Service Worker</a> um APIs Express-ähnlich nachzubauen</li> </ul> </div></section> <section class="slide" id="end-to-end-tests"><div><h2>End-to-end-Tests</h2> <ul> <li><a href="https://playwright.dev/">Playwright</a></li> <li><a href="https://www.cypress.io">Cypress</a></li> <li><a href="https://github.com/puppeteer/puppeteer">Puppeteer</a></li> </ul> </div></section>