Pin GTK and GDK to 3.0 for the repo-root test suite#950
Conversation
The tests/ suite (run by `python3 -m unittest discover -s tests`) imports gramps.gui.* modules directly, which bypasses the Gramps GUI launcher's own gi.require_version. On a host where GTK 4 is the default GI resolution, Gtk/Gdk then load unpinned — emitting PyGIWarning and risking the wrong stack (and the GUI-touching tests silently skipping). Pin both in tests/__init__.py, which `unittest discover -s tests` imports before any test module, so the whole repo-root suite runs on the GTK 3 / GDK 3 stack a real Gramps session uses. tests/test_gtk_version_pin.py guards it (skips where the 3.0 typelibs are absent). Verified: `python3 -m unittest discover -s tests -p "test_*.py" -t .` pins both (get_required_version == "3.0"); the guard is red without the pin. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
My typical approach is to run the tests manually. Will this migration to code in the upper level tests directory break the specific tests if they do not have the version pinning in
|
|
@GaryGriffin it only works for full runs over all tests, not manual - yet. Once 820 lands, the command looks like this PYTHONPATH=.github/scripts/gi_bootstrap python3 -m unittest Form.tests.test_form_validatorYou can make it work right now with python3 -m unittest tests.test_make_listing Form.tests.test_important is that you call tests.test_make_listing first. How about extending the make.py to commands like python3 make.py <gramps_version> <command> [addon]? |
|
Why not put it in the |
You could put it there, but then you need to make sure that every implementor thinks of this. I was trying to abstract it away from the Addon developer. The GraphView implemented it's own pinning and dependency loading which is great that the author thought of, but also counter productive because that broke the unit testing with dogtail and doesn't conform to the loading rules with Gramps. There are 2 ways to solve this: have clear guidelines on what the Addon developer must and musn't do or you need to find a way to abstract it. I have been building some guidelines which I will put up for review once I feel the quality is sufficient and I've seen there are contributing pages in the repository and more in the wiki itself. I've been working on automating it as well and we can include if 820 lands, but it's always better to hide such implementation details. This is here is the attempt of "abstracting" it which honestly works great if you are testing everything but breaks in your scenario. Ultimately, you have to choose your poison here. We can close this item and stick with the guideline approach if you like. |
|
I will always vote for the abstraction, and making it easy on the addon developer. This seems like a good compromise: |
I added some comments there. Great work. Question - does every addon test folder need the pinning? Or just some of them? I thought it was just some. I see 28 unittests currently and 14 have If all addons need Gtk/Gdk pinning, then abstraction makes sense. Is there any sense that in the future, there will be additional needs for pinning (easier to add in a single location rather than in each test case)? I see two users for testing: Developer generating tests; CI running tests. I have been focused on the first case. The second case gets automated. Is abstracting making it easier or harder for the developer to add a unittest? Do addon developers normally have a built source tree locally? That is needed for them to run As the maintainer, it would be much easier for me to use Sorry for the ramblings. |
Thanks, I'll make sure they find their way back in.
Not all need pinning necessarily - strictly speaking, only the ones that have any GUI elements. The core problem is that Gramps implements a certain environment and provides some infrastructure that the Addons can then use if they need to. GTK pinning and loading of dependencies are the two I'm currently aware of, there might be more or Gramps might choose to implement more sometime later. The Addon developer should be shielded from the "dirty details" to be able to focus on their core objective: building logic. The problem we've seen is that developers write their unit code with certain assumptions that don't hold true. For example the bsdbb tests (that's core, but the example still counts) was written with the assumption that bsdbb modules are installed and started failing on systems where they could no longer be loaded. The reason they didn't get noticed was because the Exception got swallowed, showing all green. Similar with the GraphView logic where the developer realized there were dependencies they needed to take care of, but didn't realize it was handled by Gramps and therefore wrote dependency loading logic. The problem was that it worked fine in the Gramps environment because it had already loaded there and the developer had written the logic without any infrastructure around it. You do need to provide a baseline and that can be the CI 820 PR, but that will make assumptions about the environment (e.g. loading dependencies, GTK pinning, etc.) that aren't given with the Addon unless the developer thinks of implementing it at Addon level. The result will be that the unit tests run fine for the Addon developer in their local environment and fail when trying to submit a PR.
Yes, you are right to ask about that. As I said: you need to choose which way you want to go, both are valid options. The reason I chose the "central" instead of "distributed" variant was that it's easier to change if the Gramps environment changes. It might end up breaking several Addons, but that's a benefit: we see which Addons have issues with whatever Gramps changes are introduced (e.g. a switch to Gtk 4.0) while in the distributed case, we'd have to update all Addons.
No, not necessary. We are extending what the make.py does.
That's an "flurish" which we can also drop. I was just considering if developers want to use it to test for the upcoming release, etc. like now: build it for 6.0 but test it for 6.1 to be ready.
We can do it that way.
I rather you questioning every aspect based on your experience then introducing something that doesn't fit. |
Independent of #820 (based on clean
maintenance/gramps60).What
The repo-root
tests/suite — run bypython3 -m unittest discover -s tests -p "test_*.py" -t .— importsgramps.gui.*modules directly, which bypasses the Gramps GUI launcher's owngi.require_version. On a host where GTK 4 is the default GI resolution,Gtk/Gdkthen load unpinned →PyGIWarningand the risk of loading the wrong stack (GUI-touching tests can silently skip).Pin both in
tests/__init__.py, whichunittest discover -s testsimports before any test module, so the whole repo-root suite runs on the GTK 3 / GDK 3 stack a real Gramps session uses:tests/test_gtk_version_pin.pyguards it (asserts both are pinned; skips where the 3.0 typelibs aren't installed).Verification
python3 -m unittest discover -s tests -p "test_*.py" -t .→ 3 tests OK, with the guard passing (get_required_version("Gtk"|"Gdk") == "3.0"). The guard is red without the pin (AssertionError: None != '3.0').Draft until review/sign-off.
🤖 Generated with Claude Code