Unit-Testing-Wettbewerb

12

Meine Arbeitgeber veranstalten monatlich einen Unit-Testing-Wettbewerb. Ein ganzer Tag ist dem Verfassen von Unit-Tests gewidmet - natürlich machen wir im Laufe des Monats mehr Tests, aber dies ist ein ganzer Tag - und der "Gewinner" des Wettbewerbs erhält einen Preis. Wir stellen jedoch fest, dass es schwierig ist festzustellen, wer der Gewinner ist.

Wir haben für jeden Testfall Punkte vergeben. Also, wenn Sie einen Unit-Test wie diesen geschrieben haben ...

for (int i = 0; i < 100; i++) {
  assertTrue(i*i, square(i));
}

Sie würden 100 Punkte gegeben. Dies ist natürlich ein vereinfachtes Beispiel, aber es zeigt die Probleme bei der Zuweisung von "Punkten" für jeden Testfall.

Wir sind hauptsächlich ein Java- und Javascript-Shop. Also schlug ich vor, die Anzahl der getesteten Code-Zweige als Metrik zu zählen. Wir können die mit einem Code-Coverage-Tool (wie EclEmma) getesteten Zweige leicht zählen. Wir sind uns jedoch nicht sicher, wie wir dies mit unseren Selenium-Tests und einer Codeabdeckung der Javascript-Quellen tun würden (irgendwelche Ideen?)

Hat jemand Vorschläge, wie wir den Gewinner dieses Wettbewerbs besser bestimmen können?

Bearbeiten

Ich weiß, wie man Komponententests schreibt, ich weiß, wie man effektive Komponententests schreibt, ich brauche keine Hilfe, um zu bestimmen, was zu testen ist. Ich habe keine Kontrolle über diesen Wettbewerb - der Wettbewerb wird fortgesetzt. Also füge ich entweder etwas Input hinzu, um es besser zu machen, oder spiele die Tests weiter (ja, ich spiele sie. Natürlich spiele ich sie. Es gibt Preise zu gewinnen)

Bearbeiten

Diese Frage hier ist offensichtlich kein Duplikat, obwohl sie nützliche Informationen zum Auffinden guter Testfälle enthält, enthält sie keine nützlichen Metriken zum Bewerten der Konkurrenz.

Shaun
quelle
Nicht ganz. Ich habe es von Anfang an erkannt
Shaun,
2
Sie scheinen das ganze Ausmaß noch nicht zu realisieren. Jedes Maß, das angibt , wer die besten Testfälle geschrieben hat, ist entweder vollständig subjektiv oder weist diese Probleme zu einem gewissen Grad auf. Welche Metrik am besten funktioniert, hängt von Ihren Zielen für diese Wettbewerbe ab und davon, wie ausgereift (dh wahrscheinlich nicht, dass Sie die Wertung ausnutzen, anstatt die bestmöglichen Tests zu schreiben) die Teilnehmer sind.
Wieder nein. Mir wurde klar, dass sie gespielt werden können. Ich habe keine Kontrolle über diesen Wettbewerb, wurde aber gefragt: "Wie können wir das besser machen
Shaun,
13
Wäre es eine Verbesserung, es nicht zu einem Wettbewerb zu machen? Warum muss alles ein Wettbewerb sein? Warum kannst du nicht zusammenarbeiten? Vielleicht wäre es hilfreich, einige Ihrer sinnloseren Komponententests loszuwerden und eine Reihe nützlicher Rauch- und Regressionstests zu erstellen.
Thomas Owens
1
Ich bin bei Thomas ... der Gewinner sollte die Codebasis / der Kunde sein, da sich die Codequalität verbessert hat. Legen Sie ein Gesamt- / Gruppenziel fest, basierend auf der Codeabdeckung der Komponententests ... + 5% über dem aktuellen Wert oder was auch immer. ... und spielen Sie nicht das System für Preise ... was auch immer mit einer gut gemachten Arbeit passiert ist, ist seine eigene Belohnung?
JeffC

Antworten:

15

Hat jemand Vorschläge, wie wir den Gewinner dieses Wettbewerbs besser bestimmen können?

