Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is it possible to use this Test engine for integration tests? #37

Open
GasimGasimzada opened this issue Nov 18, 2023 · 4 comments
Open

Comments

@GasimGasimzada
Copy link

Does the backend or something matter for ImGui to work in this case? I want to somehow run Imgui tests using Google test but in an integration way where the real application is not running but I am calling Imgui to render the UI and then automatically clicking buttons etc and checking the results.

@ocornut
Copy link
Owner

ocornut commented Dec 13, 2023

I'm not sure I understand the question but the answer is probably yes.

where the real application is not running

The real application needs to be running, it's the one submitting ImGui widgets.
But you may use a "headless" application, aka one with no visible rendering context.

@GasimGasimzada
Copy link
Author

GasimGasimzada commented Dec 23, 2023

Basically, instead of running the full application that is very heavy in terms of all the functionality it has, I want to test each part of the application in isolation. In terms of testing strategy, instead of using E2E tests where the whole application is being run, I want to do integration tests where I mock some of the services that are not necessary for the UI (e.g Physics engine).

This is the type of test that I want to write (using GoogleTest):

// Function that I want to test
void renderEntityPanel(EntityDatabase &db, Entity entity) {
  If (Imgui::Begin("Entity panel")) {
    if (ImGui::Button("Add animator")) {
      db.set(entity, Animator{});
    }
    ImGui::End();
  }
}

TEST_F(EntityPanelTest, ClickingAddAnimatorCreatesAnimatorComponent) {
      auto imTest = IM_REGISTER_TEST(engine, "Tests", "test");
      imTest->TestFunc = [](auto *ctx) {
         ctx->SetRef("Entity panel");
         ctx->ItemClick("Add Animator");
      };

      EntityDatabase db;
      auto entity = db.create();

      ImGui::NewFrame();
      renderEntityPanel(db, entity);
      Imgui::Render();

      // I want to run the test function right here
      imTest->RunTestFunction();

      // Do I need to call `renderEntityPanel` again for the button to be registered?
      EXPECT_TRUE(db.has<Animator>(entity));
}

I have couple of questions to be able to achieve this:

  1. How can programatically run a registered test?

  2. In order to get this working, do I need to call

    ImGui::NewFrame();
    renderEntityPanel(db, entity);
    Imgui::Render();

    after the test function is run?

  3. Is there a guarantee that after a test function is run with item being clicked, if (ImGui::Button("Add animator")) condition will be true in the next frame?

@mgerhardy
Copy link

mgerhardy commented May 17, 2024

I'm not sure if this is the best approach - but I am doing this:

ImGuiTestEngineIO& test_io = ImGuiTestEngine_GetIO(_engine);
test_io.ConfigLogToTTY = true;

in the docking branch I don't want other windows to become visible

static void ImGui_ImplSDL2_NoShowWindow(ImGuiViewport *) {
}

[...]
ImGuiPlatformIO &platform_io = ImGui::GetPlatformIO();
platform_io.Platform_ShowWindow = ImGui_ImplSDL2_NoShowWindow;
[...]

this is not really headless - a NullBackend would most likely still be better, but for me it works to run it from the command line like this

ImGuiTestEngine_QueueTests(_engine, ImGuiTestGroup_Tests, "tests", ImGuiTestRunFlags_RunFromCommandLine);

Find most of my solution here https://github.com/vengi-voxel/vengi/blob/a2be632581a9883ab28811d9386718c390559d3f/src/modules/ui/IMGUIApp.cpp

@ocornut
Copy link
Owner

ocornut commented May 17, 2024

This made me realize that it may be worth extracting the "null viewport backend" support from shared/imgui_app.cpp into a more regular backend or file which may be used for that purpose (without requiring user app to use imgui_app.cpp which of course his our own helper).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants