ホームページ >バックエンド開発 >Python チュートリアル >テスト駆動開発 (TDD) を使用した文字列計算機の構築: ステップバイステップ ガイド

テスト駆動開発 (TDD) を使用した文字列計算機の構築: ステップバイステップ ガイド

Barbara Streisand
Barbara Streisandオリジナル
2025-01-15 18:09:48923ブラウズ

Building a String Calculator with Test-Driven Development (TDD): A Step-by-Step Guide

テスト駆動開発 (TDD) アプローチを使用して、Python で文字列計算機を実装します。これは、対応する機能を実装する前に、各機能のテストを作成することを意味します。

TDD 実装のチェックポイントとして、リンク https://osherove.com/tdd-kata-1 を参照できます。リンクには、従うことができる段階的な手順が記載されています。

はじめる

プロジェクト フォルダーに、string_calculator.py と testing/test_string_calculator.py の 2 つのファイルを作成します。機能を段階的に実装していきます。まず、add メソッドを使用して StringCalculator クラスを作成する必要があります。

ステップ 1: 空の文字列は「0」を返す必要があります

unittest ライブラリを使用して、アプリケーションの最初のテストを作成しましょう。 testing/test_string_calculator.py ファイルを開き、次のコードから始めます:

import unittest
from string_calculator import StringCalculator

class TestStringCalculator(unittest.TestCase):
    """Test suite for the StringCalculator class."""

    def setUp(self):
        """
        Create a new instance of StringCalculator for each test.
        Can use static method to avoid creating a new instance.
        """
        self.calculator = StringCalculator()

    def test_empty_string_returns_zero(self):
        """
        Test case: Adding an empty string should return 0.
        Input: "" 
        Expected Output: 0
        """
        self.assertEqual(self.calculator.add(""), 0)

次に、string_calculator.py ファイルに StringCalculator クラスを実装しましょう。

class StringCalculator:
    def add(self, numbers:str):
        if not numbers:
            return 0

テストを実行するには、次の手順に従います:

  1. string_calculator.py および testing/test_string_calculator.py ファイルが配置されているプロジェクト ディレクトリにいることを確認してください。

  2. ターミナルまたはコマンド プロンプトを開きます。

  3. 次のコマンドを実行してテストを実行します:

python -m unittest discover tests

このコマンドは、tests フォルダー内のすべてのテストを自動的に検出して実行します。

期待される出力:

テストに合格すると、次のような内容が表示されるはずです。


----------------------------------------------------------------------
Ran 1 test in 0.001s

OK

すべてが正しく設定され、テスト ケースに合格した場合、空の文字列を処理する実装が期待どおりに動作していることを意味します。

ステップ 2: 1 つまたは 2 つの数値を加算すると、その合計が返されるはずです

入力文字列に数値が 1 つまたは 2 つしかない場合を処理できるようにメソッドを更新する必要があり、それらの合計を返す必要があります。空の文字列の場合、メソッドは 0 を返す必要があります。

テストを書く

tests/test_string_calculator.py ファイルを開き、すべてのシナリオをカバーする次のテスト ケースを追加します。

    def test_add_single_number(self):
        """
        Test case: Adding a single number should return the number itself.
        Input: "1"
        Expected Output: 1
        """
        self.assertEqual(self.calculator.add("1"), 1)

    def test_add_two_numbers(self):
        """
        Test case: Adding two numbers should return their sum.
        Input: "1,2"
        Expected Output: 3
        """
        self.assertEqual(self.calculator.add("1,2"),3)

コードの実装

ここで、string_calculator.py ファイルの add メソッドを更新して、1 つまたは 2 つの数値の加算を処理します。

class StringCalculator:
    def add(self, numbers:str):
        if not numbers:
            return 0
        '''
        Split the string by commas, convert each value to an integer, 
        and sum them up
        '''
        numbers_list = map(int,numbers.split(',')) 
        return sum(numbers_list)

前の手順に従ってコードを再度テストできます。

ステップ 3 : 複数の番号の処理

メソッドがカンマで区切られた複数の数値を処理できるかどうかを確認するテスト ケースを作成します。

テストを書く

tests/test_string_calculator.py ファイルを開き、複数の数値を処理するテスト ケースを追加します。

import unittest
from string_calculator import StringCalculator

class TestStringCalculator(unittest.TestCase):
    """Test suite for the StringCalculator class."""

    def setUp(self):
        """
        Create a new instance of StringCalculator for each test.
        Can use static method to avoid creating a new instance.
        """
        self.calculator = StringCalculator()

    def test_empty_string_returns_zero(self):
        """
        Test case: Adding an empty string should return 0.
        Input: "" 
        Expected Output: 0
        """
        self.assertEqual(self.calculator.add(""), 0)

機能はすでに実装されているため、コードのテストに進み、次のステップに進むことができます。

ステップ 4: 数値間の改行の処理

ここで、コンマに加えて、新しい行 (n) を数値間の有効な区切り文字として処理できるように add メソッドを強化する必要があります。

テストを書く

tests/test_string_calculator.py ファイルを開き、メソッドが改行を区切り文字として正しく処理するかどうかを確認するテスト ケースを追加します。

class StringCalculator:
    def add(self, numbers:str):
        if not numbers:
            return 0

コードの実装

次に、string_calculator.py ファイルの add メソッドを更新して、改行 (n) を区切り文字として処理します。 n をカンマに置き換えて文字列をカンマで分割するようにメソッドを変更できます。

add メソッドの更新されたコードは次のとおりです:

python -m unittest discover tests

step1 で定義されている前の手順に従って、コードを再度テストできます。

ステップ 5: カスタム区切り文字の処理

このステップでは、カスタム区切り文字を使用できるように機能をさらに強化します。たとえば、ユーザーは文字列の先頭にカスタム区切り文字を指定できる必要があります。例:

  • 入力文字列は // で始まり、その後にカスタム区切り文字が続きます。たとえば、//;n1;2;3 は 6 を返す必要があります。
  • //;n1;2;3 のような区切り文字をサポートします。

テストを書く

tests/test_string_calculator.py ファイルを開き、カスタム区切り文字機能を処理するテスト ケースを追加します。


----------------------------------------------------------------------
Ran 1 test in 0.001s

OK

コードの実装

カスタム区切り文字を処理するには、入力文字列で区切り文字を検索するように add メソッドを更新します。区切り文字は、文字列の先頭の //.

の後に指定する必要があります。

更新された追加メソッドは次のとおりです:

    def test_add_single_number(self):
        """
        Test case: Adding a single number should return the number itself.
        Input: "1"
        Expected Output: 1
        """
        self.assertEqual(self.calculator.add("1"), 1)

    def test_add_two_numbers(self):
        """
        Test case: Adding two numbers should return their sum.
        Input: "1,2"
        Expected Output: 3
        """
        self.assertEqual(self.calculator.add("1,2"),3)

ステップ 6: 負の数の処理

このステップでは、負の数を処理できるように add メソッドを変更する必要があります。負の数値が渡された場合は、「負の値は許可されません」というメッセージを含む例外をスローし、渡された負の数値を含める必要があります。

テストを書く

tests/test_string_calculator.py ファイルを開き、負の数の例外を処理するテスト ケースを追加します。

class StringCalculator:
    def add(self, numbers:str):
        if not numbers:
            return 0
        '''
        Split the string by commas, convert each value to an integer, 
        and sum them up
        '''
        numbers_list = map(int,numbers.split(',')) 
        return sum(numbers_list)

コードの実装

ここで、負の数値をチェックし、適切なメッセージで ValueError を発生させるように add メソッドを変更します。

更新された追加メソッドは次のとおりです:

def test_add_multiple_numbers(self):
    """
    Test case: Adding multiple numbers should return their sum.
    Input: "1,2,3,4,5"
    Expected Output: 15
    """
    self.assertEqual(self.calculator.add("1,2,3,4,5"), 15)

ステップ 7: Add メソッド呼び出しのカウント

このステップでは、add() メソッドが呼び出された回数を返す GetCalledCount() というメソッドを StringCalculator クラスに追加します。最初に失敗するテストを作成し、次に機能を実装するという TDD プロセスに従います。

テストを書く

まず、GetCalledCount() メソッドのテスト ケースを追加します。このテストでは、メソッドが add() の呼び出し回数を正しくカウントしていることを確認する必要があります。

