Maison >développement back-end >Tutoriel Python >Création d'une calculatrice de chaînes avec le développement piloté par les tests (TDD) : un guide étape par étape
Nous implémenterons un calculateur de chaînes en Python en utilisant une approche de développement piloté par les tests (TDD). Cela signifie que nous écrirons des tests pour chaque fonctionnalité avant d'implémenter la fonctionnalité correspondante.
Vous pouvez vous référer au lien https://osherove.com/tdd-kata-1 comme points de contrôle pour la mise en œuvre de TDD. Le lien fournit des instructions étape par étape que vous pouvez suivre.
Dans votre dossier de projet, créez deux fichiers : string_calculator.py et tests/test_string_calculator.py. Nous mettrons en œuvre les fonctionnalités étape par étape. Tout d’abord, nous devons créer une classe StringCalculator avec une méthode add.
Écrivons le premier test de notre application en utilisant la bibliothèque unittest. Ouvrez le fichier tests/test_string_calculator.py et commencez avec le code suivant :
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)
Maintenant, implémentons la classe StringCalculator dans le fichier string_calculator.py :
class StringCalculator: def add(self, numbers:str): if not numbers: return 0
Pour exécuter les tests, suivez ces étapes :
Assurez-vous que vous êtes dans le répertoire du projet où se trouvent vos fichiers string_calculator.py et tests/test_string_calculator.py.
Ouvrez votre terminal ou votre invite de commande.
Exécutez la commande suivante pour exécuter les tests :
python -m unittest discover tests
Cette commande découvrira et exécutera automatiquement tous les tests dans le dossier tests.
Vous devriez voir quelque chose comme ceci si le test réussit :
---------------------------------------------------------------------- Ran 1 test in 0.001s OK
Si tout est configuré correctement et que le scénario de test réussit, cela signifie que votre implémentation pour gérer une chaîne vide fonctionne comme prévu.
Nous devons mettre à jour la méthode pour gérer le cas où il n'y a qu'un ou deux nombres dans la chaîne d'entrée, et elle doit renvoyer leur somme. Pour une chaîne vide, la méthode doit renvoyer 0.
Ouvrez le fichier tests/test_string_calculator.py et ajoutez les cas de test suivants pour couvrir tous les scénarios :
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)
Maintenant, mettez à jour la méthode add dans le fichier string_calculator.py pour gérer l'ajout d'un ou deux nombres :
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)
Vous pouvez tester à nouveau le code en suivant les étapes précédentes.
Nous allons écrire un cas de test pour vérifier si la méthode peut gérer plusieurs nombres séparés par des virgules.
Ouvrez le fichier tests/test_string_calculator.py et ajoutez un cas de test pour gérer plusieurs nombres :
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)
La fonctionnalité a déjà été implémentée, nous pouvons donc procéder au test du code puis passer à l'étape suivante.
Maintenant, nous devons améliorer la méthode add pour gérer les nouvelles lignes (n) comme séparateurs valides entre les nombres, en plus des virgules.
Ouvrez le fichier tests/test_string_calculator.py et ajoutez un scénario de test pour vérifier si la méthode gère correctement les nouvelles lignes comme séparateurs :
class StringCalculator: def add(self, numbers:str): if not numbers: return 0
Ensuite, mettez à jour la méthode add dans le fichier string_calculator.py pour gérer les nouvelles lignes (n) comme séparateurs. Nous pouvons modifier la méthode pour remplacer n par des virgules, puis diviser la chaîne par des virgules.
Voici le code mis à jour pour la méthode add :
python -m unittest discover tests
Vous pouvez tester à nouveau le code en suivant les étapes précédentes définies à l'étape 1.
Dans cette étape, nous améliorerons encore la fonctionnalité pour permettre des délimiteurs personnalisés. Par exemple, les utilisateurs devraient pouvoir spécifier un délimiteur personnalisé au début de la chaîne. Par exemple :
Ouvrez le fichier tests/test_string_calculator.py et ajoutez un scénario de test pour gérer la fonctionnalité de délimiteur personnalisé :
---------------------------------------------------------------------- Ran 1 test in 0.001s OK
Pour gérer les délimiteurs personnalisés, mettez à jour la méthode add pour rechercher le délimiteur dans la chaîne d'entrée. Le délimiteur doit être spécifié au début de la chaîne après //.
Voici la méthode d'ajout mise à jour :
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)
Dans cette étape, nous devons modifier la méthode add pour gérer les nombres négatifs. Lorsqu'un nombre négatif est transmis, il doit lever une exception avec le message « négatifs non autorisés » et inclure les nombres négatifs qui ont été transmis.
Ouvrez le fichier tests/test_string_calculator.py et ajoutez un scénario de test pour gérer l'exception de nombre négatif :
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)
Maintenant, modifiez la méthode add pour vérifier les nombres négatifs et déclenchez une ValueError avec le message approprié.
Voici la méthode d'ajout mise à jour :
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)
Dans cette étape, nous ajouterons une méthode appelée GetCalledCount() à la classe StringCalculator qui renverra combien de fois la méthode add() a été invoquée. Nous suivrons le processus TDD en écrivant d'abord un test ayant échoué, puis en implémentant la fonctionnalité.
Commencez par ajouter un scénario de test pour la méthode GetCalledCount(). Ce test doit vérifier que la méthode compte correctement le nombre de fois que add() est appelée.
Ouvrez le fichier tests/test_string_calculator.py et ajoutez le test suivant :
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)
Maintenant, implémentez la méthode GetCalledCount() dans la classe StringCalculator. Cette méthode devra garder une trace du nombre de fois que add() a été invoquée.
Voici la classe StringCalculator mise à jour :
class StringCalculator: def add(self, numbers:str): if not numbers: return 0
Dans cette étape, nous mettrons en œuvre deux exigences :
Nous allons d'abord écrire les tests pour ces deux exigences, puis implémenter la fonctionnalité dans la classe StringCalculator.
Ajoutez les tests suivants à la fois pour les nombres ignorés supérieurs à 1 000 et pour la gestion des délimiteurs personnalisés de n'importe quelle longueur. Ouvrez le fichier tests/test_string_calculator.py et ajoutez ce qui suit :
python -m unittest discover tests
Maintenant, implémentez la fonctionnalité dans la classe StringCalculator. Cela comprendra :
Voici la classe StringCalculator mise à jour :
---------------------------------------------------------------------- Ran 1 test in 0.001s OK
Dans cette étape, nous modifierons la méthode add() pour prendre en charge plusieurs délimiteurs de n'importe quelle longueur. Cela nous permettra de gérer les cas où il y a plusieurs délimiteurs au format //[delimiter1][delimiter2]n.
Commencez par ajouter un scénario de test pour vérifier plusieurs délimiteurs. Ouvrez le fichier tests/test_string_calculator.py et ajoutez le test suivant :
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)
Maintenant, modifiez la méthode add() pour gérer plusieurs délimiteurs. Les délimiteurs seront passés à l'intérieur de [], et nous devons prendre en charge la gestion de plusieurs délimiteurs au format //[delimiter1][delimiter2]n.
Voici la classe StringCalculator mise à jour pour prendre en charge cela :
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)
Relancez les tests pour vérifier que tout fonctionne, y compris la rétrocompatibilité avec l'ancien format et la prise en charge du nouveau format à délimiteurs multiples :
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)
Les tests doivent réussir pour les anciens et les nouveaux formats :
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)
Merci de suivre cette série TDD ! J'espère que vous l'avez trouvé utile.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!