Challenge 2: Write a View Test With the Test Client — Possible Solution ==================================================================== # catalog/tests.py from django.test import TestCase from .models import Author, Book class BookDetailViewTests(TestCase): def setUp(self): self.author = Author.objects.create(name="N.K. Jemisin") self.book = Book.objects.create( title="The Fifth Season", author=self.author, price=14.99, ) def test_book_detail_returns_200(self): response = self.client.get(f"/books/{self.book.pk}/") self.assertEqual(response.status_code, 200) def test_book_detail_uses_correct_template(self): response = self.client.get(f"/books/{self.book.pk}/") self.assertTemplateUsed(response, "catalog/book_detail.html") def test_book_detail_contains_title(self): response = self.client.get(f"/books/{self.book.pk}/") self.assertContains(response, "The Fifth Season") def test_book_detail_404_for_missing_book(self): response = self.client.get("/books/99999/") self.assertEqual(response.status_code, 404) WHY THIS WORKS -------------- - self.client.get(f"/books/{self.book.pk}/") builds the URL using the actual primary key of the book created in setUp() — using an f-string with self.book.pk (rather than a hardcoded "/books/1/") means the test keeps working even if Django's auto-incrementing IDs don't happen to start at 1 in a given test run. - assertTemplateUsed and assertContains check two DIFFERENT things that could each fail independently: assertTemplateUsed confirms the correct TEMPLATE rendered (catching a view that accidentally renders the wrong page while still returning 200), while assertContains confirms the actual page CONTENT includes the expected text — a view could use the right template but still fail to pass the right context data into it. - test_book_detail_404_for_missing_book uses a primary key (99999) that's extremely unlikely to exist, verifying the view correctly returns a 404 for a nonexistent book rather than crashing with an unhandled DoesNotExist exception — a common real bug when a view uses Book.objects.get(pk=book_id) directly instead of get_object_or_404(Book, pk=book_id).