Professionelles Testen mit pytest: Mocking mit monkeypatch und create_autospec

Ein umfassender Leitfaden zum professionellen Testen mit pytest. Lernen Sie, wie Sie mit monkeypatch und create_autospec typsichere Mocks erstellen und warum create_autospec entscheidend ist, um Signaturen nicht zu ignorieren.

Professionelles Testen mit pytest: Ein umfassender Leitfaden

Testing ist das Rückgrat jeder professionellen Software-Entwicklung. In diesem ausführlichen Artikel zeigen wir Ihnen, wie Sie mit pytest effektive und wartbare Tests schreiben. Besonders fokussieren wir uns auf das Mocking mit monkeypatch und create_autospec - zwei mächtige Werkzeuge, die oft missverstanden oder falsch eingesetzt werden.

Warum pytest?

pytest ist das de-facto Standard-Testing-Framework für Python und bietet gegenüber dem eingebauten unittest mehrere Vorteile:

  • Einfache Syntax: Normale assert-Statements statt spezieller Assertion-Methoden
  • Automatische Test-Discovery: Findet Tests automatisch basierend auf Namenskonventionen
  • Fixtures: Mächtige Dependency-Injection für Test-Setup und -Teardown
  • Parametrisierte Tests: Einfaches Testen mit verschiedenen Eingabewerten
  • Umfangreiches Plugin-Ökosystem: Erweiterungen für Coverage, Benchmarking, etc.

Grundlagen: Einfache Tests schreiben

Beginnen wir mit einem einfachen Beispiel:

# calculator.py
class Calculator:
    def add(self, a, b):
        return a + b

    def divide(self, a, b):
        if b == 0:
            raise ValueError("Division by zero is not allowed")
        return a / b
# test_calculator.py
import pytest
from calculator import Calculator


def test_add():
    calc = Calculator()
    result = calc.add(2, 3)
    assert result == 5


def test_divide():
    calc = Calculator()
    result = calc.divide(10, 2)
    assert result == 5.0


def test_divide_by_zero():
    calc = Calculator()
    with pytest.raises(ValueError, match="Division by zero is not allowed"):
        calc.divide(10, 0)

Fixtures: Setup und Teardown elegant lösen

Fixtures sind pytest's Antwort auf Setup- und Teardown-Code:

import pytest
from calculator import Calculator


@pytest.fixture
def calculator():
    # Fixture that provides a Calculator instance for tests
    return Calculator()


def test_add_with_fixture(calculator):
    result = calculator.add(2, 3)
    assert result == 5


@pytest.fixture
def database_connection():
    # Fixture with setup and teardown
    # Setup
    connection = create_database_connection()
    yield connection
    # Teardown
    connection.close()

Das Problem mit externen Abhängigkeiten

In realen Anwendungen haben unsere Klassen oft externe Abhängigkeiten:

# email_service.py
import smtplib
from email.mime.text import MIMEText


class EmailService:
    def __init__(self, smtp_server, port):
        self.smtp_server = smtp_server
        self.port = port

    def send_email(self, to_email, subject, body):
        # Send an email via SMTP
        msg = MIMEText(body)
        msg['Subject'] = subject
        msg['To'] = to_email

        with smtplib.SMTP(self.smtp_server, self.port) as server:
            server.send_message(msg)
            return True


# notification_service.py
from email_service import EmailService


class NotificationService:
    def __init__(self, email_service: EmailService):
        self.email_service = email_service

    def notify_user(self, user_email, message):
        # Send notification to user
        subject = "Important Notification"
        success = self.email_service.send_email(user_email, subject, message)
        if success:
            return f"Notification sent to {user_email}"
        else:
            return "Failed to send notification"

Das Testen dieser Klassen ohne Mocking würde bedeuten, dass wir echte E-Mails versenden müssten - das ist unpraktisch, langsam und kann Seiteneffekte haben.

Mocking mit monkeypatch: Die Grundlagen

monkeypatch ist pytest's eingebautes Fixture zum Ersetzen von Objekten zur Laufzeit:

