Help me een uitgebreide eenheidsteststrategie maken voor mijn gegevensverwerkingsapplicatie
description
Door deze prompt te volgen, stel je een duidelijke en effectieve eenheidsteststrategie op die is afgestemd op jouw gegevensverwerkingsapplicatie, wat de betrouwbaarheid, onderhoudbaarheid en algehele kwaliteit van je code verbetert.
prompt
try_prompt
Ik ontwikkel een gegevensverwerkingsapplicatie en heb begeleiding nodig over hoe ik een uitgebreide eenheidsteststrategie kan maken. Geef een overzicht van de beste praktijken voor het testen van verschillende gegevenstransformaties, inclusief ran ... more
generate_helper
...
tags
ai_answers
provider: openai
model: gpt-4.1-nano
Zeker! Hier is een overzicht van beste praktijken voor het ontwikkelen van een uitgebreide eenheidsteststrategie voor een ETL-tool in Python, inclusief voorbeelden en tips om gegevensintegriteit te waarborgen:
1. **Structuur van de testomgeving**
- Gebruik testframeworks zoals `unittest`, `pytest` of `nose`.
- Maak gescheiden testgegevenssets voor verschillende scenario's.
- Gebruik mock-data en mock-functies waar mogelijk om externe afhankelijkheden te vermijden.
2. **Testen van gegevenstransformaties**
- **Input-validatie testen:** Controleer of de invoergegevens voldoen aan de verwachte structuur en datatypes.
- **Transformatieregels testen:** Verifieer dat transformaties correct worden toegepast volgens specificaties.
- **Output-validatie:** Controleer of de uitgangsdatasets correct en compleet zijn.
3. **Randgevallen en foutafhandeling**
- **Lege gegevenssets:** Wat gebeurt er als de invoer leeg is?
- **Onvolledige of corrupte gegevens:** Test met ontbrekende waarden, onjuiste datatypes, of formaatfouten.
- **Extreme waarden:** Bijvoorbeeld zeer grote cijfers, negatieve getallen, of extreem lange strings.
- **Onverwachte invoerformaten:** Bijvoorbeeld onverwachte datumnotaties.
4. **Gegevensvalidatiecontroles**
- **Consistentiecontroles:** Verifieer dat na transformatie de gegevens consistent blijven (bijv. geen duplicaten, referentiële integriteit).
- **Validatie van bedrijfsregels:** Bijvoorbeeld, dat een geboortedatum niet in de toekomst ligt.
- **Uniciteit en primary key checks:** Zorg dat unieke identifiers niet worden overschreven of duplicated.
5. **Voorbeelden van testscenario's**
- **Test 1: Basis transformatie**
```python
def test_basic_transformatie():
invoer = [{'id': 1, 'waarde': '10'}]
verwachte_uitvoer = [{'id': 1, 'waarde': 10, 'waarde_double': 20}]
resultaat = transformeer(invoer)
assert resultaat == verwachte_uitvoer
```
- **Test 2: Lege invoer**
```python
def test_lege_invoer():
invoer = []
resultaat = transformeer(invoer)
assert resultaat == []
```
- **Test 3: Onjuiste datatypes**
```python
def test_onjuiste_datatype():
invoer = [{'id': 'abc', 'waarde': '10'}]
with pytest.raises(ValidationError):
transformeer(invoer)
```
- **Test 4: Randwaarde (bijvoorbeeld negatieve getallen)**
```python
def test_negatieve_waarde():
invoer = [{'id': 2, 'waarde': '-5'}]
resultaat = transformeer(invoer)
assert resultaat[0]['waarde'] >= 0 # Of andere verwachte verwerking
```
6. **Waarborgen van gegevensintegriteit tijdens testen**
- Gebruik gecontroleerde, bekende testdatasets.
- Voer integriteitstests uit na elke transformatiefase.
- Controleer dat de totalen, gemiddelden en andere aggregaten overeenkomen met verwachte waarden.
- Maak gebruik van database-transaction management om tests te isoleren en revertibele te maken.
7. **Automatisering en Continuous Integration**
- Automatiseer je tests met CI-tools zoals Jenkins, GitHub Actions of GitLab CI.
- Zorg dat alle tests automatisch worden uitgevoerd bij elke codewijziging.
8. **Documentatie en rapportage**
- Documenteer testcases en verwachte resultaten.
- Gebruik testrapporten om snel inzicht te krijgen in falende tests en dataverlies of -fouten.
**Kort samengevat:** Ontwikkel een modulaire teststrategie die inputvalidatie, transformatielogica, randgevallen en gegevensintegriteit dekt. Maak gebruik van mocking voor externe afhankelijkheden en automatiseer tests voor continue bescherming. Door deze aanpak zorg je voor robuuste, betrouwbare gegevensverwerking in je ETL-applicatie.
provider: deepseek
model: deepseek-chat
Zeker, hier is een uitgebreid overzicht voor het opzetten van een eenheidsteststrategie voor je ETL-tool in Python, met specifieke voorbeelden en best practices.
### Basisprincipes voor ETL-testen
1. **Testpyramide**: Focus op veel eenheidstests, minder integratietests, en weinig end-to-end tests
2. **Isolatie**: Test elke transformatie onafhankelijk van bronnen en bestemmingen
3. **Reproduceerbaarheid**: Gebruiek vaste testdata voor voorspelbare resultaten
4. **Data-integriteit**: Controleer consistentie en nauwkeurigheid tijdens alle stappen
### Teststrategie Componenten
#### 1. Gegevenstransformatie Tests
```python
import pytest
import pandas as pd
from your_etl_tool import transformations
def test_basis_transformatie():
# Arrange
input_data = pd.DataFrame({"naam": [" jan ", "PETER"], "leeftijd": ["25", "30"]})
verwachte_output = pd.DataFrame({"naam": ["Jan", "Peter"], "leeftijd": [25, 30]})
# Act
resultaat = transformations.clean_and_convert_data(input_data)
# Assert
pd.testing.assert_frame_equal(resultaat, verwachte_output)
def test_berekende_kolom():
input_data = pd.DataFrame({"prijs": [100, 200], "btw_percentage": [0.21, 0.09]})
verwachte_output = pd.DataFrame({
"prijs": [100, 200],
"btw_percentage": [0.21, 0.09],
"totaal_prijs": [121, 218]
})
resultaat = transformations.bereken_totaal_prijs(input_data)
pd.testing.assert_frame_equal(resultaat, verwachte_output)
```
#### 2. Randgevallen Tests
```python
def test_lege_dataset():
input_data = pd.DataFrame()
verwachte_output = pd.DataFrame()
resultaat = transformations.clean_data(input_data)
assert resultaat.empty
def test_ontbrekende_waarden():
input_data = pd.DataFrame({
"naam": ["Jan", None, "Piet"],
"salaris": [1000, 2000, None]
})
resultaat = transformations.handle_missing_values(input_data)
# Controleer of ontbrekende waarden correct zijn afgehandeld
assert resultaat["naam"].isnull().sum() == 0
assert resultaat["salaris"].isnull().sum() == 0
def test_extreme_numerieke_waarden():
input_data = pd.DataFrame({
"temperatuur": [-273.15, 0, 10000],
"snelheid": [0, 299792458, -1]
})
resultaat = transformations.validate_numeric_ranges(input_data)
# Controleer of extreme waarden zijn gefilterd of aangepast
```
#### 3. Gegevensvalidatie Tests
```python
def test_datum_validatie():
input_data = pd.DataFrame({
"datum": ["2023-02-30", "2023-13-01", "2023-12-15"] # Ongeldige datums
})
resultaat = transformations.validate_dates(input_data)
assert len(resultaat) == 1 # Alleen geldige datum blijft over
assert resultaat.iloc[0]["datum"] == "2023-12-15"
def test_email_validatie():
input_data = pd.DataFrame({
"email": ["ongeldig", "geldig@voorbeeld.nl", "geen@"]
})
resultaat = transformations.validate_emails(input_data)
assert len(resultaat) == 1
assert resultaat.iloc[0]["email"] == "geldig@voorbeeld.nl"
def test_referentiele_integriteit():
hoofd_data = pd.DataFrame({"id": [1, 2, 3], "naam": ["A", "B", "C"]})
detail_data = pd.DataFrame({"hoofd_id": [1, 2, 4], "waarde": [10, 20, 30]}) # ID 4 bestaat niet
resultaat = transformations.validate_foreign_key(hoofd_data, detail_data, "hoofd_id")
assert len(resultaat) == 2 # Alleen geldige referenties
```
### Data-integriteit Waarborgen
#### 1. Test Data Management
```python
@pytest.fixture
def sample_test_data():
"""Vaste testdataset voor reproduceerbare tests"""
return pd.DataFrame({
"id": [1, 2, 3, 4, 5],
"naam": ["Jan", "Piet", "Klaas", "Marie", "Anna"],
"leeftijd": [25, 30, 35, 28, 42],
"salaris": [3000, 4000, 3500, 4200, 3800]
})
def test_data_integriteit_volledigheid(sample_test_data):
resultaat = transformations.clean_data(sample_test_data)
# Controleer dat geen rijen verloren zijn gegaan
assert len(resultaat) == len(sample_test_data)
# Controleer dat alle vereiste kolommen aanwezig zijn
vereiste_kolommen = ["id", "naam", "leeftijd", "salaris"]
assert all(kolom in resultaat.columns for kolom in vereiste_kolommen)
def test_data_integriteit_transformatie(sample_test_data):
origineel_totaal_salaris = sample_test_data["salaris"].sum()
resultaat = transformations.apply_salary_adjustment(sample_test_data)
# Controleer dat salaristotaal correct is getransformeerd
# (bijv. na percentage verhoging)
verwacht_totaal = origineel_totaal_salaris * 1.05 # 5% verhoging
assert resultaat["salaris"].sum() == pytest.approx(verwacht_totaal, rel=1e-2)
```
#### 2. Foutafhandeling Tests
```python
def test_onverwachte_datatypes():
input_data = pd.DataFrame({
"leeftijd": ["vijfentwintig", 30, "35"], # Mix van types
"salaris": [3000, "4000 euro", 3500]
})
with pytest.raises(ValueError):
transformations.convert_to_numeric(input_data)
def test_bestandsformaat_validatie():
ongeldig_csv_content = "naam,leeftijd\nJan,25\nPiet,dertig" # Ongeldige leeftijd
with pytest.raises(ValueError, match="Ongeldig numeriek formaat"):
transformations.load_and_validate_csv(ongeldig_csv_content)
```
### Test Organisatie en Uitvoering
#### 1. Test Configuratie
```python
# conftest.py
import pytest
import pandas as pd
@pytest.fixture
def mock_database_connection():
"""Mock database connectie voor geïsoleerde tests"""
# Implementeer mock logica
return MockDatabase()
@pytest.fixture
def complex_test_scenario():
"""Complex testscenario met meerdere transformatiestappen"""
test_data = pd.DataFrame({
# Uitgebreide testdataset
})
return test_data
```
#### 2. Integratie Tests
```python
def test_complete_etl_pipeline(mock_database_connection):
# Test de volledige ETL pipeline
input_data = pd.DataFrame({
"raw_data": [" waarde1 ", "WAARDE2", " waarde3 "]
})
resultaat = complete_etl_pipeline(
input_data,
mock_database_connection
)
# Controleer eindresultaat
assert "clean_data" in resultaat.columns
assert len(resultaat) == 3
assert all(resultaat["clean_data"].str.islower())
```
### Aanbevolen Testbibliotheken
- **pytest**: Hoofd test framework
- **pandas.testing**: Voor DataFrame vergelijkingen
- **unittest.mock**: Voor mocking externe afhankelijkheden
- **hypothesis**: Voor property-based testing
- **pytest-cov**: Voor test coverage rapportage
### Best Practices Samenvatting
1. **Test alle transformatielogica** onafhankelijk
2. **Cover randgevallen** en uitzonderingssituaties
3. **Valideer data kwaliteit** voor en na transformaties
4. **Mock externe afhankelijkheden** (databases, APIs)
5. **Meet test coverage** en streef naar >80%
6. **Automatiseer testuitvoering** in CI/CD pipeline
7. **Documenteer testscenario's** voor toekomstig onderhoud
Deze aanpak zorgt voor robuuste ETL-processen met gegarandeerde data-integriteit door de gehele pipeline.

