Files
chemenu/kb/concepts/Ambient Environment Dependency.md
T
torben 18ae28f918
CI / verify (push) Failing after 32s
Release / release (push) Successful in 38s
Chemenu 2.1.0 - deterministischer Wissenskompiler
Chemenu kompiliert Rohnotizen zu einem verlinkten, quellengebundenen Wiki:
raw/ -> types/ + tools/ -> kb/ -> reports/. Was mechanisch ist, macht
tools/wikitool; was Urteil braucht, macht ein Agent unter Contracts, deren
Grenzen in Code durchgesetzt sind statt im Prompt.

Dieser Commit ist der Startpunkt der oeffentlichen Historie. Die vorherige
Entwicklung fand in einer privaten Instanz statt und ist nicht Teil dieses
Repositorys; ihre Erzaehlung steht vollstaendig in CHANGES.md, das mit 44
Eintraegen von 0.1.0 bis 2.1.0 erhalten geblieben ist.

Der mitgelieferte Korpus ist ein Testbett und eine Demo: 170 Seiten ueber den
Stack selbst - Gates, Lint, Versionierung, Suche, das Wiki-Muster. Er
dokumentiert das Werkzeug mit den eigenen Mitteln des Werkzeugs.

Lizenz: AGPL-3.0 fuer den Stack (tools/, types/), CC-BY-4.0 fuer die Inhalte.
Die Grenze zwischen beiden ist der Dateiplan, den dist export berechnet -
siehe NOTICE.
2026-09-01 16:26:14 +02:00

7.7 KiB

type, concept_type, tags, created, modified, related, sources, confidence, confidence_base, provenance, summary
type concept_type tags created modified related sources confidence confidence_base provenance summary
types/concept.md problem
tests
ci
tooling
quality
2026-08-31 2026-08-31
Structural Enforcement over Documented Rule
Green Suite Blind Spot
wikitool
Gitea Actions
Source - Conversation - Hardening the Test Suite Against Silent Environment Dependencies Session 2026-08-31
0.50 0.50 sourced Fehlerklasse, in der ein Test gruen ist, weil die Maschine zufaellig passt statt weil der Code stimmt - abgegrenzt gegen den Green Suite Blind Spot, belegt an vier Faellen unter Gitea-Issue #8

Ambient Environment Dependency

Typ: Problem

Definition

Eine Ambient Environment Dependency liegt vor, wenn Code stillschweigend Zustand von der Maschine liest, auf der er läuft - Umgebungsvariablen, globale Konfigurationsdateien, das Home-Verzeichnis - und ein Testlauf grün wird, weil die Maschine zufällig passt statt weil der Code stimmt. Der grüne Lauf misst dann die Umgebung, nicht das Verhalten.

Das unterscheidet sich vom Green Suite Blind Spot an genau einer Stelle, und die ist entscheidend: dort behauptet kein Test das richtige Verhalten, hier behauptet ein Test es sehr wohl und ist grün - aus dem falschen Grund. Der blinde Fleck ist eine Lücke in der Abdeckung; die Umgebungsabhängigkeit ist ein Fehlbeleg innerhalb der Abdeckung. Beide sind gegen die Zahl grüner Tests immun, aber nur der zweite überlebt ein "das ist doch getestet".

Die Tücke ist der fehlende Widerstand. Ein Test mit dieser Abhängigkeit verhält sich beim Schreiben, beim Review und im nächsten hundert Läufen exakt wie ein korrekter Test. Sichtbar wird sie erst auf einer fremden Maschine - und wenn niemand die Suite je woanders startet, nie.