# test_notification_service.py
import pytest
from notification_service import NotificationService
from email_service import EmailService


def test_notify_user_success(monkeypatch):
    # Test successful notification using monkeypatch
    # Arrange
    email_service = EmailService("smtp.example.com", 587)
    notification_service = NotificationService(email_service)

    # Mock the send_email method
    def mock_send_email(to_email, subject, body):
        return True

    monkeypatch.setattr(email_service, 'send_email', mock_send_email)

    # Act
    result = notification_service.notify_user("[email protected]", "Test message")

    # Assert
    assert result == "Notification sent to [email protected]"


def test_notify_user_failure(monkeypatch):
    # Test failed notification using monkeypatch
    email_service = EmailService("smtp.example.com", 587)
    notification_service = NotificationService(email_service)

    # Mock the send_email method to return False
    monkeypatch.setattr(email_service, 'send_email', lambda *args: False)

    result = notification_service.notify_user("[email protected]", "Test message")
    assert result == "Failed to send notification"

Das Problem mit einfachen Mocks

Der obige Ansatz funktioniert, hat aber einen kritischen Schwachpunkt: Signatur-Ignoranz. Wenn sich die Signatur der gemockten Methode ändert, bemerken wir das nicht:

# Angenommen, EmailService.send_email ändert sich zu:
def send_email(self, to_email, subject, body, priority="normal"):
    # ...

Unser Mock würde weiterhin funktionieren, obwohl er die neue Signatur nicht respektiert. Das kann zu Bugs führen, die erst in der Produktion auffallen.

create_autospec: Typsichere Mocks

create_autospec löst dieses Problem, indem es Mocks erstellt, die die Signatur des ursprünglichen Objekts respektieren:

from unittest.mock import create_autospec
import pytest
from notification_service import NotificationService
from email_service import EmailService


def test_notify_user_with_autospec():
    # Test using create_autospec for type-safe mocking
    # Create a mock that respects EmailService's interface
    mock_email_service = create_autospec(EmailService, instance=True)

    # Configure the mock's return value
    mock_email_service.send_email.return_value = True

    # Create the service with the mock
    notification_service = NotificationService(mock_email_service)

    # Act
    result = notification_service.notify_user("[email protected]", "Test message")

    # Assert
    assert result == "Notification sent to [email protected]"

    # Verify the mock was called with correct arguments
    mock_email_service.send_email.assert_called_once_with(
        "[email protected]", 
        "Important Notification", 
        "Test message"
    )


def test_autospec_enforces_signature():
    # Demonstrate how autospec enforces method signatures
    mock_email_service = create_autospec(EmailService, instance=True)

    # This would raise TypeError if EmailService.send_email doesn't accept these parameters
    with pytest.raises(TypeError):
        mock_email_service.send_email("too", "many", "arguments", "here", "invalid")

Warum create_autospec so wichtig ist

1. Signatur-Validierung

def test_signature_validation():
    # Demonstrate signature validation with autospec
    mock_service = create_autospec(EmailService, instance=True)

    # This will fail if the signature doesn't match
    with pytest.raises(TypeError):
        mock_service.send_email()  # Missing required arguments

2. Attribute-Validierung

def test_attribute_validation():
    # Autospec also validates attributes
    mock_service = create_autospec(EmailService, instance=True)

    # This will fail because EmailService doesn't have a 'nonexistent_method'
    with pytest.raises(AttributeError):
        mock_service.nonexistent_method()

3. Refactoring-Sicherheit

Wenn Sie Ihre Klassen refactorieren und Methodensignaturen ändern, werden Tests mit create_autospec automatisch fehlschlagen und Sie auf notwendige Anpassungen hinweisen.

Kombinieren von monkeypatch und create_autospec

Für maximale Flexibilität können Sie beide Ansätze kombinieren:

