Python

pythonによるTDD実践(6):素数列挙機能をTDDで作ってみよう最終回

前回までのコード


def enumerate_prime_number_under(n):
  prime_numbers = []
  for m in range(2, n):
    if is_prime_number(m) == True:
      prime_numbers.append(m)
    
  return prime_numbers


def is_prime_number(n):
  for m in range(2, n):
    if n % m == 0:
      return False
  
  return True

from tdd_prime.prime_enumerator import enumerate_prime_number_under, is_prime_number

def test_prime_enumeration():
  assert enumerate_prime_number_under(10) == [2, 3, 5, 7]

def test_prime_judge_true():
  assert is_prime_number(7) == True


def test_prime_judge_false():
  assert is_prime_number(14) == False

リファクタリング

前回までで、機能の実装を完了することができました。次にすべきことは、コードの設計や関数名の変更等を行うなどのリファクタリングとなります。これまでに用意したテストがあるため、変更によりコードが破壊されていないか確認しつつリファクタリングを行うことができます。enumerate_prime_number_underという名前は、長く、意味が掴みづらいため名前を変更して次のようなクラスにまとめます:



class PrimeEnumerator:
  def enumerate(self, upper_bound: int):
    prime_numbers = []
    for m in range(2, upper_bound):
      if is_prime_number(m) == True:
        prime_numbers.append(m)
    
    return prime_numbers

  def _is_prime_number(self, n):
    for m in range(2, n):
      if n % m == 0:
        return False
  
    return True

テストを実行すると、失敗します。関数のインターフェイスを変えたため、テストも変更する必要があります:


from tdd_prime.prime_enumerator import PrimeEnumerator

def test_prime_enumeration():
  assert PrimeEnumerator().enumerate(10) == [2, 3, 5, 7]

def test_prime_judge_true():
  assert PrimeEnumerator()._is_prime_number(7) == True


def test_prime_judge_false():
  assert PrimeEnumerator()._is_prime_number(14) == False

この変更で、テストが成功することが確認できます。このように、TDDを用いた開発では、まずは動くコードを書き、その後、動く状態を保ったままリファクタリングを行い、綺麗なコードに修正するといったステップで進みます。

まとめ

TDDには以下の利点があるとよく言われています:

  • テストから考えることで、実装したい機能の仕様を明確にした上で実装に着手できる
  • 細かいステップを確実に踏むことで、動くことが保証されたままでコードに変更を加えられる
  • テストしやすい作りにできる

一方で、各ステップをどのくらいの大きさにすべきかなど、考えるべきことは多いため、ほどほどにTDDを活用するのがちょうど良いと感じました。

D.S S.O
データサイエンティストのS.Oです。