플러그인에서 모델 또는 구성 요소를 커스텀 플러그인으로 가져오기: 테스트 실패

안녕하세요,
현재 Discourse 버전 3.5.0을 사용하고 있습니다.
저희는 Discourse의 다양한 요소를 오버라이드하고 자체 기능을 추가하는 자체 플러그인을 보유하고 있습니다.

이 플러그인에서 특히 composer의 도구바에 이벤트 추가 아이콘을 추가하려고 합니다. 이를 위해 다음을 가져와야 합니다:

  • plugins/discourse-calendar/assets/javascripts/discourse/models/discourse-post-event-event.js에 위치한 DiscoursePostEventEvent 모델

  • plugins/discourse-calendar/assets/javascripts/discourse/components/modal/post-event-builder.js에 위치한 PostEventBuilder 컴포넌트

또한, 플러그인 내 /test 디렉토리에 기능을 위한 통합 테스트를 작성했습니다.

import { visit } from "@ember/test-helpers";
import { test } from "qunit";
import { acceptance } from "discourse/tests/helpers/qunit-helpers";

acceptance("TOTO", function (needs) {
  test("coopaname integration - composer", async function (assert) {
    await visit("/");
    assert
      .equal(1, 1, "OK")
  });

});

원하는 동작은 구현할 수 있지만, 어떤 방식으로 import를 하든 테스트가 실패합니다.

파일 헤더에서 Import

파일 헤더에서 import 메서드를 사용하여 모델과 컴포넌트를 가져올 때:

import DiscoursePostEventEvent from "discourse/plugins/discourse-calendar/discourse/models/discourse-post-event-event";
import PostEventBuilder from "discourse/plugins/discourse-calendar/discourse/components/modal/post-event-builder";

실행 시에는 문제가 없지만, 테스트를 실행하면 테스트가 실행되지 않습니다.

파일 헤더에서 Require

파일 헤더에서 require 메서드를 사용하여 모델과 컴포넌트를 가져올 때:

const DiscoursePostEventEvent = require("discourse/plugins/discourse-calendar/discourse/models/discourse-post-event-event").default;
const PostEventBuilder = require("discourse/plugins/discourse-calendar/discourse/components/modal/post-event-builder".default;

실행 시에는 문제가 없지만, 테스트를 실행하면 테스트가 실행되지 않습니다.

이는 import를 사용했을 때와 동일한 결과를 보입니다.

파일 본문에서 Require

함수 본문에서 require 메서드를 사용하여 모델과 컴포넌트를 가져올 때:

import { withPluginApi } from "discourse/lib/plugin-api";

function initializeEventBuilder(api) {
  const DiscoursePostEventEvent =
     require("discourse/plugins/discourse-calendar/discourse/models/discourse-post-event-event").default;
  const PostEventBuilder =
     require("discourse/plugins/discourse-calendar/discourse/components/modal/post-event-builder").default;

  ... 나머지 코드
}

export default {
  name: "add-custom-create-event-button",
  initialize(container) {
    withPluginApi(initializeEventBuilder);
  },
};

실행 시에는 문제가 없지만, 테스트를 실행하면 실패합니다.

모델을 찾을 수 없다고 합니다.

요약하자면, 통합 테스트를 실행할 수 있도록 다른 플러그인에서 모델, 컴포넌트 등을 올바르게 가져오는 방법에 대해 알고 싶습니다.
감사합니다!

안녕하세요 @Marine

문제가 코드에서 needs.settings 블록에 잘못된 설정이 사용되고 있는 것 같습니다:

acceptance("Some tests", function (needs) {
  needs.settings({
    // This won't enable the right settings, so the calendar plugin won't be loaded, and the files we need won't be available
    // discourse_post_event_enabled: true, 
    // 
    // Enabling the calendar will solve the issue:
    calendar_enabled: true

    our_plugin_enabled: true
  });


  test("The test", async function (assert) {
    await visit("/");
    assert.equal(1, 1);
  });
});

음, 그것은 사실이 아닙니다. 플러그인이 이벤트 양식을 오버라이드하므로 discourse_post_event_enabledtrue로 설정해야 합니다. 그러면 플러그인에서 가져오기가 실패하는 초기 상태로 돌아가게 됩니다.

어떤 생각이 있으신가요?

qunit에서 플러그인을 테스트할 때, 해당 특정 플러그인의 JS만 로드합니다. 이는 여러 플러그인이 서로 상호작용할 때 발생할 수 있는 예상치 못한 문제를 방지하는 데 도움이 됩니다. 또한 플러그인이 다른 플러그인에 의도치 않게 의존하게 되는 것을 방지하는 데에도 도움이 됩니다.

질문자님의 경우, 상호작용이 의도된 것이며 사용자들이 항상 discourse-calendar를 활성화해 있을 것으로 기대하는 것 같습니다. 이 경우, about.json 파일에 설정을 추가하여 질문자님 플러그인의 테스트에서 discourse-calendar JS를 사용할 수 있게 만들 수 있습니다. 예시는 다음과 같습니다:

^^ 이 경우 discourse-assign을 추가하고 있습니다. 질문자님의 경우, 이를 discourse-calendar로 설정하면 됩니다.

감사합니다! about.json에 대해 몰랐는데, 덕분에 문제가 해결되었습니다. 이제 완전히 기능적인 컨텍스트를 다시 만드는 것은 저희 몫이네요 :wink:

다시 한번 감사합니다!

엔드투엔드 테스트를 위한 시스템 스펙에도 관심이 있을 수 있습니다. 이렇게 하면 실제 Discourse 서버를 대상으로 테스트가 실행되므로, 코어 및 두 플러그인의 모든 네트워크 요청을 가짜로 만들 필요가 없습니다.

단점은 훨씬 느리다는 것입니다. 따라서 가능하면 단위/컴포넌트 테스트는 qunit에 유지하는 것이 좋습니다.

좋은 팁 감사합니다!

보통 Rails 앱을 테스트할 때 RSpec이나 Cucumber를 사용하다 보니 시스템 스펙이 훨씬 더 익숙합니다. :slight_smile:

테스트 케이스에 따라 QUnit이나 RSpec 중 어떤 것이 테스트할 가치가 있는지 살펴보겠습니다.

지금은 수정하고 싶었던 프론트엔드 버그를 재현하는 데 성공했으니, QUnit 테스트를 좀 더 깊이 파고들 예정입니다.