def test_combined_approach(monkeypatch):
    # Combine monkeypatch with create_autospec
    # Create a type-safe mock
    mock_email_service = create_autospec(EmailService, instance=True)
    mock_email_service.send_email.return_value = True

    # Use monkeypatch to replace the class constructor
    monkeypatch.setattr('notification_service.EmailService', 
                       lambda *args: mock_email_service)

    # Now any code that creates EmailService will get our mock
    from notification_service import NotificationService
    service = NotificationService(EmailService("any", "args"))

    result = service.notify_user("[email protected]", "Test")
    assert result == "Notification sent to [email protected]"

Erweiterte Mocking-Patterns

Side Effects für komplexe Szenarien

def test_side_effects():
    # Use side_effect for complex mock behavior
    mock_service = create_autospec(EmailService, instance=True)

    # First call succeeds, second fails
    mock_service.send_email.side_effect = [True, False]

    notification_service = NotificationService(mock_service)

    # First call
    result1 = notification_service.notify_user("[email protected]", "Message 1")
    assert result1 == "Notification sent to [email protected]"

    # Second call
    result2 = notification_service.notify_user("[email protected]", "Message 2")
    assert result2 == "Failed to send notification"

Exception-Handling testen

def test_exception_handling():
    # Test how your code handles exceptions
    mock_service = create_autospec(EmailService, instance=True)
    mock_service.send_email.side_effect = ConnectionError("SMTP server unavailable")

    notification_service = NotificationService(mock_service)

    with pytest.raises(ConnectionError):
        notification_service.notify_user("[email protected]", "Test")

Best Practices für pytest und Mocking

1. Verwenden Sie aussagekräftige Testnamen

def test_notification_service_returns_success_message_when_email_sent():
    # Klar, was getestet wird
    pass

def test_notify():  # Schlecht: Unklar was getestet wird
    pass

2. Folgen Sie dem AAA-Pattern

def test_user_notification():
    # Arrange
    mock_service = create_autospec(EmailService, instance=True)
    mock_service.send_email.return_value = True
    notification_service = NotificationService(mock_service)

    # Act
    result = notification_service.notify_user("[email protected]", "Test")

    # Assert
    assert result == "Notification sent to [email protected]"

3. Mocken Sie nur was nötig ist

# Gut: Nur die externe Abhängigkeit mocken
def test_with_minimal_mocking():
    mock_email = create_autospec(EmailService, instance=True)
    mock_email.send_email.return_value = True
    # Test logic...

# Schlecht: Alles mocken
def test_with_excessive_mocking(monkeypatch):
    monkeypatch.setattr('builtins.str', lambda x: 'mocked')
    monkeypatch.setattr('builtins.len', lambda x: 42)
    # Macht den Test unverständlich und fragil

4. Verwenden Sie Fixtures für wiederverwendbare Mocks

@pytest.fixture
def mock_email_service():
    # Reusable mock for EmailService
    mock = create_autospec(EmailService, instance=True)
    mock.send_email.return_value = True
    return mock


def test_with_fixture(mock_email_service):
    notification_service = NotificationService(mock_email_service)
    # Test logic...

Walkthrough: Ein komplettes Beispiel

Lassen Sie uns ein vollständiges Beispiel durchgehen, das alle Konzepte zusammenbringt:

# user_manager.py
from typing import List
from email_service import EmailService
from database import UserRepository


class UserManager:
    def __init__(self, user_repo: UserRepository, email_service: EmailService):
        self.user_repo = user_repo
        self.email_service = email_service

    def register_user(self, email: str, name: str) -> dict:
        # Register a new user and send welcome email
        # Check if user already exists
        if self.user_repo.find_by_email(email):
            return {"success": False, "error": "User already exists"}

        # Create user
        user_id = self.user_repo.create_user(email, name)

        # Send welcome email
        welcome_message = f"Welcome {name}! Your account has been created."
        email_sent = self.email_service.send_email(
            email,
            "Welcome to our platform",
            welcome_message
        )

        if not email_sent:
            # Rollback user creation if email fails
            self.user_repo.delete_user(user_id)
            return {"success": False, "error": "Failed to send welcome email"}

        return {"success": True, "user_id": user_id}
# test_user_manager.py
import pytest
from unittest.mock import create_autospec
from user_manager import UserManager
from email_service import EmailService
from database import UserRepository


