Testing, CI & Docker

Proving a GIS workflow still works, and shipping it somewhere reproducible.

An assertion on the exact output bytes against assertions on the properties that must hold. assert what has to be true, not what the bytes wereassert wkt == "POLYGON ((0 0, …"breaks when GEOS reorders a ringand tells you nothing about whyassert out.is_valid.all()assert out.crs == src.crsassert area == approx(expected)survives every upgrade that keeps the meaningthe same function, two testsWhich is also why the Docker image is part of the test: the versions are half the behaviour

Testing GIS code is mostly a design problem wearing a testing costume. Code that reads a fixed path, transforms, and writes a fixed path has no seams to test; push the I/O to the edges and the interesting part becomes a function from a GeoDataFrame to a GeoDataFrame, which is trivially testable.

The second question is what to assert. A byte-for-byte comparison of WKT breaks the day GEOS reorders a ring, and tells you nothing about why. Properties — validity, CRS, row count, area within a tolerance, geometry type — survive upgrades that preserve the meaning and fail the ones that do not. That is also why the container is part of the test: in this stack the library versions are half the behaviour.

The pages below cover fixtures, temporary paths, round-trip and golden-file tests, and getting the whole thing to run in CI without running out of memory.

Learning paths run through this topic too — see the end of this page.

🧭 Start with the concepts

The ideas the how-to guides below assume you already have.

⚙️ Then do the task

Step-by-step walkthroughs with code you can copy and adapt.

Show every how-to guide in this topic

🔧 When it breaks

The errors this topic produces, with the cause explained rather than just the command.

Related topics

Subjects that keep coming up alongside this one, most overlap first.

Keep browsing

Testing, CI & Docker sits in Production. Every topic on the site is listed on the topics index.