我参加了一个TDD编码Dojo,我们尝试在简单问题上练习纯TDD。然而,我发现单元测试中出现的代码并不是最有效的。现在大多数情况下都没问题,但是如果代码使用量增加,那么效率就成了问题。如何通过单元测试产生高效的代码?
我喜欢代码从单元测试中出现的方式,但是有可能通过进一步的测试使效率属性出现吗?
这里是一个红宝石的例子:素因子分解。我遵循纯粹的TDD方法,使得测试一个接一个地验证我的原始验收测试(在底部注释)。 如果我想让generic prime factorization algorithms之一出现,我还能采取哪些步骤?为了减少问题领域,我们假设我想要实现一个quadratic sieve ...现在在这种精确的情况下,我知道“最优算法,但在大多数情况下,客户端只会添加一个要求, x”的时间,特定的环境。
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
和天真的算法,我创造了这个方法
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
编辑1从第一个答案来看,我想我并不清楚我的初始描述:性能测试是不是是我单元测试的一个标准部分,它是一个新验收测试编写回答特定要求从客户端。
编辑2我知道如何测试执行时间,但它似乎从简单的算法转移到优化的算法是一个巨大的步骤。我的问题是如何使最优代码emerge,换句话说:你如何分解从平凡代码到最优代码的迁移? 一些人提到这是一个问题的具体方法:我提供了一个示例问题,我不知道如何继续。
会很好,但无论设计正确的代码还是有效的代码,单元测试都不会显示出现的属性。一个给定的单元测试可以通过许多非常**不同的实现来满足。 – Ray 2010-04-14 01:18:24
如果你对Ruby感到满意,那么你根本不在意perf :-)如果你真的关心perf,那么你一定知道它必须通过为perf设计来实现,这意味着思考需要很长的时间并且很努力。这使得TDD成为了性能的致命的敌人 - 因为TDD旨在专注于“今天为我做了些什么”并缩短了交付时间。 – ZXX 2010-08-08 15:14:03
是不是“为perf设计”最终形式过早优化? :) 此外,我在例子中使用红宝石,因为它很容易阅读。这只是为了例子,而不是我的问题的对象。 – Jean 2010-08-08 17:57:10