ocornut / imgui_test_engine

Dear ImGui Automation Engine & Test Suite
386 stars 40 forks source link

Idea: testing language bindings by comparing "screen recordings" of imgui_demo #31

Open oprypin opened 9 months ago

oprypin commented 9 months ago

Hi!

I maintain a bindings project for another programming language. I always cover the whole API and port over the whole imgui_demo.

I don't have any tests, I just sometimes check if the reimplementation of the demo still works as expected, by poking around it manually. If something doesn't look right, I can't be sure whether the bug is in the bindings themselves or in my port of the demo, but either way it's a bug for me to solve. To make this slightly more convenient, I also have the original C++-based demo window opened right next to it, for comparison.

So my testing session might look like this (click to see screenshot) ![screenshot](https://github.com/ocornut/imgui_test_engine/assets/371383/58ac723c-fa5c-4269-accc-60307239c0f8)

Manual testing is not sustainable at all, though.


So the main idea people might think of instead is to also bind "imgui_test_engine" to the destination language and port "imgui_test_suite" to it. But that's waaay too much work. Let's think outside the box – maybe we can somehow just automate my manual testing steps?


Having a reimplementation of imgui_demo (the crucial part) alongside the C++ original imgui_demo can actually open an interesting and kinda lazy approach for making a test – we'll just check that the reimplementation behaves identically to the original. Specifically, make several tests like this:

But when thinking about this historically, I was stopped by several challenges – which actually all seem to have a direct solution in this repository.

  1. I don't know what exactly would be a good way to record all inputs on a timeline, as well as record graphical outputs in a way that's not wasteful and not affected by timing artifacts.

    • From my initial understanding, "imgui_test_engine" has already solved this challenge as part of its implementation, so that's great.
  2. My handmade recordings of clicks might become obsoleted by changes to Dear ImGui (even any minor design changes) and actually also changes to imgui_demo itself. So this is not future-proof at all.

    • Luckily seems like another thing that "imgui_test_engine" can do is synthesize a series of inputs based on declarations of "what to do". So, great, I could just write the declarations instead, then record the synthesized inputs (or even synthesize on the fly, of course). At least I assume that this repository can be reused to synthesize and replay inputs on another arbitrary window.
  3. Maybe I'm too lazy to actually write declarative tests or think of interesting test cases. Can't I just take them from someone who already wrote them?

    • Well... this repository is the real motherload, then! Even though many of the tests first create their own window to then interact with (meaning I'd have to port at least all the t->GuiFunc method bodies), a large chunk of tests simply reuses the imgui_demo window, which I already have ported! So with this single requirement, all these tests (filtered as ./imgui_test_suite demo, as I understand) can be reused directly!
  4. Oh but surely porting all those asserts that are written in C++ is too much work?

    • That's a trick question! No, we'll just ignore the asserts and only use the "screen recording". If the bindings-based demo produces an identical recording, then surely it would've passed the asserts as well.

In summary, if I just somehow wire all this machinery together, I should be able to get a large test suite for correctness of language bindings without writing a single test method body myself.

For now I'm just sharing this idea here, I hope this can inspire people, and eventually I'll probably ask for some assistance with understanding this repository and picking it apart :sweat_smile: Also I hope I'm not saying something that's already widely known. Or if that's the case, great, point me that way!