tests/test_string_calculator.py ファイルを開き、次のテストを追加します:

import unittest
from string_calculator import StringCalculator

class TestStringCalculator(unittest.TestCase):
    """Test suite for the StringCalculator class."""

    def setUp(self):
        """
        Create a new instance of StringCalculator for each test.
        Can use static method to avoid creating a new instance.
        """
        self.calculator = StringCalculator()

    def test_empty_string_returns_zero(self):
        """
        Test case: Adding an empty string should return 0.
        Input: "" 
        Expected Output: 0
        """
        self.assertEqual(self.calculator.add(""), 0)

コードの実装

次に、StringCalculator クラスに GetCalledCount() メソッドを実装します。このメソッドは、add() が呼び出された回数を追跡する必要があります。

更新された StringCalculator クラスは次のとおりです:

class StringCalculator:
    def add(self, numbers:str):
        if not numbers:
            return 0

ステップ 8 と 9: 1000 を超える数値を無視し、任意の長さのカスタム区切り文字を処理する

このステップでは、次の 2 つの要件を実装します。

  1. 合計では 1000 を超える数値は無視されます。
  2. カスタム区切り文字は //[delimiter]n の形式で任意の長さにすることができ、メソッドはそれらを処理する必要があります。

最初にこれらの要件の両方に対するテストを作成し、次に StringCalculator クラスに機能を実装します。

テストを書く

1000 を超える数値の無視と、任意の長さのカスタム区切り文字の処理の両方について、次のテストを追加します。 testing/test_string_calculator.py ファイルを開き、以下を追加します:

python -m unittest discover tests

コードの実装

次に、StringCalculator クラスに機能を実装します。これには以下が含まれます:

  1. 1000 を超える数値は無視されます。
  2. 任意の長さのカスタム区切り文字を処理します。

更新された StringCalculator クラスは次のとおりです:


----------------------------------------------------------------------
Ran 1 test in 0.001s

OK

ステップ 10: 複数の区切り文字のサポート

このステップでは、任意の長さの複数の区切り文字をサポートするように add() メソッドを変更します。これにより、//[delimiter1][delimiter2]n.

の形式で複数の区切り文字がある場合を処理できるようになります。

テストを書く

まず、複数の区切り文字をチェックするテスト ケースを追加します。 testing/test_string_calculator.py ファイルを開き、次のテストを追加します:

    def test_add_single_number(self):
        """
        Test case: Adding a single number should return the number itself.
        Input: "1"
        Expected Output: 1
        """
        self.assertEqual(self.calculator.add("1"), 1)

    def test_add_two_numbers(self):
        """
        Test case: Adding two numbers should return their sum.
        Input: "1,2"
        Expected Output: 3
        """
        self.assertEqual(self.calculator.add("1,2"),3)

コードの実装

次に、複数の区切り文字を処理できるように add() メソッドを変更します。区切り文字は [] 内で渡され、//[delimiter1][delimiter2]n.

形式での複数の区切り文字の処理をサポートする必要があります。

これをサポートするために更新された StringCalculator クラスは次のとおりです。

class StringCalculator:
    def add(self, numbers:str):
        if not numbers:
            return 0
        '''
        Split the string by commas, convert each value to an integer, 
        and sum them up
        '''
        numbers_list = map(int,numbers.split(',')) 
        return sum(numbers_list)

テストしてみる

テストを再度実行して、古い形式との下位互換性や新しい複数区切り文字形式のサポートなど、すべてが機能することを確認します。

def test_add_multiple_numbers(self):
    """
    Test case: Adding multiple numbers should return their sum.
    Input: "1,2,3,4,5"
    Expected Output: 15
    """
    self.assertEqual(self.calculator.add("1,2,3,4,5"), 15)

期待される出力

古い形式と新しい形式の両方でテストに合格する必要があります:

def test_add_numbers_with_newlines(self):
    """
    Test case: Adding numbers separated by newlines should return their sum.
    Input: "1\n2\n3"
    Expected Output: 6
    """
    self.assertEqual(self.calculator.add("1\n2\n3"), 6)

この TDD シリーズをフォローしていただきありがとうございます!お役に立てば幸いです。

以上がテスト駆動開発 (TDD) を使用した文字列計算機の構築: ステップバイステップ ガイドの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。