Skip to content

tests: Migrate r.fill.stats from gunittest to pytest - #7894

Open
Valyrian-Code wants to merge 9 commits into
OSGeo:mainfrom
Valyrian-Code:r.fill.stats-pytest
Open

Valyrian-Code wants to merge 9 commits into
OSGeo:mainfrom
Valyrian-Code:r.fill.stats-pytest

Conversation

@Valyrian-Code

@Valyrian-Code Valyrian-Code commented Sep 5, 2026 •

Copy link
Copy Markdown
Contributor

Migrates the r.fill.stats testsuite from gunittest to pytest, keeping the ASCII files and comparing arrays from Tools rather than a difference raster.

One cell changed in each reference file. The northeast corner was null but the tool fills it, in all four modes, and it is the only cell that differs. See #8057 for why the old check missed it.

Suggested squash commit message

tests: Migrate r.fill.stats from gunittest to pytest

Keeps the ASCII input and reference files and compares the tool output against the reference as NumPy arrays from Tools, rather than through a difference raster.

Corrects one cell in each of the four reference files. The northeast corner was stored as null but the tool fills it in every mode. The old assertRastersNoDifference could not detect this, since a difference against a null is itself null. Reported in #8057.

@github-actions github-actions Bot added raster Related to raster data processing Python Related code is in Python module tests Related to Test Suite labels Sep 5, 2026
@Valyrian-Code

Copy link
Copy Markdown
Contributor Author

Same CI infra issue as noted on #7780: the failing checks are hitting an HTTP 504 from Launchpad while adding the ubuntugis-unstable PPA, unrelated to this PR. Should clear with a re-run.

@Valyrian-Code
Valyrian-Code marked this pull request as ready for review September 19, 2026 18:40
Copilot AI lite review requested due to automatic review settings September 19, 2026 18:40

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

The NumPy comparison retains a relative tolerance, weakening the previous absolute 1e-6 assertion.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 1 Medium severity

Open (1)
What changed in this PR

Migrates r.fill.stats regression coverage from gunittest to pytest, using isolated GRASS sessions, grass.tools, and NumPy comparisons.

Changes:

  • Adds parametrized tests for all four interpolation modes.
  • Inlines input and reference raster data.
  • Removes the legacy gunittest test and data files.
File Description
raster/​r.fill.stats/​tests/​r_fill_stats_test.py New pytest-based regression tests and inline fixtures.
raster/​r.fill.stats/​testsuite/​test_r_fill_stats.py Removes the legacy gunittest test.
raster/​r.fill.stats/​testsuite/​data/​input_ascii.txt Removes migrated input data.
raster/​r.fill.stats/​testsuite/​data/​output_wmean.txt Removes migrated weighted-mean reference.
raster/​r.fill.stats/​testsuite/​data/​output_mean.txt Removes migrated mean reference.
raster/​r.fill.stats/​testsuite/​data/​output_median.txt Removes migrated median reference.
raster/​r.fill.stats/​testsuite/​data/​output_mode.txt Removes migrated mode reference.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread raster/r.fill.stats/tests/r_fill_stats_test.py Outdated
np.allclose applies rtol as well as atol, so with the default rtol=1e-5 a
cell near 5 could differ by about 5e-5 and still pass, where the gunittest
version used an absolute precision=1e-6. Setting rtol=0 restores that.
@Valyrian-Code

Copy link
Copy Markdown
Contributor Author

Good catch, fixed. The original was an absolute precision=1e-6, and the default rtol=1e-5 let a cell near 5 drift about 5e-5, so this had quietly loosened it. Set rtol=0, all four modes still pass.

@Valyrian-Code

Copy link
Copy Markdown
Contributor Author

The red macOS check is unrelated to this PR. All four r.fill.stats tests passed there; what failed is every test in python/grass/temporal/tests/grass_temporal_gui_support_test.py, each with Timeout (>300.0s) from pytest-timeout. macOS is green on main and on my other open PRs, so it looks like a hang on that runner rather than anything here.

@echoix

echoix commented Oct 12, 2026

Copy link
Copy Markdown
Member

The thing I don't like here, is that I'm not 100% sure that now or in the future, we will still test the compatibility of previous files the same way. I remember doing something to keep testsuite/data directories with the same line endings and encoding. The goal is that Windows GRASS will be able to open a file output from Linux GRASS and vice versa, and keep being able to open a previously created file in a future version.

Having the string inlined in tests, doesn't assure us that python won't be adjusting for the correct representation for that platform, so windows is testing something different than Linux.

Are you able to see if you can keep such independent data files with pytest? And maybe do the move without involving copying and pasting the contents, to keep the actual encoding? Also check with .gitattributes and editor config nothing will be lost while moving from directories.

Inlining them meant the bytes the tool sees came from a Python string
literal rather than from disk, so the test no longer exercised reading the
file as stored. Move the five fixtures to tests/data and pass their paths to
r.in.ascii, as the gunittest version did. Git reports them as exact renames.
@Valyrian-Code

Copy link
Copy Markdown
Contributor Author

Yes, data files work with pytest. temporal/t.rast.import/tests/data already does it via pathlib.Path(__file__).parent / "data", and that one is a tar.bzip2, so bytes survive fine.

Moved the five fixtures to tests/data and went back to passing paths to r.in.ascii like the gunittest version did, so the tool reads them off disk instead of a Python literal. Took them from the stored blobs rather than copying text, and git reports all five as R100 against main.

No .gitattributes exists, and .editorconfig sets end_of_line = lf for [*] with editorconfig-checker in pre-commit. None of the five contain CR, so nothing is lost by the move. Your point stands though, inlining was the wrong shape for fixtures meant to be read as stored.

@wenzeslaus wenzeslaus left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While I think is acceptable with the minor fixes specified in the comments, clearly showing this is a migration of the test, I think changing the reference data to the current data makes sense and would simplify the test.

As for the files, since the original input and reference is ASCII files, we can keep them here and it will make the change of the reference clearly visible. However, if this would be written from scratch today, we would likely have a NumPy array as a literal in the code skipping all conversions for the reference data. Given we want an example of having data in files for tests and the value of keeping the tests same here, let's keep it using the files here, but let's not make it a rule.

Comment thread raster/r.fill.stats/tests/r_fill_stats_test.py Outdated
Comment thread raster/r.fill.stats/tests/r_fill_stats_test.py Outdated
Comment thread raster/r.fill.stats/tests/r_fill_stats_test.py Outdated
Update the reference data to what the tool produces now. In every mode the
northeast corner is the only cell that differs: the tool fills it and the
stored reference had it as null. With that one cell corrected the test is a
plain comparison again, so the known-corner constants and the surrounding
bookkeeping are gone.

Read the tool output and the reference through Tools as NumPy arrays instead
of converting with grass.script.array.

Drop the comments about where the fixtures came from and about the bytes on
disk. The first belongs in the commit message and the second is a general
point about file-based fixtures rather than anything specific to this tool,
which never reads the files itself.
@Valyrian-Code

Copy link
Copy Markdown
Contributor Author

Updated the reference data.
One cell per file, the northeast corner, which the tool fills and the reference had as null.

#8057 still covers the null-vs-value case that hid it.

@Valyrian-Code Valyrian-Code changed the title r.fill.stats: migrate tests from gunittest to pytest tests: Migrate r.fill.stats from gunittest to pytest Oct 22, 2026
@Valyrian-Code

Copy link
Copy Markdown
Contributor Author

Updated the reference data. One cell per file, the northeast corner, which the tool fills and the reference had as null. #8057 still covers the null-vs-value case that hid it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

module Python Related code is in Python raster Related to raster data processing tests Related to Test Suite

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants