410 Stimmen

Sollte ich private Methoden oder nur öffentliche Methoden testen?

Ich habe gelesen diese Stelle darüber, wie man private Methoden testet. Ich teste sie normalerweise nicht, weil ich immer dachte, dass es schneller ist, nur öffentliche Methoden zu testen, die von außerhalb des Objekts aufgerufen werden. Testen Sie private Methoden? Sollte ich sie immer testen?

6voto

fernandezdavid7 Punkte 61

Sie sollten nicht . Wenn Ihre privaten Methoden so komplex sind, dass sie getestet werden müssen, sollten Sie sie einer anderen Klasse zuordnen. Behalten Sie hohe Kohäsion Eine Klasse sollte nur einen Zweck haben. Die öffentliche Schnittstelle der Klasse sollte ausreichend sein.

3voto

Billy Jo Punkte 1287

Wenn Sie Ihre privaten Methoden nicht testen, woher wissen Sie dann, dass sie nicht kaputt gehen?

3voto

Colm Bhandal Punkte 2364

Ja, Sie sollten private Methoden testen, wo immer dies möglich ist. Warum? Zur Vermeidung einer unnötigen Zustandsraumexplosion von Testfällen, die letztendlich nur dazu führen, dass dieselben privaten Funktionen wiederholt auf dieselben Eingaben getestet werden. Lassen Sie uns anhand eines Beispiels erklären, warum.

Betrachten Sie das folgende, leicht erfundene Beispiel. Nehmen wir an, wir wollen eine Funktion öffentlich zugänglich machen, die 3 ganze Zahlen annimmt und nur dann true zurückgibt, wenn diese 3 ganzen Zahlen alle Primzahlen sind. Wir könnten sie wie folgt implementieren:

public bool allPrime(int a, int b, int c)
{
  return andAll(isPrime(a), isPrime(b), isPrime(c))
}

private bool andAll(bool... boolArray)
{
  foreach (bool b in boolArray)
  {
    if(b == false) return false;
  }
  return true;
}

private bool isPrime(int x){
  //Implementation to go here. Sorry if you were expecting a prime sieve.
}

Wenn wir nun den strikten Ansatz verfolgen würden, dass nur öffentliche Funktionen getestet werden sollten, dürften wir nur testen allPrime und nicht isPrime o andAll .

Als Prüfer sind wir vielleicht an fünf Möglichkeiten für jedes Argument interessiert: < 0 , = 0 , = 1 , prime > 1 , not prime > 1 . Aber um gründlich zu sein, müssten wir auch sehen, wie jede Kombination der Argumente zusammenspielt. Das ist also 5*5*5 = 125 Testfälle, die wir brauchen, um diese Funktion gründlich zu testen, so unsere Intuition.

Wäre es uns hingegen erlaubt, die privaten Funktionen zu testen, könnten wir mit weniger Testfällen genauso viel Fläche abdecken. Wir bräuchten nur 5 Testfälle, um zu testen isPrime auf die gleiche Ebene wie unsere bisherige Intuition. Und durch die Hypothese des geringen Umfangs Daniel Jackson vorgeschlagen hat, bräuchten wir nur die andAll Funktion bis zu einer kleinen Länge, z. B. 3 oder 4. Das wären dann höchstens 16 weitere Tests. Insgesamt also 21 Tests. Anstelle von 125. Natürlich würden wir wahrscheinlich einen wenige Tests zu allPrime aber wir würden uns nicht so verpflichtet fühlen, alle 125 Kombinationen von Eingabeszenarien, die uns wichtig sind, erschöpfend zu behandeln. Nur ein paar glückliche Wege.

Das Beispiel ist sicher etwas konstruiert, aber es war notwendig, um es zu verdeutlichen. Und das Muster lässt sich auf echte Software übertragen. Private Funktionen sind in der Regel die Bausteine der untersten Ebene und werden daher oft miteinander kombiniert, um Logik auf höherer Ebene zu erhalten. Das bedeutet, dass es auf höheren Ebenen aufgrund der verschiedenen Kombinationen mehr Wiederholungen von Elementen der unteren Ebene gibt.

3voto

Olivier Pichon Punkte 213

Ich verstehe den Standpunkt, dass private Methoden als Implementierungsdetails betrachtet werden und daher nicht getestet werden müssen. Und ich würde mich an diese Regel halten, wenn wir nur außerhalb des Objekts entwickeln müssten. Aber wir, sind wir eine Art eingeschränkte Entwickler, die nur außerhalb von Objekten entwickeln und nur deren öffentliche Methoden aufrufen? Oder entwickeln wir tatsächlich auch das Objekt? Da wir nicht verpflichtet sind, außerhalb von Objekten zu programmieren, müssen wir wahrscheinlich diese privaten Methoden in neuen öffentlichen Methoden, die wir entwickeln, aufrufen. Wäre es nicht großartig, zu wissen, dass die private Methode allen Widrigkeiten zum Trotz standhält?

Ich weiß, dass einige Leute antworten könnten, dass, wenn wir eine weitere öffentliche Methode für dieses Objekt entwickeln, diese getestet werden sollte und das war's (die private Methode könnte ohne Test weiterleben). Aber das gilt auch für alle öffentlichen Methoden eines Objekts: Bei der Entwicklung einer Webanwendung werden alle öffentlichen Methoden eines Objekts von Controllermethoden aufgerufen und können daher als Implementierungsdetails für Controller betrachtet werden.

Warum also testen wir Objekte in der Einheit? Weil es wirklich schwierig, um nicht zu sagen unmöglich ist, sicher zu sein, dass wir die Methoden des Controllers mit den richtigen Eingaben testen, die alle Verzweigungen des zugrunde liegenden Codes auslösen werden. Mit anderen Worten: Je höher wir im Stack sind, desto schwieriger ist es, das gesamte Verhalten zu testen. Das Gleiche gilt für private Methoden.

Für mich ist die Grenze zwischen privaten und öffentlichen Methoden ein psychologisches Kriterium, wenn es um Tests geht. Kriterien, die für mich wichtiger sind, sind:

  • wird die Methode mehr als einmal von verschiedenen Stellen aus aufgerufen?
  • Ist die Methode so anspruchsvoll, dass Tests erforderlich sind?

2voto

dvorak Punkte 29751

Das hängt natürlich von der Sprache ab. In der Vergangenheit habe ich in C++ die Testklasse zu einer Freundesklasse erklärt. Leider erfordert dies, dass Ihr Produktionscode von der Testklasse weiß.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X