Das einzige, was für mich Sinn macht, ist die Abstimmung - jeder Entwickler kann dem Test jedes anderen Entwicklers (außer seinem eigenen) Punkte zuweisen. Vielleicht 3 Punkte für den Test, den er für den "effektivsten" hält, 2 Punkte für den zweiten und einen für den dritten. Der Test mit den meisten Punkten gewinnt. Es kann zu besseren Ergebnissen führen, wenn die Punktzuweisung durchgeführt wird, ohne vorher zu wissen, wer den jeweiligen Test geschrieben hat.

Als Bonus erhalten Sie alle Ihre Tests von Fachleuten überprüft.

Doc Brown
quelle
2
Das war auch mein Gedanke. Es gibt keine andere Möglichkeit, den Wert von Tests zu messen.
Eric King
2
Ja, "gute Tests" sind eine subjektive Sache, die von Gleichaltrigen oder angesehenen Behörden beurteilt werden muss. Das Verfolgen von Metriken wird nur zu viel verschwendetem Aufwand und wenig echtem Wert führen. Es könnte interessant sein, mehrere Preise zu erhalten: den einfallsreichsten Test, eine Auszeichnung, die als "Testen von etwas, das zuvor als nicht testbar galt", den besten Leistungstest, den effektivsten Test, den dunkelsten Test, den klügsten Test, den wertvollsten Test, den Endbenutzer mit größter Wahrscheinlichkeit zu schätzen wissen ...
2.
6

Also, wenn Sie einen Unit-Test wie diesen geschrieben haben ...

for (int i = 0; i < 100; i++) {
 assertTrue(i*i, square(i));
}

Sie würden 100 Punkte gegeben.

Ich würde dieser Person 0 Punkte geben (selbst wenn der Test etwas wirklich Relevantes testen würde), da Aussagen innerhalb einer Schleife wenig Sinn machen und Tests mit mehreren Aussagen (insbesondere in Form einer Schleife oder einer Karte) schwierig zu bearbeiten sind.

Das Problem ist im Wesentlichen, eine Metrik zu haben, die nicht [leicht] betrogen werden kann. Eine Metrik, die ausschließlich auf der Anzahl der Asserts basiert, entspricht genau der Anzahl der Entwickler pro geschriebenem LOC. Wie bei Pay-by-LOC, das zu umfangreichem und unmöglich zu wartendem Code führt, führt Ihre tatsächliche Unternehmensrichtlinie zu nutzlosen und möglicherweise schlecht geschriebenen Tests.

Ist die Anzahl der Asserts irrelevant, ist auch die Anzahl der Tests irrelevant. Dies gilt auch für viele Metriken (einschließlich kombinierter), die man sich für diese Art von Situationen vorstellen kann.

Idealerweise würden Sie einen systemischen Ansatz anwenden. In der Praxis kann dies in den meisten Softwareentwicklungsunternehmen kaum funktionieren. Also kann ich ein paar andere Dinge vorschlagen:

  1. Mit Paar Bewertungen für Tests und haben etwas Ähnliches wie die Anzahl der WTFs pro Minute Metrik.

  2. Messen Sie die Auswirkung dieser Tests über die Zeit auf die Anzahl der Fehler . Dies hat mehrere Vorteile:

    • Scheint fair zu sein,
    • Kann tatsächlich gemessen werden, wenn Sie genügend Daten über Fehlerberichte und deren Schicksal sammeln.
    • Lohnt sich eigentlich!
  3. Verwenden Sie die Zweigabdeckung , aber kombinieren Sie sie mit anderen Metriken (sowie einer Überprüfung). Branchendeckung hat seine Vorteile, aber das Testen von CRUD-Code, um eine bessere Note zu erhalten, ist nicht die beste Möglichkeit, die Zeit der Entwickler zu verbringen.

  4. Entscheiden Sie gemeinsam, welche Metriken Sie im Moment erzwingen möchten (solche Entscheidungen sind in einigen Unternehmen und Teams möglicherweise nicht erwünscht oder sogar möglich). Überprüfen und ändern Sie die Metriken häufig, indem Sie diejenigen auswählen, die relevanter werden, und stellen Sie sicher, dass jeder klar versteht, was und wie gemessen wird.