@pytest.fixture
def mock_user_repo():
    # Mock UserRepository with autospec
    return create_autospec(UserRepository, instance=True)


@pytest.fixture
def mock_email_service():
    # Mock EmailService with autospec
    return create_autospec(EmailService, instance=True)


@pytest.fixture
def user_manager(mock_user_repo, mock_email_service):
    # UserManager with mocked dependencies
    return UserManager(mock_user_repo, mock_email_service)


def test_register_user_success(user_manager, mock_user_repo, mock_email_service):
    # Test successful user registration
    # Arrange
    mock_user_repo.find_by_email.return_value = None  # User doesn't exist
    mock_user_repo.create_user.return_value = 123
    mock_email_service.send_email.return_value = True

    # Act
    result = user_manager.register_user("[email protected]", "John Doe")

    # Assert
    assert result == {"success": True, "user_id": 123}

    # Verify interactions
    mock_user_repo.find_by_email.assert_called_once_with("[email protected]")
    mock_user_repo.create_user.assert_called_once_with("[email protected]", "John Doe")
    mock_email_service.send_email.assert_called_once_with(
        "[email protected]",
        "Welcome to our platform",
        "Welcome John Doe! Your account has been created."
    )


def test_register_user_already_exists(user_manager, mock_user_repo, mock_email_service):
    # Test registration when user already exists
    # Arrange
    mock_user_repo.find_by_email.return_value = {"id": 456, "email": "[email protected]"}

    # Act
    result = user_manager.register_user("[email protected]", "John Doe")

    # Assert
    assert result == {"success": False, "error": "User already exists"}

    # Verify no user creation or email sending occurred
    mock_user_repo.create_user.assert_not_called()
    mock_email_service.send_email.assert_not_called()


def test_register_user_email_failure_rollback(user_manager, mock_user_repo, mock_email_service):
    # Test rollback when email sending fails
    # Arrange
    mock_user_repo.find_by_email.return_value = None
    mock_user_repo.create_user.return_value = 123
    mock_email_service.send_email.return_value = False  # Email fails

    # Act
    result = user_manager.register_user("[email protected]", "John Doe")

    # Assert
    assert result == {"success": False, "error": "Failed to send welcome email"}

    # Verify rollback occurred
    mock_user_repo.delete_user.assert_called_once_with(123)

Fazit

Das Schreiben effektiver Tests mit pytest erfordert mehr als nur das Kennen der Syntax. Die richtige Verwendung von Mocking-Techniken, insbesondere create_autospec, ist entscheidend für:

  1. Typsicherheit: Ihre Tests brechen, wenn sich Signaturen ändern
  2. Wartbarkeit: Tests bleiben synchron mit dem Code
  3. Vertrauen: Sie können sicher refactorieren
  4. Geschwindigkeit: Tests laufen schnell ohne externe Abhängigkeiten

Wichtige Takeaways:

  • Verwenden Sie create_autospec statt einfacher Mocks für typsichere Tests
  • Kombinieren Sie monkeypatch und create_autospec für maximale Flexibilität
  • Folgen Sie dem AAA-Pattern (Arrange, Act, Assert)
  • Mocken Sie nur externe Abhängigkeiten, nicht Ihre eigene Logik
  • Schreiben Sie aussagekräftige Testnamen und verwenden Sie Fixtures für Wiederverwendbarkeit

Mit diesen Techniken können Sie robuste, wartbare Tests schreiben, die Ihnen helfen, qualitativ hochwertigen Code zu entwickeln und dabei das Vertrauen in Ihre Software zu stärken.

Weiterführende Ressourcen

Haben Sie Fragen zu pytest oder Mocking? Kontaktieren Sie uns gerne für eine persönliche Beratung zu Ihren Testing-Strategien!

Über re-minds GmbH

Seit 2015 entwickeln wir maßgeschneiderte Software-Lösungen und begleiten Unternehmen bei ihrer digitalen Transformation. Unser Fokus liegt auf Python, Django und modernen Cloud-Technologien.

