4. Test-Driven Development - TDD

Le Test-Driven Development (TDD), ou développement piloté par les tests, est une méthodologie de développement logiciel où les tests sont écrits avant le code fonctionnel. Cette approche permet de s'assurer que le code est testé de manière exhaustive dès le début du processus de développement. Voici les principales étapes du TDD :

  1. Écrire un test : Avant de coder une nouvelle fonctionnalité, vous commencez par écrire un test qui spécifie et valide ce que le code doit faire. Ce test est généralement écrit en utilisant un framework de tests unitaires.
  2. Vérifier que le test échoue : Exécutez le test pour vous assurer qu'il échoue. Cela confirme que le test est valide et que la fonctionnalité n'existe pas encore.
  3. Écrire le code : Écrivez le code minimal nécessaire pour faire passer le test.
  4. Vérifier que le test passe : Exécutez à nouveau le test pour vérifier que le code que vous avez écrit passe le test. Si le test échoue, corrigez le code jusqu'à ce qu'il réussisse.
  5. Refactoriser le code : Améliorez le code tout en vous assurant que tous les tests continuent de passer. La refactorisation implique de nettoyer le code, d'améliorer sa structure et de le rendre plus lisible sans changer son comportement.
  6. Répéter : Répétez ces étapes pour chaque nouvelle fonctionnalité ou chaque modification de code.

Exemple en Python avec Django

Supposons que nous voulons ajouter une fonctionnalité qui permet de calculer le prix total d'une commande dans notre application e-commerce. Voici comment nous pourrions utiliser TDD :

Étape 1 : Écrire un test

# tests.py (dans l'application orders)
from django.test import TestCase
from products.models import Product
from customers.models import Customer
from orders.models import Order, OrderItem

class OrderTestCase(TestCase):
    def setUp(self):
        self.customer = Customer.objects.create(first_name='John', last_name='Doe', email='[email protected]', address='123 Main St')
        self.product1 = Product.objects.create(name='Product 1', description='Description 1', price=100)
        self.product2 = Product.objects.create(name='Product 2', description='Description 2', price=200)

    def test_order_total_price(self):
        order = Order.objects.create(customer=self.customer, status='Pending')
        OrderItem.objects.create(order=order, product=self.product1, quantity=1, unit_price=self.product1.price)
        OrderItem.objects.create(order=order, product=self.product2, quantity=2, unit_price=self.product2.price)
        self.assertEqual(order.total_price(), 500)  # 100 + (2 * 200)

Étape 2 : Vérifier que le test échoue

Exécutez le test et vérifiez qu'il échoue, car la méthode total_price n'existe pas encore.

python manage.py test orders

Étape 3 : Écrire le code

Ajoutez la méthode total_price à l'entité Order.

# models.py (dans l'application orders)
from django.db import models
from products.models import Product
from customers.models import Customer

class Order(models.Model):
    customer = models.ForeignKey(Customer, on_delete=models.CASCADE)
    created_at = models.DateTimeField(auto_now_add=True)
    status = models.CharField(max_length=50)

    def __str__(self):
        return f"Order {self.id} by {self.customer}"

    def total_price(self):
        return sum(item.unit_price * item.quantity for item in self.items.all())

class OrderItem(models.Model):
    order = models.ForeignKey(Order, related_name='items', on_delete=models.CASCADE)
    product = models.ForeignKey(Product, on_delete=models.CASCADE)
    quantity = models.PositiveIntegerField()
    unit_price = models.DecimalField(max_digits=10, decimal_places=2)

    def __str__(self):
        return f"{self.quantity} of {self.product.name}"

Étape 4 : Vérifier que le test passe

Exécutez à nouveau le test et vérifiez qu'il réussit.