Arseni Mourzenko
quelle
1
+1 für Nullpunkte. Andere Einwände wären AAA - Arrangieren, Handeln, Durchsetzen; Parametrisierte Tests; Nein Kopieren von Code der Implementierung ...
thepacker
5

Ich nehme an, Ihr Arbeitgeber organisiert diesen Unit-Test-Tag, um Ihren Mitarbeitern Anreize zu bieten, Fehler zu finden, eine bessere Codeabdeckung zu erzielen und am Ende mehr Tests durchzuführen, die für immer von Nutzen sind.

Ich würde also denken, dass es Sinn macht, dass der Gewinner der Entwickler ist, der die meisten Fehler findet, oder der Entwickler, dessen Tests die größte Zunahme der Codeabdeckung erzielen.

Ein Test würde Ihnen einen Punkt einbringen, wenn er dazu führt, dass ein neuer Eintrag in Ihrem Problem- / Fehler- / Fehlerverfolgungssystem geöffnet wird. Wenn für dieses Problem bereits ein Eintrag geöffnet ist, zählt dieser nicht. Wie in den Kommentaren vorgeschlagen, zählen auch Fehler in Ihrem eigenen Code nicht; Nur Fehler im Code anderer Personen sollten zählen. Leider liefert dieser Ansatz keine sofortige Befriedigung, da es einige Tage dauern kann, bis alle fehlgeschlagenen Tests durchgesehen und die entsprechenden Probleme gelöst sind. Dies funktioniert möglicherweise nicht immer. Wenn Ihr System älter wird, kann es äußerst selten werden, Fehler durch Hinzufügen von Tests zu entdecken.

Die Erhöhung der Codeabdeckung könnte eine objektivere Messung der durch die neuen Tests dargestellten Verbesserung ermöglichen. Zunächst muss die gesamte Code-Abdeckung am Tag vor dem Wettbewerb aufgezeichnet werden. Dann muss jeder Entwickler die Zunahme der Codeabdeckung, die sich allein aus seinen Tests ergibt, irgendwie nachweisen, ohne die Zunahme der Codeabdeckung zu berücksichtigen, die sich aus Tests ergibt, die von anderen Entwicklern geschrieben wurden. Dies bedeutet, dass Sie wahrscheinlich einen Schiedsrichter benötigen, der zu jedem Entwicklercomputer geht und die neue Codeabdeckung aufzeichnet, bevor die Tests von jemandem durchgeführt werden.

Im Übrigen bietet die Berücksichtigung der Codeabdeckung denjenigen, die echte Tests schreiben, eine angemessene Belohnung, anstatt dumme Dinge wie das Beispiel zu tun, das Sie in der Frage angegeben haben.

Mike Nakis
quelle
2
Hört sich vielversprechend an, aber dann wird aus dem Verhalten des "Spielens im System" eine schöne Sammlung von Bugs, die nur Ihnen bekannt sind und beim nächsten Testwettbewerb
timday
3
Eine Möglichkeit besteht darin, nur Punkte für Fehler im Code zu vergeben, die von einer anderen Person geschrieben wurden.
Cel Skeggs
@ col6y du hast recht, das ist auch ganz wichtig. Leider gibt es immer noch Möglichkeiten, das System zu manipulieren. Wenn Ihr Code beispielsweise meinen Code aufruft, um seine Aufgabe zu erledigen, könnte mein Code dafür sorgen, dass Ihr Code einen "Unfall" erleidet.
Mike Nakis
3
Ich stimme dir nicht zu. Unit-Tests, wenn sie neu geschrieben wurden, dienen nicht dazu, Fehler zu finden , das ist ein Trugschluss. Sie können Regressionen Wochen oder Monate nach dem Verfassen finden, aber das ist höchstwahrscheinlich zu spät, um nützliche Messdaten für den Wettbewerb bereitzustellen. In der Regel schreiben Sie einen Komponententest, nachdem ein bestimmter Fehler aufgetreten ist, um sicherzustellen, dass Sie später in Zukunft nicht denselben Fehlertyp erhalten.
Doc Brown