Entwicklung

Professionelle Web-Anwendungen mit Python, Django und modernen Frameworks

Cloud & DevOps

Skalierbare Cloud-Lösungen auf AWS, GCP und Azure mit CI/CD-Pipelines

Schulungen

Inhouse-Trainings für Python, Django, DevOps und moderne Entwicklungsmethoden

Kontakt aufnehmen

Unser Büro

re-minds GmbH
Alter Postweg 32
26215 Neuenkruge

Telefon

+49 151 404 183 93

E-Mail

[email protected]

Imprint

Angaben gemäß § 5 TMG:

re-minds GmbH
Waldweg 1A
26215 Wiefelstede

Kontakt:
+49 (0)151 – 40418393
[email protected]
www.re-minds.de

Registergericht: Oldenburg
Registernummer: HRB 216237
Vertretungsberechtigte Geschäftsführer: Tim Fiedler
Umsatzsteuer-Identifikationsnummer nach § 27a UStG:
DE338576407

Datenschutzerklärung

Allgemeiner Hinweis und Pflichtinformationen

Benennung der verantwortlichen Stelle

Die verantwortliche Stelle für die Datenverarbeitung auf dieser Website ist:

re-minds GmbH
Tim Fiedler
Alter Postweg 32
26215 Neuenkruge

Die verantwortliche Stelle entscheidet allein oder gemeinsam mit anderen über die Zwecke und Mittel der Verarbeitung von personenbezogenen Daten (z.B. Namen, Kontaktdaten o. Ä.).

Widerruf Ihrer Einwilligung zur Datenverarbeitung

Nur mit Ihrer ausdrücklichen Einwilligung sind einige Vorgänge der Datenverarbeitung möglich. Ein Widerruf Ihrer bereits erteilten Einwilligung ist jederzeit möglich. Für den Widerruf genügt eine formlose Mitteilung per E-Mail. Die Rechtmäßigkeit der bis zum Widerruf erfolgten Datenverarbeitung bleibt vom Widerruf unberührt.

Recht auf Beschwerde bei der zuständigen Aufsichtsbehörde

Als Betroffener steht Ihnen im Falle eines datenschutzrechtlichen Verstoßes ein Beschwerderecht bei der zuständigen Aufsichtsbehörde zu. Zuständige Aufsichtsbehörde bezüglich datenschutzrechtlicher Fragen ist der Landesdatenschutzbeauftragte des Bundeslandes, in dem sich der Sitz unseres Unternehmens befindet. Der folgende Link stellt eine Liste der Datenschutzbeauftragten sowie deren Kontaktdaten bereit: https://www.bfdi.bund.de/DE/Infothek/Anschriften_Links/anschriften_links-node.html.

Recht auf Datenübertragbarkeit

Ihnen steht das Recht zu, Daten, die wir auf Grundlage Ihrer Einwilligung oder in Erfüllung eines Vertrags automatisiert verarbeiten, an sich oder an Dritte aushändigen zu lassen. Die Bereitstellung erfolgt in einem maschinenlesbaren Format. Sofern Sie die direkte Übertragung der Daten an einen anderen Verantwortlichen verlangen, erfolgt dies nur, soweit es technisch machbar ist.

Recht auf Auskunft, Berichtigung, Sperrung, Löschung

Sie haben jederzeit im Rahmen der geltenden gesetzlichen Bestimmungen das Recht auf unentgeltliche Auskunft über Ihre gespeicherten personenbezogenen Daten, Herkunft der Daten, deren Empfänger und den Zweck der Datenverarbeitung und ggf. ein Recht auf Berichtigung, Sperrung oder Löschung dieser Daten. Diesbezüglich und auch zu weiteren Fragen zum Thema personenbezogene Daten können Sie sich jederzeit über die im Impressum aufgeführten Kontaktmöglichkeiten an uns wenden.

SSL- bzw. TLS-Verschlüsselung

Aus Sicherheitsgründen und zum Schutz der Übertragung vertraulicher Inhalte, die Sie an uns als Seitenbetreiber senden, nutzt unsere Website eine SSL-bzw. TLS-Verschlüsselung. Damit sind Daten, die Sie über diese Website übermitteln, für Dritte nicht mitlesbar. Sie erkennen eine verschlüsselte Verbindung an der „https://“ Adresszeile Ihres Browsers und am Schloss-Symbol in der Browserzeile.

Server-Log-Dateien

In Server-Log-Dateien erhebt und speichert der Provider der Website automatisch Informationen, die Ihr Browser automatisch an uns übermittelt. Dies sind:

  • Besuchte Seite auf unserer Domain
  • Datum und Uhrzeit der Serveranfrage
  • Browsertyp und Browserversion
  • Verwendetes Betriebssystem
  • Referrer URL
  • Hostname des zugreifenden Rechners
  • IP-Adresse

Es findet keine Zusammenführung dieser Daten mit anderen Datenquellen statt. Grundlage der Datenverarbeitung bildet Art. 6 Abs. 1 lit. b DSGVO, der die Verarbeitung von Daten zur Erfüllung eines Vertrags oder vorvertraglicher Maßnahmen gestattet.

Kontaktformular

Per Kontaktformular übermittelte Daten werden einschließlich Ihrer Kontaktdaten gespeichert, um Ihre Anfrage bearbeiten zu können oder um für Anschlussfragen bereitzustehen. Eine Weitergabe dieser Daten findet ohne Ihre Einwilligung nicht statt.

Die Verarbeitung der in das Kontaktformular eingegebenen Daten erfolgt ausschließlich auf Grundlage Ihrer Einwilligung (Art. 6 Abs. 1 lit. a DSGVO). Ein Widerruf Ihrer bereits erteilten Einwilligung ist jederzeit möglich. Für den Widerruf genügt eine formlose Mitteilung per E-Mail. Die Rechtmäßigkeit der bis zum Widerruf erfolgten Datenverarbeitungsvorgänge bleibt vom Widerruf unberührt.

Über das Kontaktformular übermittelte Daten verbleiben bei uns, bis Sie uns zur Löschung auffordern, Ihre Einwilligung zur Speicherung widerrufen oder keine Notwendigkeit der Datenspeicherung mehr besteht. Zwingende gesetzliche Bestimmungen - insbesondere Aufbewahrungsfristen - bleiben unberührt.

Cookies

Unsere Website verwendet Cookies. Das sind kleine Textdateien, die Ihr Webbrowser auf Ihrem Endgerät speichert. Cookies helfen uns dabei, unser Angebot nutzerfreundlicher, effektiver und sicherer zu machen.

Einige Cookies sind “Session-Cookies.” Solche Cookies werden nach Ende Ihrer Browser-Sitzung von selbst gelöscht. Hingegen bleiben andere Cookies auf Ihrem Endgerät bestehen, bis Sie diese selbst löschen. Solche Cookies helfen uns, Sie bei Rückkehr auf unserer Website wiederzuerkennen.

Mit einem modernen Webbrowser können Sie das Setzen von Cookies überwachen, einschränken oder unterbinden. Viele Webbrowser lassen sich so konfigurieren, dass Cookies mit dem Schließen des Programms von selbst gelöscht werden. Die Deaktivierung von Cookies kann eine eingeschränkte Funktionalität unserer Website zur Folge haben.

Das Setzen von Cookies, die zur Ausübung elektronischer Kommunikationsvorgänge oder der Bereitstellung bestimmter, von Ihnen erwünschter Funktionen (z.B. Warenkorb) notwendig sind, erfolgt auf Grundlage von Art. 6 Abs. 1 lit. f DSGVO. Als Betreiber dieser Website haben wir ein berechtigtes Interesse an der Speicherung von Cookies zur technisch fehlerfreien und reibungslosen Bereitstellung unserer Dienste. Sofern die Setzung anderer Cookies (z.B. für Analyse-Funktionen) erfolgt, werden diese in dieser Datenschutzerklärung separat behandelt.

Google Analytics

