Ich nehme an einem TDD Coding Dojo teil, wo wir versuchen, reines TDD an einfachen Problemen zu üben. Dabei ist mir aufgefallen, dass der Code, der aus den Unit-Tests hervorgeht, nicht der effizienteste ist. Das ist in den meisten Fällen in Ordnung, aber was ist, wenn der Codeverbrauch so wächst, dass die Effizienz zu einem Problem wird?
Ich liebe die Art und Weise der Code entsteht aus Unit-Tests, aber ist es möglich, die Effizienz Eigenschaft entstehen durch weitere Tests?
Hier ist ein triviales Beispiel in Ruby: Primfaktorzerlegung. Ich habe einen reinen TDD-Ansatz verfolgt, bei dem die Tests einen nach dem anderen bestanden haben und meinen ursprünglichen Akzeptanztest (unten kommentiert) validiert haben. Welche weiteren Schritte könnte ich unternehmen, wenn ich einen der Tests generische Algorithmen zur Primfaktorzerlegung auftauchen? Um den Problembereich einzugrenzen, sagen wir, ich möchte eine quadratisches Sieb Umsetzung ... In diesem konkreten Fall kenne ich den "optimalen Algorithmus", aber in den meisten Fällen wird der Kunde einfach eine Anforderung hinzufügen, dass die Funktion in einer bestimmten Umgebung in weniger als "x" Zeit läuft.
require 'shoulda'
require 'lib/prime'
class MathTest < Test::Unit::TestCase
context "The math module" do
should "have a method to get primes" do
assert Math.respond_to? 'primes'
end
end
context "The primes method of Math" do
should "return [] for 0" do
assert_equal [], Math.primes(0)
end
should "return [1] for 1 " do
assert_equal [1], Math.primes(1)
end
should "return [1,2] for 2" do
assert_equal [1,2], Math.primes(2)
end
should "return [1,3] for 3" do
assert_equal [1,3], Math.primes(3)
end
should "return [1,2] for 4" do
assert_equal [1,2,2], Math.primes(4)
end
should "return [1,5] for 5" do
assert_equal [1,5], Math.primes(5)
end
should "return [1,2,3] for 6" do
assert_equal [1,2,3], Math.primes(6)
end
should "return [1,3] for 9" do
assert_equal [1,3,3], Math.primes(9)
end
should "return [1,2,5] for 10" do
assert_equal [1,2,5], Math.primes(10)
end
end
# context "Functionnal Acceptance test 1" do
# context "the prime factors of 14101980 are 1,2,2,3,5,61,3853"do
# should "return [1,2,3,5,61,3853] for ${14101980*14101980}" do
# assert_equal [1,2,2,3,5,61,3853], Math.primes(14101980*14101980)
# end
# end
# end
end
und der naive Algorithmus, den ich mit diesem Ansatz entwickelt habe
module Math
def self.primes(n)
if n==0
return []
else
primes=[1]
for i in 2..n do
if n%i==0
while(n%i==0)
primes<<i
n=n/i
end
end
end
primes
end
end
end
bearbeiten 1 Nach den ersten Antworten zu urteilen, habe ich mich in meiner ursprünglichen Beschreibung wohl nicht klar ausgedrückt: Der Leistungstest ist nicht ein Standardbestandteil meines Einheitstests, es ist ein neue Abnahmeprüfung geschrieben als Antwort auf eine spezielle Anforderung vom Kunden.
bearbeiten 2 Ich weiß, wie man die Ausführungszeit testet, aber es scheint, dass der Übergang vom trivialen Algorithmus zum optimierten Algorithmus ein großer Schritt ist. auftauchen Oder anders ausgedrückt: Wie zerlegt man die Migration vom trivialen Code zum optimalen Code? Einige erwähnten, dass es sich um einen problemspezifischen Ansatz handelt: Ich habe ein Beispielproblem angegeben, bei dem ich nicht weiß, wie es weitergehen soll.