Android Coden
Android 7 min lesen

Fehler- und Aufgabenverfolgung in Android-Projekten

Gute Issues machen Bugs, Aufgaben und Releases nachvollziehbar. Du lernst, wie Kontext, Repro-Schritte und Akzeptanzkriterien helfen.

Fehler- und Aufgabenverfolgung hilft dir, Android-Arbeit so zu beschreiben, dass andere sie verstehen, prüfen und abschließen können. In echten Projekten reicht es nicht, im Chat zu schreiben, dass „der Login kaputt“ ist. Du brauchst ein Issue, das Kontext, Repro-Schritte und klare Akzeptanzkriterien enthält, damit aus einer Beobachtung eine bearbeitbare Aufgabe im Backlog wird.

Was ist das?

Fehler- und Aufgabenverfolgung ist die strukturierte Verwaltung von Arbeit in Form von Issues. Ein Issue kann ein Bug, eine technische Aufgabe, eine Verbesserung, ein Release-Problem oder eine Analyse sein. Entscheidend ist nicht das Tool, sondern die Qualität der Beschreibung. Ob du Jira, GitHub Issues, Linear, YouTrack oder ein anderes System nutzt, ist zweitrangig. Wichtig ist: Das Issue muss erklären, was beobachtet wurde, warum es relevant ist, wie man es nachvollziehen kann und wann es als erledigt gilt.

Im Android-Kontext tauchen Issues überall auf. Ein Compose-Screen rendert nach einer Zustandsänderung falsch. Ein Flow sendet doppelte Werte. Ein ViewModel lädt Daten nicht neu, wenn der Nutzer den Account wechselt. Ein Crash tritt nur auf Android 14 auf. Ein Play-Release soll erst über einen internen Test-Track geprüft werden, bevor er breiter ausgerollt wird. All das sind keine losen Gedanken, sondern Arbeitspakete, die du sauber festhalten solltest.

Das mentale Modell für Einsteiger ist einfach: Ein Issue ist kein Tagebucheintrag und keine Schuldzuweisung. Es ist ein Vertrag über Verständnis. Die Person, die das Issue liest, soll ohne mühsames Nachfragen erkennen, worum es geht. Die Person, die es umsetzt, soll wissen, welche Schritte sinnvoll sind. Die Person, die es testet, soll prüfen können, ob die Arbeit abgeschlossen ist.

Der Backlog ist dabei die Sammlung dieser offenen Arbeit. Er enthält Bugs, Tasks und Verbesserungen, aber nicht alles ist gleich dringend. Ein Crash beim App-Start hat eine andere Priorität als eine kleine Textkorrektur in einem selten genutzten Dialog. Gute Fehler- und Aufgabenverfolgung macht diese Unterschiede sichtbar. Sie hilft Teams, Qualität, Architekturarbeit und Release-Ziele nicht nur im Kopf zu behalten, sondern planbar zu machen.

Wie funktioniert es?

Ein gutes Issue besteht aus wenigen, aber wichtigen Bausteinen. Der Titel fasst die Beobachtung präzise zusammen. Der Kontext erklärt, wo das Problem auftritt und warum es relevant ist. Die Repro-Schritte beschreiben, wie jemand den Zustand erneut herstellen kann. Das erwartete Verhalten sagt, was korrekt wäre. Das tatsächliche Verhalten beschreibt, was stattdessen passiert. Akzeptanzkriterien legen fest, wann die Aufgabe fertig ist.

Bei Android-Bugs gehören oft zusätzliche Daten dazu: App-Version, Build-Variante, Gerät, Android-Version, Sprache, Netzwerkzustand und gegebenenfalls ein Auszug aus Logcat oder Crashlytics. Wenn ein Problem nur im Release-Build auftritt, ist das ein wichtiger Hinweis. Wenn es nur nach einer Migration von Room-Daten passiert, gehört auch das ins Issue. Je genauer der Kontext ist, desto weniger Zeit geht beim Nachstellen verloren.

