Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test/179 inventorize koswat acceptance tests #221

Merged
merged 8 commits into from
Nov 11, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 90 additions & 0 deletions tests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# Test strategy `Koswat`

## Overview
We adhere to the standard [V-model](#https://en.wikipedia.org/wiki/V-model_(software_development)).

| Type of test | Scope |
|-------------------|---------------|
| Unittests | Class |
| Integration tests | Subpackage |
| System tests | Package |
| Acceptance tests | Requirements |

These types of tests are described below in the `Koswat` context.

## Unit-/integration tests
For `Koswat` no distinction is made between the unit- and integration test.
The goal of the unit- and integration tests is to validate the behavior of separate classes or subpackages.
In general they don't require data input or output unless that is what the class is about.

## System tests
The goal of the system tests is to validate the outer behavior of the package is as expected.
The system tests can be found in `tests\test_main.py`.

Possible improvements:
- Mark the tests as `system`.
- Strip the test to only test the outer behavior (can package be installed and run, is logging created).

## Acceptance tests
The goal of the acceptance tests is to test if the overall behavior of the application is according to requirements.
The full workflow is executed and the output is validated.
As these tests take relatively much time to be executed, they are marked as `slow`.
The system tests can be found in `tests\test_acceptance.py`.

Possible improvements:
- Add docstrings to the fixtures and classes used, describing the purpose and usage.

### Sandbox tests
Several cases are tested, which are defined in `acceptance_test_scenario_cases`.
A case combines a dike profile (`AcceptanceTestInputProfileCases`) with layers (`LayersCases`) and scenarios (`ScenarioCases*`).

Goal: Validate a Koswat run generates the correct results.

Inputs:
- Realistic run settings (defined in `sandbox_acceptance_case`).
- NO locations and NO surroundings.

Validations:
- Check if the generated geometry images (`.png`) are identical to the provided reference images.
- Check is the generated exports (`.csv`) are identical to the provided reference files.

Possible improvements:
- Add a limited number of locations.

### Surroundings tests
A limited number of cases is tested, using the default dike profile (`InputProfileCases`) with 2 layer cases (`LayersCases`) and 3 different scenarios (`ScenarioCases`).

Goal: TODO

Inputs:
- Realistic run settings.
- Obstacles (NO infrastructures) from `test_data\csv_reader\Omgeving\T_10_3_bebouwing_binnendijks.csv`
- Locations from `test_data\shp_reader\Dijkvak\Dijkringlijnen_KOSWAT_Totaal_2017_10_3_Dijkvak.shp`.

Validations:
- Rough check on the presence of valid outputs:
- Have all profiles been calculated?
- Have all the expected .csv-files been created?

Possible improvements:
- Remove as they are superseded by the [Obstance and infrastructure tests](#Obstance-and-infrastructure-tests)?

### Obstacle and infrastructure tests
A limited number of cases is tested, using the default dike profile (`InputProfileCases`) with 2 layer cases (`LayersCases`) and 3 different scenarios (`ScenarioCases`). These are combined with 4 different surrounding scenarios with and without infrastructure and/or obstacles.

Goal: Validate the calculations for locations with obstacles and infrastructures work correctly.

Inputs:
- Configs from `koswat_general.ini` and `koswat_costs.ini` in `test_data\acceptance`.
- Surroundings from `test_data\acceptance\surroundings_analysis\10_3`.
- Locations from `test_data\shp_reader\Dijkvak\Dijkringlijnen_KOSWAT_Totaal_2017_10_3_Dijkvak.shp`.

Validations:
- Rough check on the presence of valid outputs:
- Have all the expected .csv-files been created?
- Are any surrouding reports (obstacles and/or infrastructure) present?

Possible improvements:
- Reduce the number of cases?
- Reduce the number of locations?
- Check content of .csv-files
1 change: 1 addition & 0 deletions tests/acceptance_scenarios/koswat_scenario_test_cases.py
Original file line number Diff line number Diff line change
@@ -25,6 +25,7 @@ class ScenarioCases(CasesProtocol):
crest_width=5,
waterside_slope=3,
)
# TODO: not used
scenario_infra = KoswatScenario(
d_h=0,
d_s=20,
4 changes: 2 additions & 2 deletions tests/cost_report/infrastructure/conftest.py
Original file line number Diff line number Diff line change
@@ -26,7 +26,7 @@

@pytest.fixture(name="reinforcement_profile_builder")
def _get_dummy_reinforcment_profile_builder() -> Iterable[
Callable[[CharacteristicPoints, CharacteristicPoints], ReinforcementProfileProtocol]
Callable[[list[tuple[float]], list[tuple[float]]], ReinforcementProfileProtocol]
]:
@dataclass
class DummyReinforcementProfile(KoswatProfileBase, ReinforcementProfileProtocol):
@@ -72,7 +72,7 @@ def _get_surroundings_infrastructure_fixture(
Callable[[], PointSurroundings], PointSurroundingsTestCase
],
request: pytest.FixtureRequest,
) -> Iterable[SurroundingsInfrastructure]:
) -> Iterable[tuple[SurroundingsInfrastructure, PointSurroundingsTestCase]]:
_infra_width = request.param
_builder, test_case = point_surroundings_for_zones_builder_fixture
test_case.expected_total_widths = list(
11 changes: 8 additions & 3 deletions tests/test_acceptance.py
Original file line number Diff line number Diff line change
@@ -376,6 +376,7 @@ def test_koswat_run_as_sandbox_with_surroundings(
KoswatSummaryExporter().export(_summary, _test_dir)
assert _test_dir.joinpath("summary_costs.csv").exists()
assert _test_dir.joinpath("summary_locations.csv").exists()
assert _test_dir.joinpath("summary_infrastructure_costs.csv").exists()

# 3. Verify expectations.
assert any(_summary.locations_profile_report_list)
@@ -416,7 +417,7 @@ def sandbox_acceptance_case(
assert isinstance(_acceptance_test_scenario, AcceptanceTestScenario)

# 1. Setup acceptance test case
# Get the refernce data in the output directory.
# Get the reference data in the output directory.
_results_dir_name = get_fixturerequest_case_name(request)
_output_dir = test_results.joinpath(
"sandbox_acceptance_case", _results_dir_name
@@ -476,8 +477,12 @@ def sandbox_acceptance_case(
SurtaxFactorEnum.MOEILIJK
)
_run_settings.surroundings = SurroundingsWrapper()
_run_settings.surroundings.reinforcement_min_buffer = 10
_run_settings.surroundings.reinforcement_min_separation = 50
_run_settings.surroundings.obstacle_surroundings_wrapper.reinforcement_min_buffer = (
10
)
_run_settings.surroundings.obstacle_surroundings_wrapper.reinforcement_min_separation = (
50
)
_run_settings.costs_setting = KoswatCostsSettings()
_run_settings.costs_setting.dike_profile_costs = DikeProfileCostsSettings()
_run_settings.costs_setting.dike_profile_costs.added_layer_grass_m3 = 12.44