Kernpunkte

  • Der Beleg aus diesem Stack (Gitea-Issue #8). config.default_author() ruft git config user.name mit cwd=config.ROOT auf. Die Fixture-Wurzel ist kein Repository, also antwortete die globale git-Konfiguration desjenigen, der die Suite startete. Der erste CI-Lauf, der überhaupt bis pytest kam, meldete 2 failed, 628 passed; auf jeder Entwicklermaschine war dieselbe Suite monatelang grün gewesen1 .
  • Sie vermehrt sich schneller, als sie gefunden wird. Nach der Reparatur der ersten beiden Fälle führten zwei neue Tests dieselbe Abhängigkeit erneut ein - geschrieben von jemandem, der das Issue vorher gelesen hatte. Vier Fälle, zwei davon nach der Warnung1 . Das ist der Grund, warum ein Hinweis in einem Dokument hier nicht trägt; siehe Structural Enforcement over Documented Rule.
  • Die Abwesenheit von Fehlern beweist nichts über den Schutz. Vor der Härtung war die Suite unter leerem HOME und ohne git-Konfiguration bereits grün (695 Tests): die vier bekannten Fälle waren einzeln repariert, ein fünfter existierte gerade nicht1 . Ein Schutz braucht deshalb seinen eigenen Nachweis, unabhängig davon, dass nach seinem Einbau alles grün bleibt.
  • Der Nachweis führt über die Gegenprobe, nicht über den grünen Lauf. In der Sitzung ausgeführt: dieselbe Funktion antwortet ohne Isolierung 'Torben Nehmer' und mit Isolierung None1 . Erst das zeigt, dass die Isolierung etwas tut.
  • In beide Richtungen prüfen. Der übliche Gegentest ist die leere Maschine ("übersteht die Suite, nichts zu haben"). Der zweite ist die vergiftete Maschine ("übersteht sie, das Falsche zu haben"): Variablen absichtlich auf Müll setzen. Eine Isolierung, die nur auf einer ohnehin sauberen Maschine löscht, besteht den ersten Test und fällt beim zweiten durch.
  • Ein CI-Container ist kein verlässlicher Ersatz für Isolierung. Das Log von Run 79 zeigt, dass actions/checkout@v7 selbst eine globale git-Konfiguration im Container anlegt (Copying '/root/.gitconfig' to ..., Temporarily overriding HOME=...), und der Environment-Schritt schreibt safe.directory global dazu1 . Die Eigenschaft "Maschine ohne globale Konfiguration", auf der der ursprüngliche Fund beruhte, hatte der Container zufällig. Ein Guard, der sie voraussetzt, hört still auf zu greifen.
  • Das Gegenmittel setzt an der Ausführung an, nicht am einzelnen Test. Eine Isolierung, die vor jedem Test greift, macht die Abhängigkeit unschreibbar, statt sie zu melden. Ein Test, der Identität braucht, muss sie dann explizit herstellen - was er ohnehin tun sollte.
  • Wer isoliert, darf nicht das Verhalten mit-isolieren, das er prüfen will. Ein pauschal gesetzter Default (etwa eine Autor-Identität für alle Tests) macht genau den Zweig untestbar, der nur auf einer Maschine ohne Identität existiert. Die Suite sieht dann grüner aus und belegt weniger.
  • Die Isolierung selbst braucht Tests. Sonst kann sie eine Variable verlieren, ohne dass ein Lauf rot wird - dasselbe Versagen eine Ebene höher.

Beispiele

  • wikitool - default_author() las die globale git-Konfiguration des Aufrufers; vier Tests hingen nacheinander daran, gefunden erst durch den ersten CI-Lauf, der bis pytest kam
  • Gitea Actions - der Job-Container als vermeintlich neutrale Maschine, die es seit checkout@v7 nicht mehr ist
  • Green Suite Blind Spot - die verwandte Fehlerklasse, gegen die dieselbe Zahl grüner Tests ebenfalls nichts aussagt

Wann zu verwenden

  • Wenn ein Test auf einer fremden Maschine fällt, der lokal grün ist - die erste Frage ist nicht "was ist an der Maschine kaputt", sondern "was hat der Test von ihr gelesen".
  • Beim Schreiben eines Tests, der Identität, Pfade, Zeitzone, Locale oder Netzwerkzugang berührt: was davon kommt aus der Umgebung, und was stellt der Test selbst her.
  • Wenn ein grüner Lauf als Beleg für Korrektheit angeführt wird und die Suite bisher nur auf einer Sorte Maschine lief.
  • Bevor eine Suite an eine Stelle wandert, wo sie erstmals woanders läuft - CI, ein zweiter Entwickler, eine verteilte Instanz.

Wann NICHT zu verwenden

  • Für Tests, die die Umgebung absichtlich prüfen und sie dafür selbst aufbauen. Ein Test, der ein Fixture-Repository anlegt und darin eine lokale Identität setzt, hat keine Abhängigkeit - er hat ein Fixture.
  • Für Werte, die legitim von außen kommen und deren Abwesenheit sauber behandelt wird. Nicht jeder os.environ.get ist ein Defekt; der Defekt ist, wenn ein Testergebnis davon abhängt.
  • Als Argument gegen Integrationstests gegen echte Systeme. Die stützen sich bewusst auf eine Umgebung, und das ist deklariert - nicht still.

Verwandte Concepts

Beziehungen

Siehe auch

Fußnoten