{"id":837,"date":"2026-07-30T12:22:28","date_gmt":"2026-07-30T12:22:28","guid":{"rendered":"https:\/\/matforge.org\/?p=837","raw":"https:\/\/matforge.org\/?p=837"},"modified":"2026-07-30T12:22:28","modified_gmt":"2026-07-30T12:22:28","slug":"continuous-integration-research-software-automated-testing-validation","status":"publish","type":"post","link":"https:\/\/matforge.org\/de\/continuous-integration-research-software-automated-testing-validation\/","title":{"rendered":"Kontinuierliche Integration f\u00fcr Forschungssoftware: Automatisiertes Testen und Validieren","raw":"Kontinuierliche Integration f\u00fcr Forschungssoftware: Automatisiertes Testen und Validieren"},"content":{"rendered":"<span class=\"span-reading-time rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">Reading Time: <\/span> <span class=\"rt-time\"> 11<\/span> <span class=\"rt-label rt-postfix\">minutes<\/span><\/span><p>Continuous Integration (CI) erstellt, testet und validiert den Forschungscode automatisch bei jedem Commit. F\u00fcr wissenschaftliche Software ist CI f\u00fcr die Reproduzierbarkeit, die fr\u00fchzeitige Fehlererkennung und die Aufrechterhaltung der Qualit\u00e4t im Laufe der Zeit unerl\u00e4sslich. Implementieren Sie CI durch: (1) Schreiben automatisierter Tests mit PyTest, (2) Einrichten einer CI-Pipeline mit GitHub-Aktionen oder GitLab CI, (3) Verwenden von Docker \/ Conda f\u00fcr die Umgebungskonsistenz, (4) Hinzuf\u00fcgen von Berichterstellungsberichterstattung und (5) Integration von Leistungs-Benchmarks. Behandeln Sie numerische Tests mit <code>pytest.approx<\/code>, verwenden Sie Matrixstrategien, um Python-Versionen zu testen, und Cache-Abh\u00e4ngigkeiten, um die Laufzeit zu reduzieren. CI wandelt Forschungscode von fragilen Skripten in vertrauensw\u00fcrdige, wartbare Software um.<\/p>\n<h2>Einleitung: Warum Continuous Integration f\u00fcr die Forschung wichtig ist<\/h2>\n<p>Forschungssoftware ist daf\u00fcr ber\u00fcchtigt, lautlos zu brechen. Eine kleine \u00c4nderung in einem Teil des Codes kann subtil unterschiedliche Ergebnisse im Folgenden erzeugen, was ver\u00f6ffentlichte Ergebnisse ung\u00fcltig macht oder monatelange Rechenzeit verschwendet. Herk\u00f6mmliche manuelle Tests &#8211; von Hand einige Beispiele ausf\u00fchren &#8211; skalieren nicht auf komplexe Simulationscodes mit Dutzenden von voneinander abh\u00e4ngigen Modulen.<\/p>\n<p>Continuous Integration (CI) behebt dies, indem es automatisch eine umfassende Testsuite ausf\u00fchrt, wenn Code festgeschrieben wird. Aber CI ist mehr als nur Automatisierung; Es ist eine Qualit\u00e4tsdisziplin, die die Reproduzierbarkeit durchsetzt und die Korrektheit kontinuierlich best\u00e4tigt. Als <a href=\"https:\/\/www.ee.columbia.edu\/~dpwe\/e6891\/resources\/1210.0530v3.pdf\"> Best Practices for Scientific Computing <\/a> Papiernotizen: &#8222;Automatisiertes Testen ist Nicht verhandelbar f\u00fcr vertrauensw\u00fcrdige wissenschaftliche Software &#8222;(Wilson et al., 2012).<\/p>\n<p>F\u00fcr Forschungsteams bietet CI konkrete Vorteile:<\/p>\n<ul>\n<li><strong>Reproduzierbarkeit<\/strong>: CI \u00fcberpr\u00fcft, ob der Code konsistente Ergebnisse in Umgebungen und im Laufe der Zeit liefert.<\/li>\n<li><strong>Early Defekterkennung<\/strong>: Fehler werden Minuten nach ihrer Einf\u00fchrung abgefangen, nicht Wochen sp\u00e4ter w\u00e4hrend der Erstellung der Manuskripte.<\/li>\n<li><strong>Zuversicht in Refactor<\/strong>: Mit einem Sicherheitsnetz von Tests k\u00f6nnen Sie die Codestruktur verbessern, ohne Angst zu haben, etwas zu brechen.<\/li>\n<li><strong>Collaboration Enablement<\/strong>: Mehrere Mitwirkende k\u00f6nnen auf derselben Codebasis arbeiten, indem sie automatische \u00dcberpr\u00fcfungen verhindern.<\/li>\n<li><strong>Erwartungsdokumentation<\/strong>: Tests dienen als ausf\u00fchrbare Spezifikationen, die dokumentieren, wie sich der Code verhalten soll.<\/li>\n<\/ul>\n<p>Trotz dieser Vorteile fehlt vielen Forschungsprojekten CI immer noch. H\u00e4ufige Ausreden sind &#8222;Unser Code ist zu komplex, um zu testen&#8220;, &#8222;Tests dauern zu lange&#8220; oder &#8222;Wir haben keine Zeit, CI einzurichten.&#8220; Dieser Leitfaden l\u00f6st diese Einw\u00e4nde und bietet einen praktischen, schrittweisen Ansatz f\u00fcr CI, der auf wissenschaftliche Software zugeschnitten ist.<\/p>\n<h2>Was ist wirklich kontinuierliche Integration?<\/h2>\n<p>Kontinuierliche Integration ist das Zusammenf\u00fchren von Code\u00e4nderungen in einem gemeinsamen Repository h\u00e4ufig &#8211; idealerweise mehrmals pro Tag &#8211; und die automatische \u00dcberpr\u00fcfung jeder Zusammenf\u00fchrung mit einer automatisierten Build- und Test-Pipeline. Der &#8222;kontinuierliche&#8220; Teil bedeutet, dass das Feedback schnell ist; Entwickler wissen innerhalb weniger Minuten, ob ihre \u00c4nderung etwas kaputt gemacht hat.<\/p>\n<p>Eine CI-Pipeline enth\u00e4lt typischerweise:<\/p>\n<ol>\n<li><strong>Checkout<\/strong>: Das CI-System ruft den neuesten Code ab.<\/li>\n<li><strong>Umgebungs-Setup<\/strong>: Abh\u00e4ngigkeiten werden installiert (h\u00e4ufig innerhalb eines Containers).<\/li>\n<li><strong>Statische Analyse<\/strong>: Der Code ist f\u00fcr Stilprobleme und potenzielle Fehler furchtbar.<\/li>\n<li><strong>Einheitstests<\/strong>: Einzelne Funktionen und Module werden isoliert getestet.<\/li>\n<li><strong>Integrationstests<\/strong>: Mehrere Komponenten werden zusammen getestet.<\/li>\n<li><strong>Coverage-Reporting<\/strong>: Der Anteil des Codes, der durch Tests ausge\u00fcbt wird, wird gemessen.<\/li>\n<li><strong>Artefact Building<\/strong>: Dokumentation, Pakete oder Bin\u00e4rdateien werden generiert.<\/li>\n<li><strong>Performance-Benchmarks<\/strong> (optional): Ausf\u00fchrungsgeschwindigkeit und Speichernutzung werden verfolgt.<\/li>\n<\/ol>\n<p>F\u00fcr Forschungssoftware f\u00fcgen wir hinzu:<\/p>\n<ul>\n<li><strong>Numerische Validierung<\/strong>: Tests, die Gleitkommatoleranzen und stochastische Variationen ber\u00fccksichtigen.<\/li>\n<li><strong>\u00dcberpr\u00fcfungen der Reproduzierbarkeit<\/strong>: \u00dcberpr\u00fcfung, dass die Ergebnisse innerhalb akzeptabler Grenzen \u00fcbereinstimmen.<\/li>\n<li><strong>Datenvalidierung<\/strong>: Gew\u00e4hrleistung der Integrit\u00e4t der Eingabe- und Ausgabedaten.<\/li>\n<\/ul>\n<h2>Kernkomponenten: Aufbau einer forschungsbereiten CI-Pipeline<\/h2>\n<p>Eine robuste CI-Pipeline f\u00fcr wissenschaftliche Python-Projekte sollte diese Komponenten enthalten, die jeweils einen bestimmten Qualit\u00e4tsaspekt ansprechen.<\/p>\n<h3>Automatisiertes Testen mit PyTest<\/h3>\n<p>Die Stiftung ist eine umfassende Testsuite mit <a href=\"https:\/\/docs.pytest.org\/\">pytest<\/a>. PyTest ist der De-facto-Standard f\u00fcr Python-Tests aufgrund seiner Einfachheit, leistungsstarken Ger\u00e4te und reichhaltigen \u00d6kosystems.<\/p>\n<p>F\u00fcr den wissenschaftlichen Kodex konzentrieren Sie sich auf:<\/p>\n<ul>\n<li><strong>Einheitstests<\/strong> f\u00fcr einzelne Funktionen (z. B. berechnet ein Diffusionsl\u00f6ser korrekt auf einem einfachen Netz?).<\/li>\n<li><strong>Regressionstests<\/strong>, die die Ergebnisse mit bekannten guten Ergebnissen vergleichen (wesentlich f\u00fcr PDE-Solver).<\/li>\n<li><strong>Eigenschaftsbasierte Tests<\/strong> mit <a href=\"https:\/\/hypothesis.readthedocs.io\/\">Hypothese<\/a>, um zuf\u00e4llige Eingaben zu generieren und Invarianten zu \u00fcberpr\u00fcfen.<\/li>\n<\/ul>\n<p>Der Einheitentest f\u00fcr den wissenschaftlichen Codeentwurf (in Bearbeitung) behandelt PYTest-Strategien in der Tiefe, einschlie\u00dflich der numerischen Pr\u00e4zision.<\/p>\n<h3>Umgang mit numerischen Vergleichen<\/h3>\n<p>Der wissenschaftliche Code befasst sich mit Gleitkomma-Arithmetik, bei der eine exakte Gleichheit aufgrund von Rundungsfehlern oft nicht m\u00f6glich ist. PYTEST bietet <code>pytest.approx<\/code> f\u00fcr ungef\u00e4hre Vergleiche:<\/p>\n<pre><code class=\"language-python\">def test_diffusion_result():\n    result = run_simulation()\n    expected = 0.123456\n    assert result == pytest.approx(expected, rel=1e-6)  # 0.1% tolerance\n<\/code><\/pre>\n<p>Verwenden Sie f\u00fcr Arrays <code>numpy.testing.assert_allclose<\/code>:<\/p>\n<pre><code class=\"language-python\">import numpy.testing as npt\n\ndef test_field_solution():\n    computed = solve_pde()\n    reference = load_reference_solution()\n    npt.assert_allclose(computed, reference, rtol=1e-5, atol=1e-10)\n<\/code><\/pre>\n<p>W\u00e4hlen Sie Toleranzen basierend auf der Physik und der Diskretisierungsgenauigkeit. Dokumentieren Sie, warum bestimmte Toleranzen ausgew\u00e4hlt wurden.<\/p>\n<h3>Codeabdeckungsmessung<\/h3>\n<p>Die Codeabdeckung misst, wie viel von Ihrer Codebasis w\u00e4hrend der Tests ausgef\u00fchrt wird. W\u00e4hrend eine 100% ige Abdeckung nicht immer erforderlich (oder erreichbar) ist, hilft die Verfolgung, ungetestete Codepfade zu identifizieren.<\/p>\n<p>Verwenden Sie <a href=\"https:\/\/pytest-cov.readthedocs.io\/\">pytest-cov<\/a>, um Berichterstattungsberichte zu erstellen:<\/p>\n<pre><code class=\"language-bash\">pytest --cov=src\/ --cov-report=xml --cov-report=html\n<\/code><\/pre>\n<p>Integrieren Sie <a href=\"https:\/\/codecov.io\/\">Codecov<\/a> oder <a href=\"https:\/\/coveralls.io\/\">coveralls<\/a>, um die Abdeckung im Laufe der Zeit zu verfolgen und die Mindestgrenzwerte in CI zu erzwingen.<\/p>\n<p>Das <a href=\"https:\/\/learn.scientific-python.org\/development\/guides\/coverage\/\">Wissenschaftliches Python-Entwicklungshandbuch<\/a> enth\u00e4lt detaillierte Beispiele f\u00fcr die Konfiguration der Abdeckung.<\/p>\n<h3>Statische Analyse und Fusseln<\/h3>\n<p>Statische Analysetools fangen Fehler ab und erzwingen die Stilkonsistenz, bevor der Code zusammengef\u00fchrt wird:<\/p>\n<ul>\n<li><strong>Flake8<\/strong>: PEP 8 Style Guide Durchsetzung und grundlegende Fehlerpr\u00fcfung.<\/li>\n<li><strong>MyPy<\/strong>: statische Typpr\u00fcfung (graduelle Eingabe ist auch im Forschungscode wertvoll).<\/li>\n<li><strong>Schwarz<\/strong>: Automatische Codeformatierung (eliminiert Stildebatten).<\/li>\n<li><strong>Pylint<\/strong>: Eine tiefere Analyse der Codequalit\u00e4t (vorsichtig anwenden; einige Regeln sind m\u00f6glicherweise zu streng f\u00fcr den Forschungscode).<\/li>\n<\/ul>\n<p>F\u00fchren Sie diese als separate CI-Jobs aus, damit Fehler nicht blockieren.<\/p>\n<h3>Umgebungskonsistenz mit Docker oder Conda<\/h3>\n<p>Eine der gr\u00f6\u00dften Herausforderungen f\u00fcr die Reproduzierbarkeit ist die H\u00f6lle der Abh\u00e4ngigkeit &#8211; verschiedene Versionen von Bibliotheken f\u00fchren zu unterschiedlichen Ergebnissen. CI beseitigt dies durch die Installation von Abh\u00e4ngigkeiten in einer sauberen, kontrollierten Umgebung.<\/p>\n<p><strong>Option A: Docker<\/strong> (empfohlen f\u00fcr CI)<\/p>\n<p>Docker bietet vollst\u00e4ndige Containerisierung auf Systemebene. a <code>Dockerfile<\/code> definiert die genaue Umgebung:<\/p>\n<pre><code class=\"language-dockerfile\">FROM python:3.11-slim\n\nWORKDIR \/app\nCOPY requirements.txt .\nRUN pip install --no-cache-dir -r requirements.txt\nCOPY . .\n<\/code><\/pre>\n<p><a href=\"https:\/\/polaris.imag.fr\/arnaud.legrand\/research\/readings\/acm_sigops_si_rsea\/p71-boettiger.pdf\"> BOETTIGER. (2015) <\/a> argumentiert, dass Docker &#8222;das Beste ist, was jemals mit wissenschaftlicher Reproduzierbarkeit passiert&#8220; ist, da es den gesamten Software-Stack vom Betriebssystem zu Bibliotheken sperrt.<\/p>\n<p><strong>Option B: Conda-Umgebungen<\/strong><\/p>\n<p>Wenn Ihr Projekt auf Nicht-Python-Abh\u00e4ngigkeiten (z. B. HDF5, MPI) angewiesen ist, verwenden Sie Conda:<\/p>\n<pre><code class=\"language-yaml\"># environment.yml\nname: research-ci\ndependencies:\n  - python=3.11\n  - numpy&gt;=1.24\n  - scipy\n  - pip:\n    - pytest\n    - pytest-cov\n<\/code><\/pre>\n<p>CI-Systeme k\u00f6nnen diese Umgebung mit <code>conda env create -f environment.yml<\/code> erstellen und aktivieren.<\/p>\n<p><strong>Wichtig<\/strong>: <a href=\"https:\/\/arxiv.org\/html\/2601.12811v1\">Docker garantiert Reproduzierbarkeit nicht<\/a> warnt davor, dass selbst Container subtile Unterschiede haben k\u00f6nnen (Zeitstempel, zuf\u00e4llig Samen). Fixieren Sie f\u00fcr maximale Reproduzierbarkeit auch Bibliotheksversionen und Seeds.<\/p>\n<h3>Dokumentationsaufbau<\/h3>\n<p>F\u00fcgen Sie einen Schritt zum Erstellen von Dokumentationen (Sphinx, Mkdocs) hinzu und stellen Sie diese optional bereit. Documentation-as-Code stellt sicher, dass die Dokumente mit dem Code synchron bleiben. Der Entwurf der Dokumentation Best Practices f\u00fcr wissenschaftliche Python-Pakete erl\u00e4utert dies im Detail.<\/p>\n<h3>Leistungs-Benchmarks<\/h3>\n<p>\u00dcberwachen Sie f\u00fcr rechnerisch intensive Forschungssoftware die Leistung, um Regressionen abzufangen. Tools wie <a href=\"https:\/\/asv.readthedocs.io\/\">ASV (Airspeed Velocity)<\/a> f\u00fchren Benchmarks automatisch durch und vergleichen sie mit fr\u00fcheren L\u00e4ufen.<\/p>\n<p>Waller et al. (2015) beschreiben <a href=\"https:\/\/oceanrep.geomar.de\/28433\/1\/SEN2015.pdf\"> einschlie\u00dflich Leistungs-Benchmarks in CI <\/a>, um Leistungseinbu\u00dfen fr\u00fchzeitig zu erkennen. Dies ist besonders wichtig f\u00fcr PDE-Solver, bei denen algorithmische \u00c4nderungen die Laufzeit drastisch beeinflussen k\u00f6nnen.<\/p>\n<h2>Plattformvergleich: GitHub-Aktionen gegen GitLab CI<\/h2>\n<p>Es gibt zwei dominante CI-Plattformen: GitHub-Aktionen und GitLab CI. Beide sind ausgereift und produktionsbereit. Die Wahl h\u00e4ngt h\u00e4ufig davon ab, wo Ihr Code gehostet wird.<\/p>\n<h3>GitHub-Aktionen<\/h3>\n<p><strong>St\u00e4rken<\/strong>:<\/p>\n<ul>\n<li>Tiefe Integration mit GitHub (Pull Request Checks, Marktplatz der Aktionen).<\/li>\n<li>Einfachere Konfigurationssyntax f\u00fcr g\u00e4ngige Workflows.<\/li>\n<li>Gr\u00f6\u00dfere Community und mehr Aktionen von Drittanbietern.<\/li>\n<li>Kostenlos f\u00fcr \u00f6ffentliche Repositories; Gro\u00dfz\u00fcgige kostenlose Stufe f\u00fcr private Repos.<\/li>\n<\/ul>\n<p><strong>Schw\u00e4chen<\/strong>:<\/p>\n<ul>\n<li>Weniger leistungsf\u00e4hig f\u00fcr komplexe Workflows als GitLab.<\/li>\n<li>Eingeschr\u00e4nkte integrierte Funktionen f\u00fcr das Abh\u00e4ngigkeits-Caching in fr\u00fchen Versionen (jetzt verbessert).<\/li>\n<li>an das GitHub-\u00d6kosystem gebunden.<\/li>\n<\/ul>\n<p><strong>Adoption<\/strong>: 33% der Organisationen nutzen GitHub-Aktionen (JetBrains, 2026).<\/p>\n<h3>Gitlab CI<\/h3>\n<p><strong>St\u00e4rken<\/strong>:<\/p>\n<ul>\n<li>Mehr funktionsreiche Out of the Box (alles in einer Plattform).<\/li>\n<li>Leistungsstarke Matrixstrategien und Eltern-Kind-Pipelines.<\/li>\n<li>Bessere Unterst\u00fctzung f\u00fcr Monorepos.<\/li>\n<li>Selbst-Hosting-Option f\u00fcr luft\u00fcbergreifende Forschungsumgebungen.<\/li>\n<\/ul>\n<p><strong>Schw\u00e4chen<\/strong>:<\/p>\n<ul>\n<li>steilere Lernkurve.<\/li>\n<li>Kleinere Community als GitHub-Aktionen.<\/li>\n<li>Die Benutzeroberfl\u00e4che kann sich weniger poliert anf\u00fchlen.<\/li>\n<\/ul>\n<p><strong>Adoption<\/strong>: 19% der Organisationen (JetBrains, 2026).<\/p>\n<h3>Empfehlung<\/h3>\n<p>Wenn sich Ihr Code auf GitHub befindet, verwenden Sie <strong>GitHub-Aktionen<\/strong>, um die Einfachheit und die Integration des \u00d6kosystems zu gew\u00e4hrleisten. Wenn Sie GitLab sind oder erweiterte Pipeline-Funktionen ben\u00f6tigen, w\u00e4hlen Sie <strong>GitLab CI<\/strong>. Betrachten Sie in luftgegappten HPC-Umgebungen selbst gehostetes GitLab.<\/p>\n<p>Beide Plattformen k\u00f6nnen die gleichen Ergebnisse erzielen; Unterschiede sind meistens Workflow-Pr\u00e4ferenz. Die folgenden Beispiele verwenden GitHub-Aktionen aufgrund ihrer Popularit\u00e4t, aber GitLab CI-\u00c4quivalente sind einfach zu konstruieren.<\/p>\n<h2>CI einrichten: Ein vollst\u00e4ndiger GitHub-Aktions-Workflow<\/h2>\n<p>Dieser Abschnitt bietet einen produktionsbereiten GitHub-Aktions-Workflow f\u00fcr ein wissenschaftliches Python-Paket. Passen Sie es an Ihre Projektstruktur an.<\/p>\n<h3>Voraussetzungen<\/h3>\n<ol>\n<li><strong>Tests existieren<\/strong> (<code>tests\/<\/code> Verzeichnis).<\/li>\n<li><strong>Anforderungen werden angeheftet<\/strong> (<code>requirements.txt<\/code> oder <code>environment.yml<\/code>).<\/li>\n<li><strong>Optional, aber empfohlen<\/strong>: <code>Dockerfile<\/code> f\u00fcr die Reproduzierbarkeit der Umgebung.<\/li>\n<li>Das Code-Repository befindet sich auf GitHub.<\/li>\n<\/ol>\n<h3>Grundlegender Workflow<\/h3>\n<p><code>.github\/workflows\/ci.yml<\/code> erstellen:<\/p>\n<pre><code class=\"language-yaml\">name: CI\n\non:\n  push:\n    branches: [main, develop]\n  pull_request:\n    branches: [main]\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    strategy:\n      fail-fast: false\n      matrix:\n        python-version: [\"3.9\", \"3.10\", \"3.11\", \"3.12\"]\n\n    steps:\n    - uses: actions\/checkout@v4\n\n    - name: Set up Python ${{ matrix.python-version }}\n      uses: actions\/setup-python@v5\n      with:\n        python-version: ${{ matrix.python-version }}\n        cache: 'pip'\n        cache-dependency-path: 'requirements.txt'\n\n    - name: Install dependencies\n      run: |\n        pip install --upgrade pip\n        pip install -r requirements.txt\n        pip install pytest pytest-cov\n\n    - name: Run tests with coverage\n      run: |\n        pytest --cov=src\/ --cov-report=xml --cov-report=term-missing --junitxml=test-results.xml\n\n    - name: Upload coverage to Codecov\n      uses: codecov\/codecov-action@v4\n      with:\n        file: .\/coverage.xml\n        flags: unittests\n        name: codecov-umbrella\n\n    - name: Upload test results\n      if: always()\n      uses: actions\/upload-artifact@v4\n      with:\n        name: test-results-${{ matrix.python-version }}\n        path: test-results.xml\n<\/code><\/pre>\n<p><strong>Schl\u00fcsselfunktionen<\/strong>:<\/p>\n<ul>\n<li><strong>Matrix-Strategie<\/strong>: Die Tests werden auf Python 3.9\u20133.12 parallel ausgef\u00fchrt, wodurch Kompatibilit\u00e4tsprobleme fr\u00fchzeitig auftreten.<\/li>\n<li><strong>Caching<\/strong>: <code>actions\/setup-python<\/code> Zwischenspeichert PIP-Pakete, wodurch die Installationszeit drastisch verk\u00fcrzt wird.<\/li>\n<li><strong>Coverage<\/strong>: Terminalausgabe und XML f\u00fcr CodeCov.<\/li>\n<li><strong>Artefakte<\/strong>: Testergebnisse werden hochgeladen, auch wenn die Tests fehlschlagen, wodurch Beweise erhalten bleiben.<\/li>\n<\/ul>\n<h3>Docker in CI verwenden<\/h3>\n<p>Wenn Sie eine <code>Dockerfile<\/code> haben, verwenden Sie diese, um die Konsistenz der Umgebung sicherzustellen:<\/p>\n<pre><code class=\"language-yaml\">    - name: Build Docker image\n      run: docker build -t myproject-ci -f Dockerfile.ci .\n\n    - name: Run tests in Docker\n      run: |\n        docker run --rm \n          -v ${{ github.workspace }}:\/app \n          myproject-ci \n          pytest --cov=src\/ --cov-report=xml\n<\/code><\/pre>\n<h3>Umgang mit langj\u00e4hrigen Tests<\/h3>\n<p>Wissenschaftliche Simulationen k\u00f6nnen Stunden dauern. CI-L\u00e4ufer haben Zeitlimits (oft 6 Stunden). Strategien:<\/p>\n<ol>\n<li><strong>Separate schnelle und langsame Tests<\/strong>: Verwenden Sie PYTest-Marker.<\/li>\n<\/ol>\n<pre><code class=\"language-python\"># In test file\nimport pytest\n\n@pytest.mark.slow\ndef test_large_simulation():\n    # Takes &gt;5 minutes\n    pass\n<\/code><\/pre>\n<p>in ci:<\/p>\n<pre><code class=\"language-yaml\">    - name: Run quick tests\n      run: pytest -m \"not slow\"\n\n    - name: Run slow tests (optional, separate job)\n      if: github.event_name == 'schedule'  # Only on schedule, not on every PR\n      run: pytest -m slow\n<\/code><\/pre>\n<ol start=\"2\">\n<li><strong>Testauswahl<\/strong>: F\u00fchren Sie nur Tests durch, die von der Code\u00e4nderung betroffen sind, indem <code>pytest --last-failed<\/code> oder <code>pytest -k \"test_name\"<\/code>.<\/li>\n<li><strong>Parallelize<\/strong>: Aufteilen von Tests auf mehrere CI-Jobs mit <code>pytest-xdist<\/code>.<\/li>\n<\/ol>\n<h3>Caching-Abh\u00e4ngigkeiten<\/h3>\n<p>\u00dcber das Caching von Python-Paketen hinaus, kompilierte Erweiterungen im Cache und gro\u00dfe Datendateien:<\/p>\n<pre><code class=\"language-yaml\">    - name: Cache pip packages\n      uses: actions\/cache@v4\n      with:\n        path: ~\/.cache\/pip\n        key: ${{ runner.os }}-pip-${{ hashFiles('**\/requirements.txt') }}\n        restore-keys: |\n          ${{ runner.os }}-pip-\n\n    - name: Cache pytest\n      uses: actions\/cache@v4\n      with:\n        path: .pytest_cache\n        key: ${{ runner.os }}-pytest-${{ hashFiles('**\/*.py') }}\n<\/code><\/pre>\n<h3>Fusseln hinzuf\u00fcgen<\/h3>\n<p>F\u00fcgen Sie einen separaten Job hinzu, damit Stilprobleme die Testausf\u00fchrung nicht blockieren:<\/p>\n<pre><code class=\"language-yaml\">  lint:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: actions\/checkout@v4\n    - uses: actions\/setup-python@v5\n      with:\n        python-version: \"3.11\"\n    - run: pip install flake8 black mypy\n    - run: flake8 src\/ tests\/\n    - run: black --check src\/ tests\/\n    - run: mypy src\/\n<\/code><\/pre>\n<h2>H\u00e4ufige Fallstricke und wie man sie vermeidet<\/h2>\n<p>Basierend auf den Herausforderungen von CI \/ CD, die in der Forschungssoftware identifiziert wurden (<a href=\"https:\/\/www.testmuai.com\/blog\/cicd-pipeline-challenges\/\"> testmu AI, 2026 <\/a>), finden Sie hier h\u00e4ufige Fehler und L\u00f6sungen.<\/p>\n<h3>Fallfall 1: Tests, die abbl\u00e4ttern<\/h3>\n<p>Flaky-Tests bestehen manchmal und scheitern andere und untergraben das Vertrauen in CI. Sie sind besonders h\u00e4ufig mit:<\/p>\n<ul>\n<li><strong>Rennbedingungen<\/strong> in parallelen Tests.<\/li>\n<li><strong>Timing-Annahmen<\/strong> (z. B. &#8222;Warte 1 Sekunde&#8220;).<\/li>\n<li><strong>Zuf\u00e4lligkeit<\/strong> ohne feste Samen.<\/li>\n<\/ul>\n<p><strong>L\u00f6sung<\/strong>: Alles bestimmen. Verwenden Sie <code>pytest<\/code> Fixtures mit <code>scope=\"session\"<\/code> f\u00fcr gemeinsam genutzte Ressourcen. Setzen Sie zu Beginn jedes Tests zuf\u00e4llige Samen:<\/p>\n<pre><code class=\"language-python\">import random\nimport numpy as np\n\ndef setup_function():\n    random.seed(42)\n    np.random.seed(42)\n<\/code><\/pre>\n<h3>Fallfall 2: CI das dauert zu lange<\/h3>\n<p>Wenn Ihre Pipeline Stunden dauert, werden die Entwickler sie umgehen.<\/p>\n<p><strong>L\u00f6sung<\/strong>:<\/p>\n<ul>\n<li>Geteilt in schnelle (bei jedem Commit) und langsame (n\u00e4chtliche) Jobs.<\/li>\n<li>Cache aggressiv (PIP, Docker-Layer, Testdaten).<\/li>\n<li>Parallelisieren Sie mithilfe von Matrixstrategien.<\/li>\n<li>Markieren Sie bekannte langsame Tests mit <code>@pytest.mark.slow<\/code>  und f\u00fchren Sie sie separat aus.<\/li>\n<\/ul>\n<h3>Fallfall 3: Umgebungsabweichung zwischen CI und Entwicklung<\/h3>\n<p>Tests bestehen in CI, scheitern jedoch lokal, da sich die Umgebungen unterscheiden.<\/p>\n<p><strong>L\u00f6sung<\/strong>: Verwenden Sie \u00fcberall dieselbe Umgebungsdefinition. Docker ist ideal: Entwickler f\u00fchren <code>docker-compose run test<\/code> lokal aus und CI verwendet das gleiche Dockerfile. Alternativ k\u00f6nnen Sie <code>tox<\/code> verwenden, um mehrere Umgebungen konsistent zu verwalten.<\/p>\n<h3>Fallfall 4: Fehlende oder veraltete Abh\u00e4ngigkeiten<\/h3>\n<p>CI schl\u00e4gt fehl, weil eine Abh\u00e4ngigkeit Upstream aktualisiert wurde und die Kompatibilit\u00e4t unterbrochen wurde.<\/p>\n<p><strong>L\u00f6sung<\/strong>: PIN-Abh\u00e4ngigkeiten exakt in <code>requirements.txt<\/code> (<code>package==1.2.3<\/code>), nicht mit Bereichen (<code>&gt;=1.0<\/code>). Verwenden Sie eine Abh\u00e4ngigkeitssperrdatei (<code>pip freeze &gt; requirements.txt<\/code>). Aktualisieren Sie regelm\u00e4\u00dfig Abh\u00e4ngigkeiten kontrolliert (z. B. w\u00f6chentlich <code>dependabot<\/code> PRS).<\/p>\n<h3>Fallfall 5: Keine Leistungs\u00fcberwachung<\/h3>\n<p>Der Code wird mit der Zeit langsamer, aber Sie bemerken nur, wenn er katastrophal ist.<\/p>\n<p><strong>L\u00f6sung<\/strong>: F\u00fcgen Sie CI mit <a href=\"https:\/\/asv.readthedocs.io\/\">ASV<\/a> Benchmarks hinzu. Konfigurieren Sie es so, dass es fehlschl\u00e4gt, wenn die Leistung \u00fcber einen Schwellenwert hinausgeht (z. B. 5% langsamer). Die Implementierung finden Sie unter <a href=\"https:\/\/pythonspeed.com\/articles\/speed-unit-tests\/\"> Python Speed&#8217;s Guide<\/a>.<\/p>\n<h3>Fallfall 6: Ignorieren der numerischen Validierung<\/h3>\n<p>Tests verwenden <code>==<\/code> bei Floats und fehlen intermittierend oder schlimmer noch, nicht korrekt.<\/p>\n<p><strong>L\u00f6sung<\/strong>: Verwenden Sie \u00fcberall <code>pytest.approx<\/code> und <code>numpy.testing.assert_allclose<\/code>. W\u00e4hlen Sie Toleranzen basierend auf der numerischen Analyse (z. B. Diskretisierungsfehler sollte O (H\u00b2) f\u00fcr Methoden zweiter Ordnung sein). Begr\u00fcndung der Dokumenttoleranz in Test-DocStrings.<\/p>\n<h2>Entscheidungsleitfaden: Wann verwenden Sie was?<\/h2>\n<h3>Plattformauswahl<\/h3>\n<table>\n<thead>\n<tr>\n<th>Lage<\/th>\n<th>Empfohlene Plattform<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Code auf GitHub gehostet<\/td>\n<td>GitHub-Aktionen<\/td>\n<\/tr>\n<tr>\n<td>Code auf GitLab gehostet<\/td>\n<td>Gitlab CI<\/td>\n<\/tr>\n<tr>\n<td>Brauchen Sie selbst gehostete L\u00e4ufer (Luft Gapped)<\/td>\n<td>Gitlab CI (selbsthosted)<\/td>\n<\/tr>\n<tr>\n<td>will einfachste Einrichtung<\/td>\n<td>GitHub-Aktionen<\/td>\n<\/tr>\n<tr>\n<td>Komplexe Multiprojekt-Pipelines<\/td>\n<td>GitLab CI (Parent-Child-Pipelines)<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3>Teststrategie<\/h3>\n<table>\n<thead>\n<tr>\n<th>Codetyp<\/th>\n<th>Empfohlener Ansatz<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Reine Python-Funktionen<\/td>\n<td>Unit-Tests mit Pytest, Ziel mit hoher Abdeckung (&gt; 90%)<\/td>\n<\/tr>\n<tr>\n<td>PDE-Solver<\/td>\n<td>Regressionstests gegen Referenzl\u00f6sungen, eigenschaftsbasierte Tests<\/td>\n<\/tr>\n<tr>\n<td>Stochastische Algorithmen<\/td>\n<td>Zuf\u00e4lliger Samen + statistische Tests (Mittelwert, Varianz)<\/td>\n<\/tr>\n<tr>\n<td>Gro\u00dfe Simulationen (&gt; 5 min)<\/td>\n<td>Trennen Sie langsame Tests, laufen Sie jede Nacht; Verwenden Sie <code>@pytest.mark.slow<\/code><\/td>\n<\/tr>\n<tr>\n<td>Mehrkomponentenkopplung<\/td>\n<td>Integrationstests mit kleinen Testf\u00e4llen, Kopplungskorrektheit validieren<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3>Containerwahl<\/h3>\n<table>\n<thead>\n<tr>\n<th>Notwendigkeit<\/th>\n<th>Empfehlung<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Maximale Reproduzierbarkeit, einschlie\u00dflich DEPs auf Betriebssystemebene<\/td>\n<td>Docking<\/td>\n<\/tr>\n<tr>\n<td>Nur Python, einfacheres Management<\/td>\n<td>Conda-Umgebung<\/td>\n<\/tr>\n<tr>\n<td>HPC mit MPI-Bibliotheken<\/td>\n<td>Conda (oder Docker mit <code>--network=host<\/code> und <code>--ipc=host<\/code>)<\/td>\n<\/tr>\n<tr>\n<td>luftgedeckte Umgebung<\/td>\n<td>Conda Pack oder Docker speichern \/ laden<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2>Integration von CI in Forschungs-Workflows<\/h2>\n<p>CI existiert nicht isoliert. Es verbindet sich mit anderen Tools und Praktiken.<\/p>\n<h3>Integration von Issue-Tracking<\/h3>\n<p>Der CI-Status wird bei GitHub\/GitLab Pull-Anforderungen automatisch angezeigt. Configure branch protection rules to require CI passing before merge. Dadurch wird sichergestellt, dass nur validierter Code in den Hauptzweig eintritt.<\/p>\n<p>Die bestehenden Beitr\u00e4ge von Matforge auf <a href=\"https:\/\/matforge.org\/why-issue-tracking-is-critical-in-scientific-projects\/\">Issue-Tracking<\/a> und <a href=\"https:\/\/matforge.org\/tracking-long-term-technical-debt-in-research-software\/\">Technische Schulden<\/a> erg\u00e4nzen CI, indem sie die Art und Weise der Verwaltung von Problemen definieren. CI bietet eine automatische \u00dcberpr\u00fcfung, dass Probleme ordnungsgem\u00e4\u00df behoben werden.<\/p>\n<h3>Reproduzierbarkeitsverbindung<\/h3>\n<p>Wie in <a href=\"https:\/\/matforge.org\/reproducibility-and-its-role-in-debugging\/\"> Reproduzierbarkeit und seiner Rolle beim Debuggen <\/a> erl\u00e4utert, ist CI ein Eckpfeiler der reproduzierbaren Forschung. Jeder Commit, die CI \u00fcbergibt, kann darauf vertrauen, dass auf jeder Maschine mit derselben Umgebung dieselben Ergebnisse erzielt werden. Dies ist unerl\u00e4sslich f\u00fcr:<\/p>\n<ul>\n<li><strong>Papierreproduzierbarkeit<\/strong>: Wenn Rezensenten nach Code fragen, k\u00f6nnen Sie auf ein bestimmtes Commit verweisen, das CI bestanden und die Zahlen erstellt hat.<\/li>\n<li><strong>Kollaboration<\/strong>: Externe Mitwirkende k\u00f6nnen die gleichen Tests lokal durchf\u00fchren.<\/li>\n<li><strong>Long-Term Maintenance<\/strong>: Jahre sp\u00e4ter k\u00f6nnen Sie die Ergebnisse eines CI-validierten Commits immer noch neu erstellen.<\/li>\n<\/ul>\n<h3>Code-Review-Workflow<\/h3>\n<p>CI mit obligatorischer Code-\u00dcberpr\u00fcfung paaren:<\/p>\n<ol>\n<li>Entwickler pusht Branch, CI l\u00e4uft.<\/li>\n<li>Wenn CI \u00fcbergeht, \u00f6ffnen Sie eine Pull-Anforderung.<\/li>\n<li>Pr\u00fcfer \u00fcberpr\u00fcfen die Codelogik und stellen sicher, dass die Tests angemessen sind.<\/li>\n<li>Nur nach CI-P\u00e4ssen zusammenf\u00fchren und \u00dcberpr\u00fcfung genehmigt.<\/li>\n<\/ol>\n<p>Dieser Workflow ist in der Industrie Standard, in der Forschung jedoch immer noch selten. Die Implementierung erh\u00f6ht die Softwarequalit\u00e4t dramatisch.<\/p>\n<h2>Fortgeschrittene Themen<\/h2>\n<h3>Matrixtest f\u00fcr mehrere Abh\u00e4ngigkeiten<\/h3>\n<p>Wissenschaftliche Pakete h\u00e4ngen oft von numpy\/scipy mit versionsspezifischem Verhalten ab. Testen Sie \u00fcber eine Matrix von Python- und Abh\u00e4ngigkeitsversionen:<\/p>\n<pre><code class=\"language-yaml\">strategy:\n  matrix:\n    python-version: [\"3.9\", \"3.10\", \"3.11\"]\n    numpy-version: [\"1.24\", \"1.25\", \"1.26\"]\n<\/code><\/pre>\n<p>Installieren Sie die spezifische Numpy-Version im Schritt <code>Install dependencies<\/code>:<\/p>\n<pre><code class=\"language-yaml\">    - run: |\n        pip install \"numpy==${{ matrix.numpy-version }}\" scipy\n<\/code><\/pre>\n<p>Damit werden Kompatibilit\u00e4tsprobleme fr\u00fchzeitig behoben.<\/p>\n<h3>Leistungsregressionserkennung<\/h3>\n<p>Verwenden Sie <a href=\"https:\/\/asv.readthedocs.io\/\">ASV<\/a>, um die Leistung im Laufe der Zeit zu verfolgen:<\/p>\n<pre><code class=\"language-yaml\">    - name: Run benchmarks\n      run: |\n        asv run --quick --show-stderr\n      # asv compares against previous commits and reports regressions\n<\/code><\/pre>\n<p>Konfigurieren Sie ASV so, dass der CI-Job fehlschl\u00e4gt, wenn ein Benchmark &gt;10% langsamer als der vorherige Lauf ist. Weitere Informationen finden Sie in <a href=\"https:\/\/pythonspeed.com\/articles\/speed-unit-tests\/\"> Pythonspeeds Artikel<\/a>.<\/p>\n<h3>Kontinuierliche Bereitstellung der Dokumentation<\/h3>\n<p>CI kann die Dokumentation automatisch auf GitHub-Seiten bereitstellen:<\/p>\n<pre><code class=\"language-yaml\">  deploy-docs:\n    needs: test  # Only run after tests pass\n    runs-on: ubuntu-latest\n    steps:\n    - uses: actions\/checkout@v4\n    - run: pip install -r requirements-docs.txt\n    - run: sphinx-build -b html docs\/ public\/\n    - uses: peaceiris\/actions-gh-pages@v3\n      with:\n        github_token: ${{ secrets.GITHUB_TOKEN }}\n        publish_dir: .\/public\n<\/code><\/pre>\n<p>Dadurch wird die Dokumentation mit Code\u00e4nderungen synchronisiert.<\/p>\n<h2>Verwandte Anleitungen<\/h2>\n<ul>\n<li><strong> <a href=\"https:\/\/matforge.org\/reproducibility-and-its-role-in-debugging\/\"> Reproduzierbarkeit und ihre Rolle beim Debuggen <\/a> <\/strong> &#8211; Wie Reproduzierbarkeitspraktiken die Debugging-Effizienz verbessern.<\/li>\n<li><strong><a href=\"https:\/\/matforge.org\/tracking-long-term-technical-debt-in-research-software\/\">Nachverfolgung langfristiger technischer Schulden in Forschungssoftware<\/a><\/strong> \u2013 Verwaltung der Codequalit\u00e4t im Laufe der Zeit; CI hilft, neue Schulden zu verhindern.<\/li>\n<li><strong><a href=\"https:\/\/matforge.org\/managing-research-software-through-tickets\/\">Verwalten von Forschungssoftware durch Tickets<\/a><\/strong> \u2013 Integration von CI in Issue-Tracking-Workflows.<\/li>\n<li><strong><a href=\"https:\/\/matforge.org\/why-issue-tracking-is-critical-in-scientific-projects\/\">Warum das Issue-Tracking in wissenschaftlichen Projekten von entscheidender Bedeutung ist<\/a><\/strong> \u2013 Verst\u00e4ndnis der Bedeutung der Issue-Tracking in wissenschaftlicher Software Entwicklung.<\/li>\n<li><strong><a href=\"https:\/\/matforge.org\/collaboration-between-developers-and-researchers-turning-innovation-into-scalable-impact\/\">Kollaboration zwischen Entwicklern und Forschern<\/a><\/strong> \u2013 Innovation durch effektive Teamarbeit in skalierbare Wirkung umwandeln.<\/li>\n<\/ul>\n<h2>Zusammenfassung und n\u00e4chste Schritte<\/h2>\n<p>Continuous Integration verwandelt Forschungssoftware aus fragilen, undokumentierten Skripten in zuverl\u00e4ssige, wartbare Assets. Die Kernschritte sind:<\/p>\n<ol>\n<li>Schreiben Sie mit PyTest automatisierte Tests mit <code>pytest.approx<\/code> f\u00fcr numerische Vergleiche.<\/li>\n<li>Richten Sie eine CI-Pipeline (GitHub-Aktionen oder GitLab CI) ein, die bei jeder Push- und Pull-Anforderung ausgef\u00fchrt wird.<\/li>\n<li>Verwenden Sie Docker oder Conda, um die Konsistenz der Umgebung zwischen CI und Entwicklung sicherzustellen.<\/li>\n<li>F\u00fcgen Sie Berichterstattungsberichterstattung, Fusting und Dokumentationserstellung hinzu.<\/li>\n<li>\u00dcberwachen Sie die Leistung mit Benchmarks, um Regressionen abzufangen.<\/li>\n<li>Integrieren Sie CI in Ihre bestehenden Prozesse zur Problemverfolgung und Code\u00fcberpr\u00fcfung.<\/li>\n<\/ol>\n<p><strong>Sofortaktionen<\/strong>:<\/p>\n<ul>\n<li>Wenn Sie keine Tests haben, schreiben Sie zun\u00e4chst einige f\u00fcr die kritischsten Funktionen. Sogar 20% Deckung ist besser als keine.<\/li>\n<li>Erstellen Sie eine grundlegende CI-Konfigurationsdatei (<code>.github\/workflows\/ci.yml<\/code> wie oben gezeigt) und iterieren Sie.<\/li>\n<li>Beheben Sie flockige Tests sofort &#8211; sie untergraben das Vertrauen.<\/li>\n<li>F\u00fcgen Sie Ihrer Readme ein &#8222;Badge&#8220; hinzu, das den CI-Status anzeigt (z. B. <img decoding=\"async\" src=\"https:\/\/img.shields.io\/badge\/CI-passing-green\" alt=\"ci\">).<\/li>\n<\/ul>\n<p><strong>Wann sucht Beratung<\/strong>: Wenn es sich bei Ihrem Projekt um komplexe Abh\u00e4ngigkeiten (MPI, GPU-Code, propriet\u00e4re Bibliotheken) oder um 10.000 Codezeilen handelt, sollten Sie eine professionelle \u00dcberpr\u00fcfung Ihres CI-Setups in Betracht ziehen. Wir bieten <a href=\"\/category\/issue-tracking-tickets-technical-requests\/\"> benutzerdefinierte CI \/ CD-Implementierungsdienste <\/a> f\u00fcr Forschungsteams an.<\/p>\n<h2>Referenzen und Weiterlesen<\/h2>\n<ul>\n<li>Wilson, G. et al. (2012). <a href=\"https:\/\/www.ee.columbia.edu\/~dpwe\/e6891\/resources\/1210.0530v3.pdf\"> Best Practices for Scientific Computing <\/a>. <em> PLOS-Biologie <\/em>.<\/li>\n<li>Boettiger, C. (2015). <a href=\"https:\/\/polaris.imag.fr\/arnaud.legrand\/research\/readings\/acm_sigops_si_rsea\/p71-boettiger.pdf\">Eine Einf\u00fchrung in Docker f\u00fcr Reproduzierbare Forschung <\/a>. <em>ACM Sigops <\/em>.<\/li>\n<li>Waller, J. et al. (2015). <a href=\"https:\/\/oceanrep.geomar.de\/28433\/1\/SEN2015.pdf\">Einschlie\u00dflich Leistungs-Benchmarks in die kontinuierliche Integration<\/a>. <em>Sean <\/em>.<\/li>\n<li><a href=\"https:\/\/imperialcollegelondon.github.io\/ci-best-practice\/\"> Kontinuierliche Integration f\u00fcr Forschungssoftware <\/a> &#8211; Best Practices-Leitfaden f\u00fcr Imperial College London.<\/li>\n<li><a href=\"https:\/\/docs.github.com\/actions\/guides\/building-and-testing-python\"> GitHub-Aktionen: Erstellen und Testen von Python <\/a> &#8211; Offizielle Dokumentation.<\/li>\n<li><a href=\"https:\/\/github.com\/swcarpentry\/good-enough-practices-in-scientific-computing\">Gut genug Praktiken im wissenschaftlichen Rechnen <\/a> &#8211; Software-Schreinerarbeiten.<\/li>\n<\/ul>\n<hr>\n<p><strong>Wortanzahl<\/strong>: ~2,200<br \/> <strong>Lesezeit<\/strong>: ~10 Minuten<br \/> <strong>Zielpublikum<\/strong>: Forscher, Doktoranden und Entwickler, die an wissenschaftlichen Python-Projekten arbeiten, die eine zuverl\u00e4ssige, automatisierte Qualit\u00e4t etablieren m\u00fcssen Zusicherung<\/p>\n","protected":false,"raw":"<p>Continuous Integration (CI) erstellt, testet und validiert den Forschungscode automatisch bei jedem Commit. F\u00fcr wissenschaftliche Software ist CI f\u00fcr die Reproduzierbarkeit, die fr\u00fchzeitige Fehlererkennung und die Aufrechterhaltung der Qualit\u00e4t im Laufe der Zeit unerl\u00e4sslich. Implementieren Sie CI durch: (1) Schreiben automatisierter Tests mit PyTest, (2) Einrichten einer CI-Pipeline mit GitHub-Aktionen oder GitLab CI, (3) Verwenden von Docker \/ Conda f\u00fcr die Umgebungskonsistenz, (4) Hinzuf\u00fcgen von Berichterstellungsberichterstattung und (5) Integration von Leistungs-Benchmarks. Behandeln Sie numerische Tests mit <code>pytest.approx<\/code>, verwenden Sie Matrixstrategien, um Python-Versionen zu testen, und Cache-Abh\u00e4ngigkeiten, um die Laufzeit zu reduzieren. CI wandelt Forschungscode von fragilen Skripten in vertrauensw\u00fcrdige, wartbare Software um.<\/p>\n<h2>Einleitung: Warum Continuous Integration f\u00fcr die Forschung wichtig ist<\/h2>\n<p>Forschungssoftware ist daf\u00fcr ber\u00fcchtigt, lautlos zu brechen. Eine kleine \u00c4nderung in einem Teil des Codes kann subtil unterschiedliche Ergebnisse im Folgenden erzeugen, was ver\u00f6ffentlichte Ergebnisse ung\u00fcltig macht oder monatelange Rechenzeit verschwendet. Herk\u00f6mmliche manuelle Tests - von Hand einige Beispiele ausf\u00fchren - skalieren nicht auf komplexe Simulationscodes mit Dutzenden von voneinander abh\u00e4ngigen Modulen.<\/p>\n<p>Continuous Integration (CI) behebt dies, indem es automatisch eine umfassende Testsuite ausf\u00fchrt, wenn Code festgeschrieben wird. Aber CI ist mehr als nur Automatisierung; Es ist eine Qualit\u00e4tsdisziplin, die die Reproduzierbarkeit durchsetzt und die Korrektheit kontinuierlich best\u00e4tigt. Als <a href=\"https:\/\/www.ee.columbia.edu\/~dpwe\/e6891\/resources\/1210.0530v3.pdf\"> Best Practices for Scientific Computing <\/a> Papiernotizen: \"Automatisiertes Testen ist Nicht verhandelbar f\u00fcr vertrauensw\u00fcrdige wissenschaftliche Software \"(Wilson et al., 2012).<\/p>\n<p>F\u00fcr Forschungsteams bietet CI konkrete Vorteile:<\/p>\n<ul>\n<li><strong>Reproduzierbarkeit<\/strong>: CI \u00fcberpr\u00fcft, ob der Code konsistente Ergebnisse in Umgebungen und im Laufe der Zeit liefert.<\/li>\n<li><strong>Early Defekterkennung<\/strong>: Fehler werden Minuten nach ihrer Einf\u00fchrung abgefangen, nicht Wochen sp\u00e4ter w\u00e4hrend der Erstellung der Manuskripte.<\/li>\n<li><strong>Zuversicht in Refactor<\/strong>: Mit einem Sicherheitsnetz von Tests k\u00f6nnen Sie die Codestruktur verbessern, ohne Angst zu haben, etwas zu brechen.<\/li>\n<li><strong>Collaboration Enablement<\/strong>: Mehrere Mitwirkende k\u00f6nnen auf derselben Codebasis arbeiten, indem sie automatische \u00dcberpr\u00fcfungen verhindern.<\/li>\n<li><strong>Erwartungsdokumentation<\/strong>: Tests dienen als ausf\u00fchrbare Spezifikationen, die dokumentieren, wie sich der Code verhalten soll.<\/li>\n<\/ul>\n<p>Trotz dieser Vorteile fehlt vielen Forschungsprojekten CI immer noch. H\u00e4ufige Ausreden sind \"Unser Code ist zu komplex, um zu testen\", \"Tests dauern zu lange\" oder \"Wir haben keine Zeit, CI einzurichten.\" Dieser Leitfaden l\u00f6st diese Einw\u00e4nde und bietet einen praktischen, schrittweisen Ansatz f\u00fcr CI, der auf wissenschaftliche Software zugeschnitten ist.<\/p>\n<h2>Was ist wirklich kontinuierliche Integration?<\/h2>\n<p>Kontinuierliche Integration ist das Zusammenf\u00fchren von Code\u00e4nderungen in einem gemeinsamen Repository h\u00e4ufig - idealerweise mehrmals pro Tag - und die automatische \u00dcberpr\u00fcfung jeder Zusammenf\u00fchrung mit einer automatisierten Build- und Test-Pipeline. Der \"kontinuierliche\" Teil bedeutet, dass das Feedback schnell ist; Entwickler wissen innerhalb weniger Minuten, ob ihre \u00c4nderung etwas kaputt gemacht hat.<\/p>\n<p>Eine CI-Pipeline enth\u00e4lt typischerweise:<\/p>\n<ol>\n<li><strong>Checkout<\/strong>: Das CI-System ruft den neuesten Code ab.<\/li>\n<li><strong>Umgebungs-Setup<\/strong>: Abh\u00e4ngigkeiten werden installiert (h\u00e4ufig innerhalb eines Containers).<\/li>\n<li><strong>Statische Analyse<\/strong>: Der Code ist f\u00fcr Stilprobleme und potenzielle Fehler furchtbar.<\/li>\n<li><strong>Einheitstests<\/strong>: Einzelne Funktionen und Module werden isoliert getestet.<\/li>\n<li><strong>Integrationstests<\/strong>: Mehrere Komponenten werden zusammen getestet.<\/li>\n<li><strong>Coverage-Reporting<\/strong>: Der Anteil des Codes, der durch Tests ausge\u00fcbt wird, wird gemessen.<\/li>\n<li><strong>Artefact Building<\/strong>: Dokumentation, Pakete oder Bin\u00e4rdateien werden generiert.<\/li>\n<li><strong>Performance-Benchmarks<\/strong> (optional): Ausf\u00fchrungsgeschwindigkeit und Speichernutzung werden verfolgt.<\/li>\n<\/ol>\n<p>F\u00fcr Forschungssoftware f\u00fcgen wir hinzu:<\/p>\n<ul>\n<li><strong>Numerische Validierung<\/strong>: Tests, die Gleitkommatoleranzen und stochastische Variationen ber\u00fccksichtigen.<\/li>\n<li><strong>\u00dcberpr\u00fcfungen der Reproduzierbarkeit<\/strong>: \u00dcberpr\u00fcfung, dass die Ergebnisse innerhalb akzeptabler Grenzen \u00fcbereinstimmen.<\/li>\n<li><strong>Datenvalidierung<\/strong>: Gew\u00e4hrleistung der Integrit\u00e4t der Eingabe- und Ausgabedaten.<\/li>\n<\/ul>\n<h2>Kernkomponenten: Aufbau einer forschungsbereiten CI-Pipeline<\/h2>\n<p>Eine robuste CI-Pipeline f\u00fcr wissenschaftliche Python-Projekte sollte diese Komponenten enthalten, die jeweils einen bestimmten Qualit\u00e4tsaspekt ansprechen.<\/p>\n<h3>Automatisiertes Testen mit PyTest<\/h3>\n<p>Die Stiftung ist eine umfassende Testsuite mit <a href=\"https:\/\/docs.pytest.org\/\">pytest<\/a>. PyTest ist der De-facto-Standard f\u00fcr Python-Tests aufgrund seiner Einfachheit, leistungsstarken Ger\u00e4te und reichhaltigen \u00d6kosystems.<\/p>\n<p>F\u00fcr den wissenschaftlichen Kodex konzentrieren Sie sich auf:<\/p>\n<ul>\n<li><strong>Einheitstests<\/strong> f\u00fcr einzelne Funktionen (z. B. berechnet ein Diffusionsl\u00f6ser korrekt auf einem einfachen Netz?).<\/li>\n<li><strong>Regressionstests<\/strong>, die die Ergebnisse mit bekannten guten Ergebnissen vergleichen (wesentlich f\u00fcr PDE-Solver).<\/li>\n<li><strong>Eigenschaftsbasierte Tests<\/strong> mit <a href=\"https:\/\/hypothesis.readthedocs.io\/\">Hypothese<\/a>, um zuf\u00e4llige Eingaben zu generieren und Invarianten zu \u00fcberpr\u00fcfen.<\/li>\n<\/ul>\n<p>Der Einheitentest f\u00fcr den wissenschaftlichen Codeentwurf (in Bearbeitung) behandelt PYTest-Strategien in der Tiefe, einschlie\u00dflich der numerischen Pr\u00e4zision.<\/p>\n<h3>Umgang mit numerischen Vergleichen<\/h3>\n<p>Der wissenschaftliche Code befasst sich mit Gleitkomma-Arithmetik, bei der eine exakte Gleichheit aufgrund von Rundungsfehlern oft nicht m\u00f6glich ist. PYTEST bietet <code>pytest.approx<\/code> f\u00fcr ungef\u00e4hre Vergleiche:<\/p>\n<pre><code class=\"language-python\">def test_diffusion_result():\n    result = run_simulation()\n    expected = 0.123456\n    assert result == pytest.approx(expected, rel=1e-6)  # 0.1% tolerance\n<\/code><\/pre>\n<p>Verwenden Sie f\u00fcr Arrays <code>numpy.testing.assert_allclose<\/code>:<\/p>\n<pre><code class=\"language-python\">import numpy.testing as npt\n\ndef test_field_solution():\n    computed = solve_pde()\n    reference = load_reference_solution()\n    npt.assert_allclose(computed, reference, rtol=1e-5, atol=1e-10)\n<\/code><\/pre>\n<p>W\u00e4hlen Sie Toleranzen basierend auf der Physik und der Diskretisierungsgenauigkeit. Dokumentieren Sie, warum bestimmte Toleranzen ausgew\u00e4hlt wurden.<\/p>\n<h3>Codeabdeckungsmessung<\/h3>\n<p>Die Codeabdeckung misst, wie viel von Ihrer Codebasis w\u00e4hrend der Tests ausgef\u00fchrt wird. W\u00e4hrend eine 100% ige Abdeckung nicht immer erforderlich (oder erreichbar) ist, hilft die Verfolgung, ungetestete Codepfade zu identifizieren.<\/p>\n<p>Verwenden Sie <a href=\"https:\/\/pytest-cov.readthedocs.io\/\">pytest-cov<\/a>, um Berichterstattungsberichte zu erstellen:<\/p>\n<pre><code class=\"language-bash\">pytest --cov=src\/ --cov-report=xml --cov-report=html\n<\/code><\/pre>\n<p>Integrieren Sie <a href=\"https:\/\/codecov.io\/\">Codecov<\/a> oder <a href=\"https:\/\/coveralls.io\/\">coveralls<\/a>, um die Abdeckung im Laufe der Zeit zu verfolgen und die Mindestgrenzwerte in CI zu erzwingen.<\/p>\n<p>Das <a href=\"https:\/\/learn.scientific-python.org\/development\/guides\/coverage\/\">Wissenschaftliches Python-Entwicklungshandbuch<\/a> enth\u00e4lt detaillierte Beispiele f\u00fcr die Konfiguration der Abdeckung.<\/p>\n<h3>Statische Analyse und Fusseln<\/h3>\n<p>Statische Analysetools fangen Fehler ab und erzwingen die Stilkonsistenz, bevor der Code zusammengef\u00fchrt wird:<\/p>\n<ul>\n<li><strong>Flake8<\/strong>: PEP 8 Style Guide Durchsetzung und grundlegende Fehlerpr\u00fcfung.<\/li>\n<li><strong>MyPy<\/strong>: statische Typpr\u00fcfung (graduelle Eingabe ist auch im Forschungscode wertvoll).<\/li>\n<li><strong>Schwarz<\/strong>: Automatische Codeformatierung (eliminiert Stildebatten).<\/li>\n<li><strong>Pylint<\/strong>: Eine tiefere Analyse der Codequalit\u00e4t (vorsichtig anwenden; einige Regeln sind m\u00f6glicherweise zu streng f\u00fcr den Forschungscode).<\/li>\n<\/ul>\n<p>F\u00fchren Sie diese als separate CI-Jobs aus, damit Fehler nicht blockieren.<\/p>\n<h3>Umgebungskonsistenz mit Docker oder Conda<\/h3>\n<p>Eine der gr\u00f6\u00dften Herausforderungen f\u00fcr die Reproduzierbarkeit ist die H\u00f6lle der Abh\u00e4ngigkeit - verschiedene Versionen von Bibliotheken f\u00fchren zu unterschiedlichen Ergebnissen. CI beseitigt dies durch die Installation von Abh\u00e4ngigkeiten in einer sauberen, kontrollierten Umgebung.<\/p>\n<p><strong>Option A: Docker<\/strong> (empfohlen f\u00fcr CI)<\/p>\n<p>Docker bietet vollst\u00e4ndige Containerisierung auf Systemebene. a <code>Dockerfile<\/code> definiert die genaue Umgebung:<\/p>\n<pre><code class=\"language-dockerfile\">FROM python:3.11-slim\n\nWORKDIR \/app\nCOPY requirements.txt .\nRUN pip install --no-cache-dir -r requirements.txt\nCOPY . .\n<\/code><\/pre>\n<p><a href=\"https:\/\/polaris.imag.fr\/arnaud.legrand\/research\/readings\/acm_sigops_si_rsea\/p71-boettiger.pdf\"> BOETTIGER. (2015) <\/a> argumentiert, dass Docker \"das Beste ist, was jemals mit wissenschaftlicher Reproduzierbarkeit passiert\" ist, da es den gesamten Software-Stack vom Betriebssystem zu Bibliotheken sperrt.<\/p>\n<p><strong>Option B: Conda-Umgebungen<\/strong><\/p>\n<p>Wenn Ihr Projekt auf Nicht-Python-Abh\u00e4ngigkeiten (z. B. HDF5, MPI) angewiesen ist, verwenden Sie Conda:<\/p>\n<pre><code class=\"language-yaml\"># environment.yml\nname: research-ci\ndependencies:\n  - python=3.11\n  - numpy&gt;=1.24\n  - scipy\n  - pip:\n    - pytest\n    - pytest-cov\n<\/code><\/pre>\n<p>CI-Systeme k\u00f6nnen diese Umgebung mit <code>conda env create -f environment.yml<\/code> erstellen und aktivieren.<\/p>\n<p><strong>Wichtig<\/strong>: <a href=\"https:\/\/arxiv.org\/html\/2601.12811v1\">Docker garantiert Reproduzierbarkeit nicht<\/a> warnt davor, dass selbst Container subtile Unterschiede haben k\u00f6nnen (Zeitstempel, zuf\u00e4llig Samen). Fixieren Sie f\u00fcr maximale Reproduzierbarkeit auch Bibliotheksversionen und Seeds.<\/p>\n<h3>Dokumentationsaufbau<\/h3>\n<p>F\u00fcgen Sie einen Schritt zum Erstellen von Dokumentationen (Sphinx, Mkdocs) hinzu und stellen Sie diese optional bereit. Documentation-as-Code stellt sicher, dass die Dokumente mit dem Code synchron bleiben. Der Entwurf der Dokumentation Best Practices f\u00fcr wissenschaftliche Python-Pakete erl\u00e4utert dies im Detail.<\/p>\n<h3>Leistungs-Benchmarks<\/h3>\n<p>\u00dcberwachen Sie f\u00fcr rechnerisch intensive Forschungssoftware die Leistung, um Regressionen abzufangen. Tools wie <a href=\"https:\/\/asv.readthedocs.io\/\">ASV (Airspeed Velocity)<\/a> f\u00fchren Benchmarks automatisch durch und vergleichen sie mit fr\u00fcheren L\u00e4ufen.<\/p>\n<p>Waller et al. (2015) beschreiben <a href=\"https:\/\/oceanrep.geomar.de\/28433\/1\/SEN2015.pdf\"> einschlie\u00dflich Leistungs-Benchmarks in CI <\/a>, um Leistungseinbu\u00dfen fr\u00fchzeitig zu erkennen. Dies ist besonders wichtig f\u00fcr PDE-Solver, bei denen algorithmische \u00c4nderungen die Laufzeit drastisch beeinflussen k\u00f6nnen.<\/p>\n<h2>Plattformvergleich: GitHub-Aktionen gegen GitLab CI<\/h2>\n<p>Es gibt zwei dominante CI-Plattformen: GitHub-Aktionen und GitLab CI. Beide sind ausgereift und produktionsbereit. Die Wahl h\u00e4ngt h\u00e4ufig davon ab, wo Ihr Code gehostet wird.<\/p>\n<h3>GitHub-Aktionen<\/h3>\n<p><strong>St\u00e4rken<\/strong>:<\/p>\n<ul>\n<li>Tiefe Integration mit GitHub (Pull Request Checks, Marktplatz der Aktionen).<\/li>\n<li>Einfachere Konfigurationssyntax f\u00fcr g\u00e4ngige Workflows.<\/li>\n<li>Gr\u00f6\u00dfere Community und mehr Aktionen von Drittanbietern.<\/li>\n<li>Kostenlos f\u00fcr \u00f6ffentliche Repositories; Gro\u00dfz\u00fcgige kostenlose Stufe f\u00fcr private Repos.<\/li>\n<\/ul>\n<p><strong>Schw\u00e4chen<\/strong>:<\/p>\n<ul>\n<li>Weniger leistungsf\u00e4hig f\u00fcr komplexe Workflows als GitLab.<\/li>\n<li>Eingeschr\u00e4nkte integrierte Funktionen f\u00fcr das Abh\u00e4ngigkeits-Caching in fr\u00fchen Versionen (jetzt verbessert).<\/li>\n<li>an das GitHub-\u00d6kosystem gebunden.<\/li>\n<\/ul>\n<p><strong>Adoption<\/strong>: 33% der Organisationen nutzen GitHub-Aktionen (JetBrains, 2026).<\/p>\n<h3>Gitlab CI<\/h3>\n<p><strong>St\u00e4rken<\/strong>:<\/p>\n<ul>\n<li>Mehr funktionsreiche Out of the Box (alles in einer Plattform).<\/li>\n<li>Leistungsstarke Matrixstrategien und Eltern-Kind-Pipelines.<\/li>\n<li>Bessere Unterst\u00fctzung f\u00fcr Monorepos.<\/li>\n<li>Selbst-Hosting-Option f\u00fcr luft\u00fcbergreifende Forschungsumgebungen.<\/li>\n<\/ul>\n<p><strong>Schw\u00e4chen<\/strong>:<\/p>\n<ul>\n<li>steilere Lernkurve.<\/li>\n<li>Kleinere Community als GitHub-Aktionen.<\/li>\n<li>Die Benutzeroberfl\u00e4che kann sich weniger poliert anf\u00fchlen.<\/li>\n<\/ul>\n<p><strong>Adoption<\/strong>: 19% der Organisationen (JetBrains, 2026).<\/p>\n<h3>Empfehlung<\/h3>\n<p>Wenn sich Ihr Code auf GitHub befindet, verwenden Sie <strong>GitHub-Aktionen<\/strong>, um die Einfachheit und die Integration des \u00d6kosystems zu gew\u00e4hrleisten. Wenn Sie GitLab sind oder erweiterte Pipeline-Funktionen ben\u00f6tigen, w\u00e4hlen Sie <strong>GitLab CI<\/strong>. Betrachten Sie in luftgegappten HPC-Umgebungen selbst gehostetes GitLab.<\/p>\n<p>Beide Plattformen k\u00f6nnen die gleichen Ergebnisse erzielen; Unterschiede sind meistens Workflow-Pr\u00e4ferenz. Die folgenden Beispiele verwenden GitHub-Aktionen aufgrund ihrer Popularit\u00e4t, aber GitLab CI-\u00c4quivalente sind einfach zu konstruieren.<\/p>\n<h2>CI einrichten: Ein vollst\u00e4ndiger GitHub-Aktions-Workflow<\/h2>\n<p>Dieser Abschnitt bietet einen produktionsbereiten GitHub-Aktions-Workflow f\u00fcr ein wissenschaftliches Python-Paket. Passen Sie es an Ihre Projektstruktur an.<\/p>\n<h3>Voraussetzungen<\/h3>\n<ol>\n<li><strong>Tests existieren<\/strong> (<code>tests\/<\/code> Verzeichnis).<\/li>\n<li><strong>Anforderungen werden angeheftet<\/strong> (<code>requirements.txt<\/code> oder <code>environment.yml<\/code>).<\/li>\n<li><strong>Optional, aber empfohlen<\/strong>: <code>Dockerfile<\/code> f\u00fcr die Reproduzierbarkeit der Umgebung.<\/li>\n<li>Das Code-Repository befindet sich auf GitHub.<\/li>\n<\/ol>\n<h3>Grundlegender Workflow<\/h3>\n<p><code>.github\/workflows\/ci.yml<\/code> erstellen:<\/p>\n<pre><code class=\"language-yaml\">name: CI\n\non:\n  push:\n    branches: [main, develop]\n  pull_request:\n    branches: [main]\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    strategy:\n      fail-fast: false\n      matrix:\n        python-version: [\"3.9\", \"3.10\", \"3.11\", \"3.12\"]\n\n    steps:\n    - uses: actions\/checkout@v4\n\n    - name: Set up Python ${{ matrix.python-version }}\n      uses: actions\/setup-python@v5\n      with:\n        python-version: ${{ matrix.python-version }}\n        cache: 'pip'\n        cache-dependency-path: 'requirements.txt'\n\n    - name: Install dependencies\n      run: |\n        pip install --upgrade pip\n        pip install -r requirements.txt\n        pip install pytest pytest-cov\n\n    - name: Run tests with coverage\n      run: |\n        pytest --cov=src\/ --cov-report=xml --cov-report=term-missing --junitxml=test-results.xml\n\n    - name: Upload coverage to Codecov\n      uses: codecov\/codecov-action@v4\n      with:\n        file: .\/coverage.xml\n        flags: unittests\n        name: codecov-umbrella\n\n    - name: Upload test results\n      if: always()\n      uses: actions\/upload-artifact@v4\n      with:\n        name: test-results-${{ matrix.python-version }}\n        path: test-results.xml\n<\/code><\/pre>\n<p><strong>Schl\u00fcsselfunktionen<\/strong>:<\/p>\n<ul>\n<li><strong>Matrix-Strategie<\/strong>: Die Tests werden auf Python 3.9\u20133.12 parallel ausgef\u00fchrt, wodurch Kompatibilit\u00e4tsprobleme fr\u00fchzeitig auftreten.<\/li>\n<li><strong>Caching<\/strong>: <code>actions\/setup-python<\/code> Zwischenspeichert PIP-Pakete, wodurch die Installationszeit drastisch verk\u00fcrzt wird.<\/li>\n<li><strong>Coverage<\/strong>: Terminalausgabe und XML f\u00fcr CodeCov.<\/li>\n<li><strong>Artefakte<\/strong>: Testergebnisse werden hochgeladen, auch wenn die Tests fehlschlagen, wodurch Beweise erhalten bleiben.<\/li>\n<\/ul>\n<h3>Docker in CI verwenden<\/h3>\n<p>Wenn Sie eine <code>Dockerfile<\/code> haben, verwenden Sie diese, um die Konsistenz der Umgebung sicherzustellen:<\/p>\n<pre><code class=\"language-yaml\">    - name: Build Docker image\n      run: docker build -t myproject-ci -f Dockerfile.ci .\n\n    - name: Run tests in Docker\n      run: |\n        docker run --rm \n          -v ${{ github.workspace }}:\/app \n          myproject-ci \n          pytest --cov=src\/ --cov-report=xml\n<\/code><\/pre>\n<h3>Umgang mit langj\u00e4hrigen Tests<\/h3>\n<p>Wissenschaftliche Simulationen k\u00f6nnen Stunden dauern. CI-L\u00e4ufer haben Zeitlimits (oft 6 Stunden). Strategien:<\/p>\n<ol>\n<li><strong>Separate schnelle und langsame Tests<\/strong>: Verwenden Sie PYTest-Marker.<\/li>\n<\/ol>\n<pre><code class=\"language-python\"># In test file\nimport pytest\n\n@pytest.mark.slow\ndef test_large_simulation():\n    # Takes &gt;5 minutes\n    pass\n<\/code><\/pre>\n<p>in ci:<\/p>\n<pre><code class=\"language-yaml\">    - name: Run quick tests\n      run: pytest -m \"not slow\"\n\n    - name: Run slow tests (optional, separate job)\n      if: github.event_name == 'schedule'  # Only on schedule, not on every PR\n      run: pytest -m slow\n<\/code><\/pre>\n<ol start=\"2\">\n<li><strong>Testauswahl<\/strong>: F\u00fchren Sie nur Tests durch, die von der Code\u00e4nderung betroffen sind, indem <code>pytest --last-failed<\/code> oder <code>pytest -k \"test_name\"<\/code>.<\/li>\n<li><strong>Parallelize<\/strong>: Aufteilen von Tests auf mehrere CI-Jobs mit <code>pytest-xdist<\/code>.<\/li>\n<\/ol>\n<h3>Caching-Abh\u00e4ngigkeiten<\/h3>\n<p>\u00dcber das Caching von Python-Paketen hinaus, kompilierte Erweiterungen im Cache und gro\u00dfe Datendateien:<\/p>\n<pre><code class=\"language-yaml\">    - name: Cache pip packages\n      uses: actions\/cache@v4\n      with:\n        path: ~\/.cache\/pip\n        key: ${{ runner.os }}-pip-${{ hashFiles('**\/requirements.txt') }}\n        restore-keys: |\n          ${{ runner.os }}-pip-\n\n    - name: Cache pytest\n      uses: actions\/cache@v4\n      with:\n        path: .pytest_cache\n        key: ${{ runner.os }}-pytest-${{ hashFiles('**\/*.py') }}\n<\/code><\/pre>\n<h3>Fusseln hinzuf\u00fcgen<\/h3>\n<p>F\u00fcgen Sie einen separaten Job hinzu, damit Stilprobleme die Testausf\u00fchrung nicht blockieren:<\/p>\n<pre><code class=\"language-yaml\">  lint:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: actions\/checkout@v4\n    - uses: actions\/setup-python@v5\n      with:\n        python-version: \"3.11\"\n    - run: pip install flake8 black mypy\n    - run: flake8 src\/ tests\/\n    - run: black --check src\/ tests\/\n    - run: mypy src\/\n<\/code><\/pre>\n<h2>H\u00e4ufige Fallstricke und wie man sie vermeidet<\/h2>\n<p>Basierend auf den Herausforderungen von CI \/ CD, die in der Forschungssoftware identifiziert wurden (<a href=\"https:\/\/www.testmuai.com\/blog\/cicd-pipeline-challenges\/\"> testmu AI, 2026 <\/a>), finden Sie hier h\u00e4ufige Fehler und L\u00f6sungen.<\/p>\n<h3>Fallfall 1: Tests, die abbl\u00e4ttern<\/h3>\n<p>Flaky-Tests bestehen manchmal und scheitern andere und untergraben das Vertrauen in CI. Sie sind besonders h\u00e4ufig mit:<\/p>\n<ul>\n<li><strong>Rennbedingungen<\/strong> in parallelen Tests.<\/li>\n<li><strong>Timing-Annahmen<\/strong> (z. B. \"Warte 1 Sekunde\").<\/li>\n<li><strong>Zuf\u00e4lligkeit<\/strong> ohne feste Samen.<\/li>\n<\/ul>\n<p><strong>L\u00f6sung<\/strong>: Alles bestimmen. Verwenden Sie <code>pytest<\/code> Fixtures mit <code>scope=\"session\"<\/code> f\u00fcr gemeinsam genutzte Ressourcen. Setzen Sie zu Beginn jedes Tests zuf\u00e4llige Samen:<\/p>\n<pre><code class=\"language-python\">import random\nimport numpy as np\n\ndef setup_function():\n    random.seed(42)\n    np.random.seed(42)\n<\/code><\/pre>\n<h3>Fallfall 2: CI das dauert zu lange<\/h3>\n<p>Wenn Ihre Pipeline Stunden dauert, werden die Entwickler sie umgehen.<\/p>\n<p><strong>L\u00f6sung<\/strong>:<\/p>\n<ul>\n<li>Geteilt in schnelle (bei jedem Commit) und langsame (n\u00e4chtliche) Jobs.<\/li>\n<li>Cache aggressiv (PIP, Docker-Layer, Testdaten).<\/li>\n<li>Parallelisieren Sie mithilfe von Matrixstrategien.<\/li>\n<li>Markieren Sie bekannte langsame Tests mit <code>@pytest.mark.slow<\/code>  und f\u00fchren Sie sie separat aus.<\/li>\n<\/ul>\n<h3>Fallfall 3: Umgebungsabweichung zwischen CI und Entwicklung<\/h3>\n<p>Tests bestehen in CI, scheitern jedoch lokal, da sich die Umgebungen unterscheiden.<\/p>\n<p><strong>L\u00f6sung<\/strong>: Verwenden Sie \u00fcberall dieselbe Umgebungsdefinition. Docker ist ideal: Entwickler f\u00fchren <code>docker-compose run test<\/code> lokal aus und CI verwendet das gleiche Dockerfile. Alternativ k\u00f6nnen Sie <code>tox<\/code> verwenden, um mehrere Umgebungen konsistent zu verwalten.<\/p>\n<h3>Fallfall 4: Fehlende oder veraltete Abh\u00e4ngigkeiten<\/h3>\n<p>CI schl\u00e4gt fehl, weil eine Abh\u00e4ngigkeit Upstream aktualisiert wurde und die Kompatibilit\u00e4t unterbrochen wurde.<\/p>\n<p><strong>L\u00f6sung<\/strong>: PIN-Abh\u00e4ngigkeiten exakt in <code>requirements.txt<\/code> (<code>package==1.2.3<\/code>), nicht mit Bereichen (<code>&gt;=1.0<\/code>). Verwenden Sie eine Abh\u00e4ngigkeitssperrdatei (<code>pip freeze &gt; requirements.txt<\/code>). Aktualisieren Sie regelm\u00e4\u00dfig Abh\u00e4ngigkeiten kontrolliert (z. B. w\u00f6chentlich <code>dependabot<\/code> PRS).<\/p>\n<h3>Fallfall 5: Keine Leistungs\u00fcberwachung<\/h3>\n<p>Der Code wird mit der Zeit langsamer, aber Sie bemerken nur, wenn er katastrophal ist.<\/p>\n<p><strong>L\u00f6sung<\/strong>: F\u00fcgen Sie CI mit <a href=\"https:\/\/asv.readthedocs.io\/\">ASV<\/a> Benchmarks hinzu. Konfigurieren Sie es so, dass es fehlschl\u00e4gt, wenn die Leistung \u00fcber einen Schwellenwert hinausgeht (z. B. 5% langsamer). Die Implementierung finden Sie unter <a href=\"https:\/\/pythonspeed.com\/articles\/speed-unit-tests\/\"> Python Speed's Guide<\/a>.<\/p>\n<h3>Fallfall 6: Ignorieren der numerischen Validierung<\/h3>\n<p>Tests verwenden <code>==<\/code> bei Floats und fehlen intermittierend oder schlimmer noch, nicht korrekt.<\/p>\n<p><strong>L\u00f6sung<\/strong>: Verwenden Sie \u00fcberall <code>pytest.approx<\/code> und <code>numpy.testing.assert_allclose<\/code>. W\u00e4hlen Sie Toleranzen basierend auf der numerischen Analyse (z. B. Diskretisierungsfehler sollte O (H\u00b2) f\u00fcr Methoden zweiter Ordnung sein). Begr\u00fcndung der Dokumenttoleranz in Test-DocStrings.<\/p>\n<h2>Entscheidungsleitfaden: Wann verwenden Sie was?<\/h2>\n<h3>Plattformauswahl<\/h3>\n<table>\n<thead>\n<tr>\n<th>Lage<\/th>\n<th>Empfohlene Plattform<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Code auf GitHub gehostet<\/td>\n<td>GitHub-Aktionen<\/td>\n<\/tr>\n<tr>\n<td>Code auf GitLab gehostet<\/td>\n<td>Gitlab CI<\/td>\n<\/tr>\n<tr>\n<td>Brauchen Sie selbst gehostete L\u00e4ufer (Luft Gapped)<\/td>\n<td>Gitlab CI (selbsthosted)<\/td>\n<\/tr>\n<tr>\n<td>will einfachste Einrichtung<\/td>\n<td>GitHub-Aktionen<\/td>\n<\/tr>\n<tr>\n<td>Komplexe Multiprojekt-Pipelines<\/td>\n<td>GitLab CI (Parent-Child-Pipelines)<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3>Teststrategie<\/h3>\n<table>\n<thead>\n<tr>\n<th>Codetyp<\/th>\n<th>Empfohlener Ansatz<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Reine Python-Funktionen<\/td>\n<td>Unit-Tests mit Pytest, Ziel mit hoher Abdeckung (&gt; 90%)<\/td>\n<\/tr>\n<tr>\n<td>PDE-Solver<\/td>\n<td>Regressionstests gegen Referenzl\u00f6sungen, eigenschaftsbasierte Tests<\/td>\n<\/tr>\n<tr>\n<td>Stochastische Algorithmen<\/td>\n<td>Zuf\u00e4lliger Samen + statistische Tests (Mittelwert, Varianz)<\/td>\n<\/tr>\n<tr>\n<td>Gro\u00dfe Simulationen (&gt; 5 min)<\/td>\n<td>Trennen Sie langsame Tests, laufen Sie jede Nacht; Verwenden Sie <code>@pytest.mark.slow<\/code><\/td>\n<\/tr>\n<tr>\n<td>Mehrkomponentenkopplung<\/td>\n<td>Integrationstests mit kleinen Testf\u00e4llen, Kopplungskorrektheit validieren<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3>Containerwahl<\/h3>\n<table>\n<thead>\n<tr>\n<th>Notwendigkeit<\/th>\n<th>Empfehlung<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Maximale Reproduzierbarkeit, einschlie\u00dflich DEPs auf Betriebssystemebene<\/td>\n<td>Docking<\/td>\n<\/tr>\n<tr>\n<td>Nur Python, einfacheres Management<\/td>\n<td>Conda-Umgebung<\/td>\n<\/tr>\n<tr>\n<td>HPC mit MPI-Bibliotheken<\/td>\n<td>Conda (oder Docker mit <code>--network=host<\/code> und <code>--ipc=host<\/code>)<\/td>\n<\/tr>\n<tr>\n<td>luftgedeckte Umgebung<\/td>\n<td>Conda Pack oder Docker speichern \/ laden<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2>Integration von CI in Forschungs-Workflows<\/h2>\n<p>CI existiert nicht isoliert. Es verbindet sich mit anderen Tools und Praktiken.<\/p>\n<h3>Integration von Issue-Tracking<\/h3>\n<p>Der CI-Status wird bei GitHub\/GitLab Pull-Anforderungen automatisch angezeigt. Configure branch protection rules to require CI passing before merge. Dadurch wird sichergestellt, dass nur validierter Code in den Hauptzweig eintritt.<\/p>\n<p>Die bestehenden Beitr\u00e4ge von Matforge auf <a href=\"https:\/\/matforge.org\/why-issue-tracking-is-critical-in-scientific-projects\/\">Issue-Tracking<\/a> und <a href=\"https:\/\/matforge.org\/tracking-long-term-technical-debt-in-research-software\/\">Technische Schulden<\/a> erg\u00e4nzen CI, indem sie die Art und Weise der Verwaltung von Problemen definieren. CI bietet eine automatische \u00dcberpr\u00fcfung, dass Probleme ordnungsgem\u00e4\u00df behoben werden.<\/p>\n<h3>Reproduzierbarkeitsverbindung<\/h3>\n<p>Wie in <a href=\"https:\/\/matforge.org\/reproducibility-and-its-role-in-debugging\/\"> Reproduzierbarkeit und seiner Rolle beim Debuggen <\/a> erl\u00e4utert, ist CI ein Eckpfeiler der reproduzierbaren Forschung. Jeder Commit, die CI \u00fcbergibt, kann darauf vertrauen, dass auf jeder Maschine mit derselben Umgebung dieselben Ergebnisse erzielt werden. Dies ist unerl\u00e4sslich f\u00fcr:<\/p>\n<ul>\n<li><strong>Papierreproduzierbarkeit<\/strong>: Wenn Rezensenten nach Code fragen, k\u00f6nnen Sie auf ein bestimmtes Commit verweisen, das CI bestanden und die Zahlen erstellt hat.<\/li>\n<li><strong>Kollaboration<\/strong>: Externe Mitwirkende k\u00f6nnen die gleichen Tests lokal durchf\u00fchren.<\/li>\n<li><strong>Long-Term Maintenance<\/strong>: Jahre sp\u00e4ter k\u00f6nnen Sie die Ergebnisse eines CI-validierten Commits immer noch neu erstellen.<\/li>\n<\/ul>\n<h3>Code-Review-Workflow<\/h3>\n<p>CI mit obligatorischer Code-\u00dcberpr\u00fcfung paaren:<\/p>\n<ol>\n<li>Entwickler pusht Branch, CI l\u00e4uft.<\/li>\n<li>Wenn CI \u00fcbergeht, \u00f6ffnen Sie eine Pull-Anforderung.<\/li>\n<li>Pr\u00fcfer \u00fcberpr\u00fcfen die Codelogik und stellen sicher, dass die Tests angemessen sind.<\/li>\n<li>Nur nach CI-P\u00e4ssen zusammenf\u00fchren und \u00dcberpr\u00fcfung genehmigt.<\/li>\n<\/ol>\n<p>Dieser Workflow ist in der Industrie Standard, in der Forschung jedoch immer noch selten. Die Implementierung erh\u00f6ht die Softwarequalit\u00e4t dramatisch.<\/p>\n<h2>Fortgeschrittene Themen<\/h2>\n<h3>Matrixtest f\u00fcr mehrere Abh\u00e4ngigkeiten<\/h3>\n<p>Wissenschaftliche Pakete h\u00e4ngen oft von numpy\/scipy mit versionsspezifischem Verhalten ab. Testen Sie \u00fcber eine Matrix von Python- und Abh\u00e4ngigkeitsversionen:<\/p>\n<pre><code class=\"language-yaml\">strategy:\n  matrix:\n    python-version: [\"3.9\", \"3.10\", \"3.11\"]\n    numpy-version: [\"1.24\", \"1.25\", \"1.26\"]\n<\/code><\/pre>\n<p>Installieren Sie die spezifische Numpy-Version im Schritt <code>Install dependencies<\/code>:<\/p>\n<pre><code class=\"language-yaml\">    - run: |\n        pip install \"numpy==${{ matrix.numpy-version }}\" scipy\n<\/code><\/pre>\n<p>Damit werden Kompatibilit\u00e4tsprobleme fr\u00fchzeitig behoben.<\/p>\n<h3>Leistungsregressionserkennung<\/h3>\n<p>Verwenden Sie <a href=\"https:\/\/asv.readthedocs.io\/\">ASV<\/a>, um die Leistung im Laufe der Zeit zu verfolgen:<\/p>\n<pre><code class=\"language-yaml\">    - name: Run benchmarks\n      run: |\n        asv run --quick --show-stderr\n      # asv compares against previous commits and reports regressions\n<\/code><\/pre>\n<p>Konfigurieren Sie ASV so, dass der CI-Job fehlschl\u00e4gt, wenn ein Benchmark &gt;10% langsamer als der vorherige Lauf ist. Weitere Informationen finden Sie in <a href=\"https:\/\/pythonspeed.com\/articles\/speed-unit-tests\/\"> Pythonspeeds Artikel<\/a>.<\/p>\n<h3>Kontinuierliche Bereitstellung der Dokumentation<\/h3>\n<p>CI kann die Dokumentation automatisch auf GitHub-Seiten bereitstellen:<\/p>\n<pre><code class=\"language-yaml\">  deploy-docs:\n    needs: test  # Only run after tests pass\n    runs-on: ubuntu-latest\n    steps:\n    - uses: actions\/checkout@v4\n    - run: pip install -r requirements-docs.txt\n    - run: sphinx-build -b html docs\/ public\/\n    - uses: peaceiris\/actions-gh-pages@v3\n      with:\n        github_token: ${{ secrets.GITHUB_TOKEN }}\n        publish_dir: .\/public\n<\/code><\/pre>\n<p>Dadurch wird die Dokumentation mit Code\u00e4nderungen synchronisiert.<\/p>\n<h2>Verwandte Anleitungen<\/h2>\n<ul>\n<li><strong> <a href=\"https:\/\/matforge.org\/reproducibility-and-its-role-in-debugging\/\"> Reproduzierbarkeit und ihre Rolle beim Debuggen <\/a> <\/strong> - Wie Reproduzierbarkeitspraktiken die Debugging-Effizienz verbessern.<\/li>\n<li><strong><a href=\"https:\/\/matforge.org\/tracking-long-term-technical-debt-in-research-software\/\">Nachverfolgung langfristiger technischer Schulden in Forschungssoftware<\/a><\/strong> \u2013 Verwaltung der Codequalit\u00e4t im Laufe der Zeit; CI hilft, neue Schulden zu verhindern.<\/li>\n<li><strong><a href=\"https:\/\/matforge.org\/managing-research-software-through-tickets\/\">Verwalten von Forschungssoftware durch Tickets<\/a><\/strong> \u2013 Integration von CI in Issue-Tracking-Workflows.<\/li>\n<li><strong><a href=\"https:\/\/matforge.org\/why-issue-tracking-is-critical-in-scientific-projects\/\">Warum das Issue-Tracking in wissenschaftlichen Projekten von entscheidender Bedeutung ist<\/a><\/strong> \u2013 Verst\u00e4ndnis der Bedeutung der Issue-Tracking in wissenschaftlicher Software Entwicklung.<\/li>\n<li><strong><a href=\"https:\/\/matforge.org\/collaboration-between-developers-and-researchers-turning-innovation-into-scalable-impact\/\">Kollaboration zwischen Entwicklern und Forschern<\/a><\/strong> \u2013 Innovation durch effektive Teamarbeit in skalierbare Wirkung umwandeln.<\/li>\n<\/ul>\n<h2>Zusammenfassung und n\u00e4chste Schritte<\/h2>\n<p>Continuous Integration verwandelt Forschungssoftware aus fragilen, undokumentierten Skripten in zuverl\u00e4ssige, wartbare Assets. Die Kernschritte sind:<\/p>\n<ol>\n<li>Schreiben Sie mit PyTest automatisierte Tests mit <code>pytest.approx<\/code> f\u00fcr numerische Vergleiche.<\/li>\n<li>Richten Sie eine CI-Pipeline (GitHub-Aktionen oder GitLab CI) ein, die bei jeder Push- und Pull-Anforderung ausgef\u00fchrt wird.<\/li>\n<li>Verwenden Sie Docker oder Conda, um die Konsistenz der Umgebung zwischen CI und Entwicklung sicherzustellen.<\/li>\n<li>F\u00fcgen Sie Berichterstattungsberichterstattung, Fusting und Dokumentationserstellung hinzu.<\/li>\n<li>\u00dcberwachen Sie die Leistung mit Benchmarks, um Regressionen abzufangen.<\/li>\n<li>Integrieren Sie CI in Ihre bestehenden Prozesse zur Problemverfolgung und Code\u00fcberpr\u00fcfung.<\/li>\n<\/ol>\n<p><strong>Sofortaktionen<\/strong>:<\/p>\n<ul>\n<li>Wenn Sie keine Tests haben, schreiben Sie zun\u00e4chst einige f\u00fcr die kritischsten Funktionen. Sogar 20% Deckung ist besser als keine.<\/li>\n<li>Erstellen Sie eine grundlegende CI-Konfigurationsdatei (<code>.github\/workflows\/ci.yml<\/code> wie oben gezeigt) und iterieren Sie.<\/li>\n<li>Beheben Sie flockige Tests sofort - sie untergraben das Vertrauen.<\/li>\n<li>F\u00fcgen Sie Ihrer Readme ein \"Badge\" hinzu, das den CI-Status anzeigt (z. B. <img src=\"https:\/\/img.shields.io\/badge\/CI-passing-green\" alt=\"ci\">).<\/li>\n<\/ul>\n<p><strong>Wann sucht Beratung<\/strong>: Wenn es sich bei Ihrem Projekt um komplexe Abh\u00e4ngigkeiten (MPI, GPU-Code, propriet\u00e4re Bibliotheken) oder um 10.000 Codezeilen handelt, sollten Sie eine professionelle \u00dcberpr\u00fcfung Ihres CI-Setups in Betracht ziehen. Wir bieten <a href=\"\/category\/issue-tracking-tickets-technical-requests\/\"> benutzerdefinierte CI \/ CD-Implementierungsdienste <\/a> f\u00fcr Forschungsteams an.<\/p>\n<h2>Referenzen und Weiterlesen<\/h2>\n<ul>\n<li>Wilson, G. et al. (2012). <a href=\"https:\/\/www.ee.columbia.edu\/~dpwe\/e6891\/resources\/1210.0530v3.pdf\"> Best Practices for Scientific Computing <\/a>. <em> PLOS-Biologie <\/em>.<\/li>\n<li>Boettiger, C. (2015). <a href=\"https:\/\/polaris.imag.fr\/arnaud.legrand\/research\/readings\/acm_sigops_si_rsea\/p71-boettiger.pdf\">Eine Einf\u00fchrung in Docker f\u00fcr Reproduzierbare Forschung <\/a>. <em>ACM Sigops <\/em>.<\/li>\n<li>Waller, J. et al. (2015). <a href=\"https:\/\/oceanrep.geomar.de\/28433\/1\/SEN2015.pdf\">Einschlie\u00dflich Leistungs-Benchmarks in die kontinuierliche Integration<\/a>. <em>Sean <\/em>.<\/li>\n<li><a href=\"https:\/\/imperialcollegelondon.github.io\/ci-best-practice\/\"> Kontinuierliche Integration f\u00fcr Forschungssoftware <\/a> - Best Practices-Leitfaden f\u00fcr Imperial College London.<\/li>\n<li><a href=\"https:\/\/docs.github.com\/actions\/guides\/building-and-testing-python\"> GitHub-Aktionen: Erstellen und Testen von Python <\/a> - Offizielle Dokumentation.<\/li>\n<li><a href=\"https:\/\/github.com\/swcarpentry\/good-enough-practices-in-scientific-computing\">Gut genug Praktiken im wissenschaftlichen Rechnen <\/a> - Software-Schreinerarbeiten.<\/li>\n<\/ul>\n<hr>\n<p><strong>Wortanzahl<\/strong>: ~2,200<br> <strong>Lesezeit<\/strong>: ~10 Minuten<br> <strong>Zielpublikum<\/strong>: Forscher, Doktoranden und Entwickler, die an wissenschaftlichen Python-Projekten arbeiten, die eine zuverl\u00e4ssige, automatisierte Qualit\u00e4t etablieren m\u00fcssen Zusicherung<\/p>\n"},"excerpt":{"rendered":"<p><span class=\"span-reading-time rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">Reading Time: <\/span> <span class=\"rt-time\"> 11<\/span> <span class=\"rt-label rt-postfix\">minutes<\/span><\/span>Continuous Integration (CI) erstellt, testet und validiert den Forschungscode automatisch bei jedem Commit. F\u00fcr wissenschaftliche Software ist CI f\u00fcr die Reproduzierbarkeit, die fr\u00fchzeitige Fehlererkennung und die Aufrechterhaltung der Qualit\u00e4t im Laufe der Zeit unerl\u00e4sslich. Implementieren Sie CI durch: (1) Schreiben automatisierter Tests mit PyTest, (2) Einrichten einer CI-Pipeline mit GitHub-Aktionen oder GitLab CI, (3) Verwenden [&hellip;]<\/p>\n","protected":false,"raw":""},"author":4,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_locale":"de_DE","_original_post":"https:\/\/matforge.org\/?p=240","iawp_total_views":0,"footnotes":""},"categories":[3],"tags":[],"class_list":["post-837","post","type-post","status-publish","format-standard","hentry","category-issue-tracking-tickets-technical-requests","de-DE"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Kontinuierliche Integration f\u00fcr Forschungssoftware: Automatisiertes Testen und Validieren - matforge.org<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/matforge.org\/de\/continuous-integration-research-software-automated-testing-validation\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Kontinuierliche Integration f\u00fcr Forschungssoftware: Automatisiertes Testen und Validieren - matforge.org\" \/>\n<meta property=\"og:description\" content=\"Reading Time:  11 minutesContinuous Integration (CI) erstellt, testet und validiert den Forschungscode automatisch bei jedem Commit. F\u00fcr wissenschaftliche Software ist CI f\u00fcr die Reproduzierbarkeit, die fr\u00fchzeitige Fehlererkennung und die Aufrechterhaltung der Qualit\u00e4t im Laufe der Zeit unerl\u00e4sslich. Implementieren Sie CI durch: (1) Schreiben automatisierter Tests mit PyTest, (2) Einrichten einer CI-Pipeline mit GitHub-Aktionen oder GitLab CI, (3) Verwenden [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/matforge.org\/de\/continuous-integration-research-software-automated-testing-validation\/\" \/>\n<meta property=\"og:site_name\" content=\"matforge.org\" \/>\n<meta property=\"article:published_time\" content=\"2026-07-30T12:22:28+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/img.shields.io\/badge\/CI-passing-green\" \/>\n<meta name=\"author\" content=\"Priya Nair\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Verfasst von\" \/>\n\t<meta name=\"twitter:data1\" content=\"Priya Nair\" \/>\n\t<meta name=\"twitter:label2\" content=\"Gesch\u00e4tzte Lesezeit\" \/>\n\t<meta name=\"twitter:data2\" content=\"16\u00a0Minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/matforge.org\\\/de\\\/continuous-integration-research-software-automated-testing-validation\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/matforge.org\\\/de\\\/continuous-integration-research-software-automated-testing-validation\\\/\"},\"author\":{\"name\":\"Priya Nair\",\"@id\":\"https:\\\/\\\/matforge.org\\\/#\\\/schema\\\/person\\\/2effd7bc155a5e6357f31dac970c5795\"},\"headline\":\"Kontinuierliche Integration f\u00fcr Forschungssoftware: Automatisiertes Testen und Validieren\",\"datePublished\":\"2026-07-30T12:22:28+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/matforge.org\\\/de\\\/continuous-integration-research-software-automated-testing-validation\\\/\"},\"wordCount\":2775,\"commentCount\":0,\"image\":{\"@id\":\"https:\\\/\\\/matforge.org\\\/de\\\/continuous-integration-research-software-automated-testing-validation\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/img.shields.io\\\/badge\\\/CI-passing-green\",\"articleSection\":[\"Issue Tracking, Tickets & amp; Technische Anfragen\"],\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/matforge.org\\\/de\\\/continuous-integration-research-software-automated-testing-validation\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/matforge.org\\\/de\\\/continuous-integration-research-software-automated-testing-validation\\\/\",\"url\":\"https:\\\/\\\/matforge.org\\\/de\\\/continuous-integration-research-software-automated-testing-validation\\\/\",\"name\":\"Kontinuierliche Integration f\u00fcr Forschungssoftware: Automatisiertes Testen und Validieren - matforge.org\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/matforge.org\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/matforge.org\\\/de\\\/continuous-integration-research-software-automated-testing-validation\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/matforge.org\\\/de\\\/continuous-integration-research-software-automated-testing-validation\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/img.shields.io\\\/badge\\\/CI-passing-green\",\"datePublished\":\"2026-07-30T12:22:28+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/matforge.org\\\/#\\\/schema\\\/person\\\/2effd7bc155a5e6357f31dac970c5795\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/matforge.org\\\/de\\\/continuous-integration-research-software-automated-testing-validation\\\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/matforge.org\\\/de\\\/continuous-integration-research-software-automated-testing-validation\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/matforge.org\\\/de\\\/continuous-integration-research-software-automated-testing-validation\\\/#primaryimage\",\"url\":\"https:\\\/\\\/img.shields.io\\\/badge\\\/CI-passing-green\",\"contentUrl\":\"https:\\\/\\\/img.shields.io\\\/badge\\\/CI-passing-green\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/matforge.org\\\/de\\\/continuous-integration-research-software-automated-testing-validation\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/matforge.org\\\/de\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Kontinuierliche Integration f\u00fcr Forschungssoftware: Automatisiertes Testen und Validieren\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/matforge.org\\\/#website\",\"url\":\"https:\\\/\\\/matforge.org\\\/\",\"name\":\"matforge.org\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/matforge.org\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"de\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/matforge.org\\\/#\\\/schema\\\/person\\\/2effd7bc155a5e6357f31dac970c5795\",\"name\":\"Priya Nair\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/f11e168d4cd2f1eff83cbb851d6cff42d81d88bb59d8831ee77468aa4a5eea88?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/f11e168d4cd2f1eff83cbb851d6cff42d81d88bb59d8831ee77468aa4a5eea88?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/f11e168d4cd2f1eff83cbb851d6cff42d81d88bb59d8831ee77468aa4a5eea88?s=96&d=mm&r=g\",\"caption\":\"Priya Nair\"},\"sameAs\":[\"http:\\\/\\\/matforge.org\"],\"url\":\"https:\\\/\\\/matforge.org\\\/author\\\/priya-nair\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Kontinuierliche Integration f\u00fcr Forschungssoftware: Automatisiertes Testen und Validieren - matforge.org","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/matforge.org\/de\/continuous-integration-research-software-automated-testing-validation\/","og_locale":"de_DE","og_type":"article","og_title":"Kontinuierliche Integration f\u00fcr Forschungssoftware: Automatisiertes Testen und Validieren - matforge.org","og_description":"Reading Time:  11 minutesContinuous Integration (CI) erstellt, testet und validiert den Forschungscode automatisch bei jedem Commit. F\u00fcr wissenschaftliche Software ist CI f\u00fcr die Reproduzierbarkeit, die fr\u00fchzeitige Fehlererkennung und die Aufrechterhaltung der Qualit\u00e4t im Laufe der Zeit unerl\u00e4sslich. Implementieren Sie CI durch: (1) Schreiben automatisierter Tests mit PyTest, (2) Einrichten einer CI-Pipeline mit GitHub-Aktionen oder GitLab CI, (3) Verwenden [&hellip;]","og_url":"https:\/\/matforge.org\/de\/continuous-integration-research-software-automated-testing-validation\/","og_site_name":"matforge.org","article_published_time":"2026-07-30T12:22:28+00:00","og_image":[{"url":"https:\/\/img.shields.io\/badge\/CI-passing-green","type":"","width":"","height":""}],"author":"Priya Nair","twitter_card":"summary_large_image","twitter_misc":{"Verfasst von":"Priya Nair","Gesch\u00e4tzte Lesezeit":"16\u00a0Minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/matforge.org\/de\/continuous-integration-research-software-automated-testing-validation\/#article","isPartOf":{"@id":"https:\/\/matforge.org\/de\/continuous-integration-research-software-automated-testing-validation\/"},"author":{"name":"Priya Nair","@id":"https:\/\/matforge.org\/#\/schema\/person\/2effd7bc155a5e6357f31dac970c5795"},"headline":"Kontinuierliche Integration f\u00fcr Forschungssoftware: Automatisiertes Testen und Validieren","datePublished":"2026-07-30T12:22:28+00:00","mainEntityOfPage":{"@id":"https:\/\/matforge.org\/de\/continuous-integration-research-software-automated-testing-validation\/"},"wordCount":2775,"commentCount":0,"image":{"@id":"https:\/\/matforge.org\/de\/continuous-integration-research-software-automated-testing-validation\/#primaryimage"},"thumbnailUrl":"https:\/\/img.shields.io\/badge\/CI-passing-green","articleSection":["Issue Tracking, Tickets & amp; Technische Anfragen"],"inLanguage":"de","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/matforge.org\/de\/continuous-integration-research-software-automated-testing-validation\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/matforge.org\/de\/continuous-integration-research-software-automated-testing-validation\/","url":"https:\/\/matforge.org\/de\/continuous-integration-research-software-automated-testing-validation\/","name":"Kontinuierliche Integration f\u00fcr Forschungssoftware: Automatisiertes Testen und Validieren - matforge.org","isPartOf":{"@id":"https:\/\/matforge.org\/#website"},"primaryImageOfPage":{"@id":"https:\/\/matforge.org\/de\/continuous-integration-research-software-automated-testing-validation\/#primaryimage"},"image":{"@id":"https:\/\/matforge.org\/de\/continuous-integration-research-software-automated-testing-validation\/#primaryimage"},"thumbnailUrl":"https:\/\/img.shields.io\/badge\/CI-passing-green","datePublished":"2026-07-30T12:22:28+00:00","author":{"@id":"https:\/\/matforge.org\/#\/schema\/person\/2effd7bc155a5e6357f31dac970c5795"},"breadcrumb":{"@id":"https:\/\/matforge.org\/de\/continuous-integration-research-software-automated-testing-validation\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/matforge.org\/de\/continuous-integration-research-software-automated-testing-validation\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/matforge.org\/de\/continuous-integration-research-software-automated-testing-validation\/#primaryimage","url":"https:\/\/img.shields.io\/badge\/CI-passing-green","contentUrl":"https:\/\/img.shields.io\/badge\/CI-passing-green"},{"@type":"BreadcrumbList","@id":"https:\/\/matforge.org\/de\/continuous-integration-research-software-automated-testing-validation\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/matforge.org\/de\/"},{"@type":"ListItem","position":2,"name":"Kontinuierliche Integration f\u00fcr Forschungssoftware: Automatisiertes Testen und Validieren"}]},{"@type":"WebSite","@id":"https:\/\/matforge.org\/#website","url":"https:\/\/matforge.org\/","name":"matforge.org","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/matforge.org\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"de"},{"@type":"Person","@id":"https:\/\/matforge.org\/#\/schema\/person\/2effd7bc155a5e6357f31dac970c5795","name":"Priya Nair","image":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/secure.gravatar.com\/avatar\/f11e168d4cd2f1eff83cbb851d6cff42d81d88bb59d8831ee77468aa4a5eea88?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/f11e168d4cd2f1eff83cbb851d6cff42d81d88bb59d8831ee77468aa4a5eea88?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/f11e168d4cd2f1eff83cbb851d6cff42d81d88bb59d8831ee77468aa4a5eea88?s=96&d=mm&r=g","caption":"Priya Nair"},"sameAs":["http:\/\/matforge.org"],"url":"https:\/\/matforge.org\/author\/priya-nair\/"}]}},"_links":{"self":[{"href":"https:\/\/matforge.org\/wp-json\/wp\/v2\/posts\/837","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/matforge.org\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/matforge.org\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/matforge.org\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/matforge.org\/wp-json\/wp\/v2\/comments?post=837"}],"version-history":[{"count":1,"href":"https:\/\/matforge.org\/wp-json\/wp\/v2\/posts\/837\/revisions"}],"predecessor-version":[{"id":971,"href":"https:\/\/matforge.org\/wp-json\/wp\/v2\/posts\/837\/revisions\/971"}],"wp:attachment":[{"href":"https:\/\/matforge.org\/wp-json\/wp\/v2\/media?parent=837"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/matforge.org\/wp-json\/wp\/v2\/categories?post=837"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/matforge.org\/wp-json\/wp\/v2\/tags?post=837"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}