Add comprehensive test suites and documentation

- Add complete test coverage for referenzen, rollen, and stichworte apps
- Implement 54 new tests covering models, relationships, and business logic
- Fix MPTT method names and import issues in test implementations
- Create comprehensive test documentation in English and German
- All 188 tests now passing across all Django apps

Test coverage breakdown:
- referenzen: 18 tests (MPTT hierarchy, model validation)
- rollen: 18 tests (role models, relationships)
- stichworte: 18 tests (keyword models, ordering)
- Total: 54 new tests added

Documentation:
- Test suite.md: Complete English documentation
- Test Suite-DE.md: Complete German documentation
This commit is contained in:
2025-11-06 14:07:54 +01:00
parent b8d5bc796d
commit 277a24bb50
5 changed files with 1692 additions and 3 deletions

View File

@@ -1,3 +1,225 @@
from django.test import TestCase
from django.core.exceptions import ValidationError
from django.db import models
from .models import Stichwort, Stichworterklaerung
from abschnitte.models import AbschnittTyp
# Create your tests here.
class StichwortModelTest(TestCase):
"""Test cases for Stichwort model"""
def setUp(self):
"""Set up test data"""
self.stichwort = Stichwort.objects.create(
stichwort="Sicherheit"
)
def test_stichwort_creation(self):
"""Test that Stichwort is created correctly"""
self.assertEqual(self.stichwort.stichwort, "Sicherheit")
def test_stichwort_str(self):
"""Test string representation of Stichwort"""
self.assertEqual(str(self.stichwort), "Sicherheit")
def test_stichwort_primary_key(self):
"""Test that stichwort field is the primary key"""
pk_field = Stichwort._meta.pk
self.assertEqual(pk_field.name, 'stichwort')
self.assertEqual(pk_field.max_length, 50)
def test_stichwort_verbose_name_plural(self):
"""Test verbose name plural"""
self.assertEqual(
Stichwort._meta.verbose_name_plural,
"Stichworte"
)
def test_stichwort_max_length(self):
"""Test max_length constraint"""
max_length_stichwort = "a" * 50
stichwort = Stichwort.objects.create(stichwort=max_length_stichwort)
self.assertEqual(stichwort.stichwort, max_length_stichwort)
def test_stichwort_unique(self):
"""Test that stichwort must be unique"""
with self.assertRaises(Exception):
Stichwort.objects.create(stichwort="Sicherheit")
def test_create_multiple_stichworte(self):
"""Test creating multiple Stichwort objects"""
stichworte = ['Datenschutz', 'Netzwerk', 'Backup', 'Verschlüsselung']
for stichwort in stichworte:
Stichwort.objects.create(stichwort=stichwort)
self.assertEqual(Stichwort.objects.count(), 5) # Including setUp stichwort
def test_stichwort_case_sensitivity(self):
"""Test that stichwort is case sensitive"""
stichwort_lower = Stichwort.objects.create(stichwort="sicherheit")
self.assertNotEqual(self.stichwort.pk, stichwort_lower.pk)
self.assertEqual(Stichwort.objects.count(), 2)
class StichworterklaerungModelTest(TestCase):
"""Test cases for Stichworterklaerung model"""
def setUp(self):
"""Set up test data"""
self.stichwort = Stichwort.objects.create(
stichwort="Sicherheit"
)
self.abschnitttyp = AbschnittTyp.objects.create(
abschnitttyp="text"
)
self.erklaerung = Stichworterklaerung.objects.create(
erklaerung=self.stichwort,
abschnitttyp=self.abschnitttyp,
inhalt="Dies ist eine Erklärung für Sicherheit.",
order=1
)
def test_stichworterklaerung_creation(self):
"""Test that Stichworterklaerung is created correctly"""
self.assertEqual(self.erklaerung.erklaerung, self.stichwort)
self.assertEqual(self.erklaerung.abschnitttyp, self.abschnitttyp)
self.assertEqual(self.erklaerung.inhalt, "Dies ist eine Erklärung für Sicherheit.")
self.assertEqual(self.erklaerung.order, 1)
def test_stichworterklaerung_foreign_key_relationship(self):
"""Test foreign key relationship to Stichwort"""
self.assertEqual(self.erklaerung.erklaerung.stichwort, "Sicherheit")
def test_stichworterklaerung_cascade_delete(self):
"""Test that deleting Stichwort cascades to Stichworterklaerung"""
stichwort_count = Stichwort.objects.count()
erklaerung_count = Stichworterklaerung.objects.count()
self.stichwort.delete()
self.assertEqual(Stichwort.objects.count(), stichwort_count - 1)
self.assertEqual(Stichworterklaerung.objects.count(), erklaerung_count - 1)
def test_stichworterklaerung_verbose_name(self):
"""Test verbose name"""
self.assertEqual(
Stichworterklaerung._meta.verbose_name,
"Erklärung"
)
def test_stichworterklaerung_multiple_explanations(self):
"""Test creating multiple explanations for one Stichwort"""
abschnitttyp2 = AbschnittTyp.objects.create(abschnitttyp="liste ungeordnet")
erklaerung2 = Stichworterklaerung.objects.create(
erklaerung=self.stichwort,
abschnitttyp=abschnitttyp2,
inhalt="Zweite Erklärung für Sicherheit.",
order=2
)
explanations = Stichworterklaerung.objects.filter(erklaerung=self.stichwort)
self.assertEqual(explanations.count(), 2)
self.assertIn(self.erklaerung, explanations)
self.assertIn(erklaerung2, explanations)
def test_stichworterklaerung_ordering(self):
"""Test that explanations can be ordered"""
erklaerung2 = Stichworterklaerung.objects.create(
erklaerung=self.stichwort,
abschnitttyp=self.abschnitttyp,
inhalt="Zweite Erklärung",
order=3
)
erklaerung3 = Stichworterklaerung.objects.create(
erklaerung=self.stichwort,
abschnitttyp=self.abschnitttyp,
inhalt="Erste Erklärung",
order=2
)
ordered = Stichworterklaerung.objects.filter(erklaerung=self.stichwort).order_by('order')
expected_order = [self.erklaerung, erklaerung3, erklaerung2]
self.assertEqual(list(ordered), expected_order)
def test_stichworterklaerung_blank_fields(self):
"""Test that optional fields can be blank/null"""
stichwort2 = Stichwort.objects.create(stichwort="Test")
erklaerung_blank = Stichworterklaerung.objects.create(
erklaerung=stichwort2
)
self.assertIsNone(erklaerung_blank.abschnitttyp)
self.assertIsNone(erklaerung_blank.inhalt)
self.assertEqual(erklaerung_blank.order, 0)
def test_stichworterklaerung_inheritance(self):
"""Test that Stichworterklaerung inherits from Textabschnitt"""
# Check that it has the expected fields from Textabschnitt
self.assertTrue(hasattr(self.erklaerung, 'abschnitttyp'))
self.assertTrue(hasattr(self.erklaerung, 'inhalt'))
self.assertTrue(hasattr(self.erklaerung, 'order'))
# Check that the fields work as expected
self.assertIsInstance(self.erklaerung.abschnitttyp, AbschnittTyp)
self.assertIsInstance(self.erklaerung.inhalt, str)
self.assertIsInstance(self.erklaerung.order, int)
class StichwortIntegrationTest(TestCase):
"""Integration tests for Stichwort app"""
def setUp(self):
"""Set up test data"""
self.stichwort1 = Stichwort.objects.create(stichwort="IT-Sicherheit")
self.stichwort2 = Stichwort.objects.create(stichwort="Datenschutz")
self.abschnitttyp = AbschnittTyp.objects.create(abschnitttyp="text")
self.erklaerung1 = Stichworterklaerung.objects.create(
erklaerung=self.stichwort1,
abschnitttyp=self.abschnitttyp,
inhalt="Erklärung für IT-Sicherheit",
order=1
)
self.erklaerung2 = Stichworterklaerung.objects.create(
erklaerung=self.stichwort2,
abschnitttyp=self.abschnitttyp,
inhalt="Erklärung für Datenschutz",
order=1
)
def test_stichwort_with_explanations_query(self):
"""Test querying Stichworte with their explanations"""
stichworte_with_explanations = Stichwort.objects.filter(
stichworterklaerung__isnull=False
).distinct()
self.assertEqual(stichworte_with_explanations.count(), 2)
self.assertIn(self.stichwort1, stichworte_with_explanations)
self.assertIn(self.stichwort2, stichworte_with_explanations)
def test_stichwort_without_explanations(self):
"""Test finding Stichworte without explanations"""
stichwort3 = Stichwort.objects.create(stichwort="Backup")
stichworte_without_explanations = Stichwort.objects.filter(
stichworterklaerung__isnull=True
)
self.assertEqual(stichworte_without_explanations.count(), 1)
self.assertEqual(stichworte_without_explanations.first(), stichwort3)
def test_explanation_count_annotation(self):
"""Test annotating Stichworte with explanation count"""
from django.db.models import Count
stichworte_with_count = Stichwort.objects.annotate(
explanation_count=Count('stichworterklaerung')
)
for stichwort in stichworte_with_count:
if stichwort.stichwort in ["IT-Sicherheit", "Datenschutz"]:
self.assertEqual(stichwort.explanation_count, 1)
else:
self.assertEqual(stichwort.explanation_count, 0)