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?

1voto

magallanes Punkte 6033

Ich habe das Konzept des Einheitstests nie verstanden, aber jetzt weiß ich, was das Ziel ist.

Ein Unit Test ist kein vollständiger Test . Es ist also kein Ersatz für QA und manuelle Tests. Das Konzept von TDD ist in dieser Hinsicht falsch, da man nicht alles testen kann, einschließlich privater Methoden, aber auch Methoden, die Ressourcen verwenden (insbesondere Ressourcen, über die wir keine Kontrolle haben). TDD stützt seine Qualität auf etwas, das nicht erreicht werden kann.

Ein Unit-Test ist eher ein Pivot-Test Sie markieren einen beliebigen Drehpunkt, und das Ergebnis des Drehpunkts sollte dasselbe bleiben.

1voto

tkruse Punkte 9304

Public vs. Private ist keine nützliche Unterscheidung für welche Apis von Ihren Tests aufgerufen werden sollen, ebenso wenig wie Methode vs. Klasse. Die meisten testbaren Einheiten sind in einem Kontext sichtbar, aber in anderen verborgen.

Was zählt, sind Deckung und Kosten. Sie müssen die Kosten minimieren und gleichzeitig die Abdeckungsziele Ihres Projekts erreichen (Zeile, Zweig, Pfad, Block, Methode, Klasse, Äquivalenzklasse, Anwendungsfall... was immer das Team entscheidet).

Verwenden Sie also Tools, um die Abdeckung sicherzustellen, und entwerfen Sie Ihre Tests so, dass sie möglichst wenig Kosten verursachen (kurz und langfristig ).

Machen Sie die Tests nicht teurer als nötig. Wenn es am billigsten ist, nur öffentliche Zugangspunkte zu testen, tun Sie das. Wenn es am günstigsten ist, private Methoden zu testen, tun Sie das.

Wenn Sie mehr Erfahrung haben,

1voto

Andy Punkte 19

Wenn ich feststelle, dass die private Methode groß oder komplex oder wichtig genug ist, um eigene Tests zu erfordern, füge ich sie einfach in eine andere Klasse ein und mache sie dort öffentlich (Method Object). Dann kann ich die zuvor private und nun öffentliche Methode, die nun in einer eigenen Klasse lebt, problemlos testen.

0voto

Supun Wijerathne Punkte 10926

Ein wichtiger Punkt ist

Wenn wir testen, um die Korrektheit der Logik sicherzustellen, und eine private Methode eine Logik trägt, sollten wir sie testen. Oder etwa nicht? Warum lassen wir das also aus?

Das Schreiben von Tests auf der Grundlage der Sichtbarkeit von Methoden ist eine völlig irrelevante Idee.

Umgekehrt

Auf der anderen Seite ist der Aufruf einer privaten Methode außerhalb der ursprünglichen Klasse ein großes Problem. Außerdem gibt es in einigen Mocking-Tools Einschränkungen für das Mocking einer privaten Methode. (Bsp: Mockito )

Es gibt zwar einige Tools wie Power Mock die das unterstützt, ist es eine gefährliche Operation. Der Grund dafür ist, dass es die JVM hacken muss, um das zu erreichen.

Ein möglicher Ausweg ist (Wenn Sie Testfälle für private Methoden schreiben wollen)

Erklären Sie die privat Methoden wie geschützt . In manchen Situationen ist dies jedoch nicht sinnvoll.

0voto

unflores Punkte 1584

Die Antwort auf die Frage "Sollte ich private Methoden testen?" lautet "....... manchmal". Normalerweise sollten Sie gegen die Schnittstelle Ihrer Klassen testen.

  • Einer der Gründe dafür ist, dass man für ein Feature keine doppelte Abdeckung braucht.
  • Ein weiterer Grund ist, dass Sie, wenn Sie private Methoden ändern, jeden Test für diese Methoden aktualisieren müssen, auch wenn sich die Schnittstelle Ihres Objekts nicht geändert hat.

Hier ist ein Beispiel:

class Thing
  def some_string
    one + two
  end

  private 

  def one
    'aaaa'
  end

  def two
    'bbbb'
  end

end

class RefactoredThing
def some_string
    one + one_a + two + two_b
  end

  private 

  def one
    'aa'
  end

  def one_a
    'aa'
  end

  def two
    'bb'
  end

  def two_b
    'bb'
  end
end

RefactoredThing Sie haben jetzt 5 Tests, von denen Sie 2 für das Refactoring aktualisieren mussten, aber die Funktionalität Ihres Objekts hat sich nicht wirklich geändert. Nehmen wir an, die Dinge sind komplexer als das und Sie haben eine Methode, die die Reihenfolge der Ausgabe definiert, wie z. B.:

def some_string_positioner
  if some case
  elsif other case
  elsif other case
  elsif other case
  else one more case
  end
end

Dies sollte nicht von einem externen Benutzer ausgeführt werden, aber Ihre kapselnde Klasse kann zu schwer sein, um so viel Logik immer und immer wieder durchlaufen zu lassen. In diesem Fall vielleicht würden Sie eher extrahieren Sie diese in eine separate Klasse, geben Sie dieser Klasse eine Schnittstelle und testen gegen sie.

Und schließlich, nehmen wir an, Ihr Hauptobjekt ist superschwer, und die Methode ist ziemlich klein, und Sie müssen wirklich sicherstellen, dass die Ausgabe korrekt ist. Sie denken: "Ich muss diese private Methode testen!". Haben Sie daran gedacht, dass Sie Ihr Objekt vielleicht leichter machen können, indem Sie einen Teil der schweren Arbeit als Initialisierungsparameter übergeben? Dann können Sie etwas Leichteres übergeben und dagegen testen.

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