Case Discovery¶
This guide shows how to find GeoCase cases by metadata instead of memorizing individual case IDs.
To discover cases by eye instead, browse all 135 cases.
GeoCase cases are designed to be discovered by intent:
- what data type you need,
- what geometry type you care about,
- what bug or risk you want to expose,
- what suite already groups relevant cases.
Start with the broadest filter¶
The most common first filter is category:
import pytest
@pytest.mark.geocase_select(category="vector")
def test_all_vectors(geocase) -> None:
gdf = geocase.load()
assert len(gdf) > 0
Use:
category="vector"for GeoPandas-based cases,category="raster"for raster cases,category="netcdf"for xarray/NetCDF cases.
Narrow by geometry type¶
For vector cases, geometry_type is often the next best filter.
@pytest.mark.geocase_select(category="vector", geometry_type="Polygon")
def test_polygon_cases(geocase) -> None:
gdf = geocase.load()
assert len(gdf) > 0
Common values include:
PointMultiPointLineStringMultiLineStringPolygonMultiPolygonGeometryCollection
Use tags for scenario discovery¶
Tags describe the scenario a case is meant to expose.
Examples:
datelineantimeridianutmnodatainvalidholeencodingprecision
Use tags_any when any one of the listed tags is enough:
@pytest.mark.geocase_select(category="vector", tags_any=["dateline", "antimeridian"])
def test_wrapped_longitude_cases(geocase) -> None:
gdf = geocase.load()
assert len(gdf) > 0
Use tags_all when you want cases that satisfy all listed traits:
@pytest.mark.geocase_select(category="vector", tags_all=["polygon", "invalid"])
def test_invalid_polygon_cases(geocase) -> None:
gdf = geocase.load()
assert len(gdf) > 0
Use risk types for bug-oriented selection¶
risk_types are useful when your test is about failure modes rather than shape or format.
Examples:
coordinate_wrappingtopology_breakagebbox_misinterpretationnan_propagationincorrect_statistics
@pytest.mark.geocase_select(risk_types_any=["coordinate_wrapping"])
def test_coordinate_wrapping_risks(geocase) -> None:
assert "coordinate_wrapping" in geocase.metadata.risk_types
A good rule of thumb:
- use
tagsfor scenario labels, - use
risk_typesfor the kind of bug you expect.
Filter by format¶
If you need to exercise file-format-specific behavior, use format.
@pytest.mark.geocase_select(category="vector", format="GPKG")
def test_gpkg_cases(geocase) -> None:
gdf = geocase.load()
assert len(gdf) > 0
Typical examples:
GeoJSONGPKGShapefileParquetGeoTIFFNetCDF
Use format filtering when the format itself matters, such as:
- shapefile field truncation,
- GeoJSON precision loss,
- GPKG null geometry behavior.
Use suites when the grouping already exists¶
Suites are named, curated groups of cases.
import pytest
@pytest.mark.geocase_suite("core-vector")
def test_core_vector_suite(geocase) -> None:
gdf = geocase.load()
assert len(gdf) > 0
Use a suite when:
- the repo already defines the grouping you want,
- you want a stable maintainer-curated set,
- you do not want to repeat selector logic in every test.
Use selectors when your intent is more specific or temporary.
The bundled suites are core-vector, crs-edge-cases, raster-nodata,
vector-topology, vector-crs-edge, vector-schema-encoding and
georeferencing-conventions.
Start with georeferencing-conventions if you are evaluating GeoCase against
an existing codebase. It collects the affine-transform and footprint cases —
rotation, bottom-up rasters, pixel anchoring, sparse and holed footprints,
antimeridian bounds — which otherwise span three corpus directories, and it is
the axis that has produced the most defects in external use.
Decision guide¶
| If you want... | Use... |
|---|---|
| One specific known case | @pytest.mark.geocase_case(...) |
| A curated named group | @pytest.mark.geocase_suite(...) |
| A metadata-defined family of cases | @pytest.mark.geocase_select(...) |
| Format-specific behavior | format=... |
| A geometry family | geometry_type=... |
| A bug category | risk_types_any=[...] |
| A scenario label | tags_any=[...] or tags_all=[...] |
Good discovery patterns¶
Start broad, then narrow¶
@pytest.mark.geocase_select(category="vector", geometry_type="Polygon", tags_any=["invalid"])
def test_invalid_polygon_behavior(geocase) -> None:
geom = geocase.load()
assert len(geom) > 0
Prefer suites for stable CI coverage¶
@pytest.mark.geocase_suite("core-vector")
def test_fast_smoke_suite(geocase) -> None:
assert geocase.id
Prefer selectors for behavior-driven tests¶
@pytest.mark.geocase_select(category="raster", tags_any=["nodata"])
def test_nodata_behavior(geocase) -> None:
data, _, _ = geocase.read(1)
assert data.size > 0