Unsere Website verwendet Funktionen des Webanalysedienstes Google Analytics. Anbieter des Webanalysedienstes ist die Google Inc., 1600 Amphitheatre Parkway, Mountain View, CA 94043, USA.

Google Analytics verwendet "Cookies." Das sind kleine Textdateien, die Ihr Webbrowser auf Ihrem Endgerät speichert und eine Analyse der Website-Benutzung ermöglichen. Mittels Cookie erzeugte Informationen über Ihre Benutzung unserer Website werden an einen Server von Google übermittelt und dort gespeichert. Server-Standort ist im Regelfall die USA.

Das Setzen von Google-Analytics-Cookies erfolgt auf Grundlage von Art. 6 Abs. 1 lit. f DSGVO. Als Betreiber dieser Website haben wir  ein berechtigtes Interesse an der Analyse des Nutzerverhaltens, um unser Webangebot und ggf. auch Werbung zu optimieren.

IP-Anonymisierung

Wir setzen Google Analytics in Verbindung mit der Funktion IP-Anonymisierung ein. Sie gewährleistet, dass Google Ihre IP-Adresse innerhalb von Mitgliedstaaten der Europäischen Union oder in anderen Vertragsstaaten des Abkommens über den Europäischen Wirtschaftsraum vor der Übermittlung in die USA kürzt. Es kann Ausnahmefälle geben, in denen Google die volle IP-Adresse an einen Server in den USA überträgt und dort kürzt. In unserem Auftrag wird Google diese Informationen benutzen, um Ihre Nutzung der Website auszuwerten, um Reports über Websiteaktivitäten zu erstellen und um weitere mit der Websitenutzung und der Internetnutzung verbundene Dienstleistungen gegenüber uns zu erbringen. Es findet keine Zusammenführung der von Google Analytics übermittelten IP-Adresse mit anderen Daten von Google statt.

Browser Plugin

Das Setzen von Cookies durch Ihren Webbrowser ist verhinderbar. Einige Funktionen unserer Website könnten dadurch jedoch eingeschränkt werden. Ebenso können Sie die Erfassung von Daten bezüglich Ihrer Website-Nutzung einschließlich Ihrer IP-Adresse mitsamt anschließender Verarbeitung durch Google unterbinden. Dies ist möglich, indem Sie das über folgenden Link erreichbare Browser-Plugin herunterladen und installieren: https://tools.google.com/dlpage/gaoptout?hl=de.

Widerspruch gegen die Datenerfassung

Sie können die Erfassung Ihrer Daten durch Google Analytics verhindern, indem Sie auf folgenden Link klicken. Es wird ein Opt-Out-Cookie gesetzt, der die Erfassung Ihrer Daten bei zukünftigen Besuchen unserer Website verhindert: Google Analytics deaktivieren.

Einzelheiten zum Umgang mit Nutzerdaten bei Google Analytics finden Sie in der Datenschutzerklärung von Google: https://support.google.com/analytics/answer/6004245?hl=de.

Auftragsverarbeitung

Zur vollständigen Erfüllung der gesetzlichen Datenschutzvorgaben haben wir mit Google einen Vertrag über die Auftragsverarbeitung abgeschlossen.

Demografische Merkmale bei Google Analytics

Unsere Website verwendet die Funktion “demografische Merkmale” von Google Analytics. Mit ihr lassen sich Berichte erstellen, die Aussagen zu Alter, Geschlecht und Interessen der Seitenbesucher enthalten. Diese Daten stammen aus interessenbezogener Werbung von Google sowie aus Besucherdaten von Drittanbietern. Eine Zuordnung der Daten zu einer bestimmten Person ist nicht möglich. Sie können diese Funktion jederzeit deaktivieren. Dies ist über die Anzeigeneinstellungen in Ihrem Google-Konto möglich oder indem Sie die Erfassung Ihrer Daten durch Google Analytics, wie im Punkt “Widerspruch gegen die Datenerfassung” erläutert, generell untersagen.

Quelle: Datenschutz-Konfigurator von mein-datenschutzbeauftragter.de

hier Google Analytics Tracking für diese Website abschalten