Akzeptanzkriterien sind besonders wichtig, weil sie aus einer vagen Aufgabe eine prüfbare Aufgabe machen. „Login verbessern“ ist unklar. „Wenn das Passwort falsch ist, zeigt der Login-Screen eine Fehlermeldung an, bleibt auf dem Screen und löscht das E-Mail-Feld nicht“ ist prüfbar. Du kannst daraus eine manuelle Testanweisung, einen Compose-UI-Test oder einen ViewModel-Test ableiten.

Im Alltag beginnt ein Issue oft mit einer Beobachtung. Du testest eine neue Compose-Funktion und merkst, dass ein Button nach einem Fehler dauerhaft deaktiviert bleibt. Statt sofort irgendwo Code zu ändern, formulierst du erst das Problem. Dadurch trennst du Beobachtung, Ursache und Lösung. Das ist eine wichtige Gewohnheit: Ein Issue darf eine vermutete Ursache enthalten, sollte sie aber nicht als Tatsache darstellen, wenn sie noch nicht geprüft wurde.

Ein brauchbarer Ablauf sieht so aus: Du erfasst das Issue, gibst ihm passende Labels wie bug, task, release oder backlog, ordnest es einer Priorität zu und verknüpfst es bei Bedarf mit einem Pull Request. Während der Umsetzung dokumentierst du Entscheidungen im PR oder im Issue. Nach der Umsetzung wird anhand der Akzeptanzkriterien geprüft. Erst dann wird das Issue geschlossen.

Auch Release-Arbeit profitiert davon. Die Play Console unterstützt verschiedene Release-Tracks, etwa interne Tests, geschlossene Tests, offene Tests und Produktion. Wenn ein Bug nur im internen Test auffällt, sollte das Issue klar festhalten, in welchem Track, mit welcher Version und unter welchen Bedingungen er gefunden wurde. So bleibt nachvollziehbar, ob ein Problem die Produktion blockiert oder zuerst in einem kleineren Testkreis geprüft werden kann.

In der Praxis

Stell dir vor, du arbeitest an einer Kotlin-App mit Jetpack Compose. Der Login-Screen nutzt ein ViewModel, das den Zustand über StateFlow bereitstellt. Beim Testen fällt auf: Wenn der Server einen Fehler zurückgibt, bleibt der Button „Anmelden“ deaktiviert. Ein schlechtes Issue wäre: „Login kaputt“. Damit kann zwar jemand raten, aber nicht gezielt arbeiten.

Ein deutlich besseres Issue wäre:

Titel: Login-Button bleibt nach Serverfehler deaktiviert

Kontext: Tritt im Login-Screen der Android-App auf. Beobachtet in Version 2.4.0, Debug-Build, Pixel 7, Android 15. Der Screen verwendet LoginViewModel und Compose-State aus einem StateFlow.

Repro-Schritte:

  1. App starten.
  2. Login-Screen öffnen.
  3. Gültige E-Mail und beliebiges Passwort eingeben.
  4. Netzwerkantwort mit HTTP 500 auslösen.
  5. Fehlermeldung abwarten.

Erwartetes Verhalten: Der Button wird nach der Fehlerantwort wieder aktiviert. Die E-Mail bleibt erhalten. Die Fehlermeldung ist sichtbar.

Tatsächliches Verhalten: Der Button bleibt deaktiviert. Ein neuer Login-Versuch ist erst nach Neustart des Screens möglich.

Akzeptanzkriterien:

  1. Nach einem Serverfehler ist der Login-Button wieder aktiv.
  2. Die Fehlermeldung bleibt sichtbar, bis der Nutzer die Eingabe ändert oder erneut sendet.
  3. Ein ViewModel-Test prüft den Übergang von Loading zu Error.
  4. Ein kurzer manueller Test im Debug-Build wurde durchgeführt.

Dazu passt ein kleines Code-Beispiel für die Art von Zustand, über die das Issue sprechen kann:

data class LoginUiState(
    val email: String = "",
    val password: String = "",
    val isLoading: Boolean = false,
    val errorMessage: String? = null
)

class LoginViewModel(
    private val authRepository: AuthRepository
) : ViewModel() {

    private val _uiState = MutableStateFlow(LoginUiState())
    val uiState: StateFlow<LoginUiState> = _uiState.asStateFlow()

    fun submit() {
        val current = _uiState.value

        viewModelScope.launch {
            _uiState.value = current.copy(
                isLoading = true,
                errorMessage = null
            )

            val result = authRepository.login(
                email = current.email,
                password = current.password
            )

            _uiState.value = result.fold(
                onSuccess = {
                    current.copy(isLoading = false)
                },
                onFailure = { error ->
                    current.copy(
                        isLoading = false,
                        errorMessage = error.message ?: "Anmeldung fehlgeschlagen"
                    )
                }
            )
        }
    }
}

Dieses Beispiel ist nicht als vollständige Architekturvorlage gedacht. Es zeigt, warum präzise Issues helfen: Du erkennst, welcher Zustand geprüft werden muss. Wenn das Issue nur „Button kaputt“ sagt, suchst du vielleicht im Compose-Layout. Wenn es den Übergang nach einem HTTP-500-Fehler beschreibt, schaust du eher auf ViewModel-Zustand, Repository-Rückgabe und Tests.

Eine praktische Entscheidungsregel: Wenn eine andere Person das Issue nicht ohne Rückfrage reproduzieren oder prüfen kann, ist es noch nicht bereit für die Umsetzung. Das bedeutet nicht, dass jedes Issue lang sein muss. Eine kleine Aufgabe darf kurz sein. Aber sie braucht genug Information für die nächste Handlung.

Typische Stolperfallen sind vage Titel, fehlende Versionen und vermischte Themen. Ein Issue mit dem Titel „Profil überarbeiten“ kann UI-Text, Ladeverhalten, Fehlerzustände und Navigation meinen. Besser ist es, daraus mehrere Aufgaben zu machen, wenn die Arbeit unterschiedliche Ursachen oder Akzeptanzkriterien hat. Ebenso problematisch sind Bugs ohne Repro-Schritte. Manchmal ist ein Fehler nicht stabil reproduzierbar. Dann schreibst du genau das: Wie oft trat er auf, welche Logs gibt es, welche Hypothesen wurden geprüft, welche Daten fehlen noch?

Eine weitere Falle ist die Lösung im Titel. „MutableStateFlow durch LiveData ersetzen“ beschreibt eine Maßnahme, aber nicht das Problem. Vielleicht ist der eigentliche Fehler ein falsch behandelter Ladezustand. Besser wäre: „Login-Zustand wird nach Fehlerantwort nicht zurückgesetzt“. Danach kann im Issue stehen, welche Lösungsideen es gibt. So bleibt das Team offen für eine bessere technische Entscheidung.

Bei Tasks ohne Bug gilt dasselbe Prinzip. Eine Aufgabe wie „Release für internen Test vorbereiten“ braucht ebenfalls Akzeptanzkriterien. Zum Beispiel: Versionsname ist erhöht, Release Notes sind eingetragen, Build wurde signiert, interner Test-Track ist ausgewählt, Smoke-Test wurde durchgeführt. Gerade bei Veröffentlichungen verhindert diese Klarheit, dass kleine Schritte vergessen werden.

Für Junior-Entwickler ist Issue Tracking auch ein Lernwerkzeug. Du lernst, Probleme in beobachtbares Verhalten zu zerlegen. Du lernst, Akzeptanzkriterien zu formulieren, die zu Tests passen. Du lernst, im Code-Review nicht nur über Code-Stil zu sprechen, sondern über die Frage: Löst dieser Pull Request das beschriebene Issue wirklich?

Fazit

Gute Fehler- und Aufgabenverfolgung macht Android-Entwicklung ruhiger und prüfbarer. Du beschreibst Bugs, Tasks und Backlog-Einträge so, dass Kontext, Repro-Schritte und Akzeptanzkriterien sichtbar sind. Übe das bewusst: Nimm einen echten Fehler aus deiner App, schreibe ein Issue mit erwarteten und tatsächlichen Ergebnissen, reproduziere ihn im Debugger oder mit Logcat, ergänze einen passenden Test und prüfe im Code-Review, ob die Änderung genau die Kriterien erfüllt.

Quellen (1)
Redaktion

Geschrieben von

Redaktion

Das Redaktionsteam recherchiert und schreibt Artikel zu aktuellen Themen rund um Tech, Lifestyle und Ratgeber.