Playwright를 활용한 SCORM e러닝 패키지 자동 테스트 — 단계별 가이드

발행: (2026년 6월 12일 AM 06:44 GMT+9)
6 분 소요
원문: Dev.to

출처: Dev.to

대부분의 테스트 튜토리얼은 e‑learning을 전혀 다루지 않습니다. 여기서는 SCORM 패키지가 실제로 LMS 플랫폼 전반에서 정상 작동하는지 검증하는 Playwright 테스트 스위트를 구축하는 방법을 소개합니다.

왜 e‑Learning 테스트는 다를까

SCORM 패키지를 LMS에 배포하고 나서 완료 기록이 남지 않거나, 퀴즈 점수가 사라지거나, 네비게이션이 깨지는 상황을 겪어본 적이 있다면 그 고통을 잘 아실 겁니다. e‑learning 콘텐츠는 일반 웹 애플리케이션과 다르게 동작합니다. LMS가 제공하는 iframe 안에서 실행되고, JavaScript API(SCORM Runtime)를 통해 통신하며, 어느 LMS에서 호스팅되는가에 따라 동작이 달라집니다.

3~4개의 서로 다른 LMS에서 수동 QA를 진행하는 것은 느리고 실수가 잦습니다. 이 튜토리얼에서는 Playwright를 사용해 SCORM 패키지 테스트를 자동화하는 과정을 단계별로 안내합니다—기본 콘텐츠 로딩부터 API 호출 검증, 완료 상태 확인까지.

사전 준비

시작하기 전에 다음이 설치되어 있어야 합니다:

  • Node.js 18+ 설치
  • Playwright (npm init playwright@latest)
  • SCORM 1.2 또는 2004 패키지 (e‑learning 콘텐츠가 들어 있는 .zip 파일)
  • 테스트용 로컬 LMS — 여기서는 SCORM Cloud(무료 플랜) 또는 간단한 SCORM API shim을 사용할 것입니다.

Step 1: 로컬 SCORM Runtime Shim 설정

SCORM 콘텐츠를 테스트하려면 LMS가 제공하는 API를 흉내 내는 것이 필요합니다. 전체 Moodle 인스턴스를 띄우는 대신 가벼운 shim을 만들겠습니다.

scorm-api-shim.js 파일을 생성합니다:

// scorm-api-shim.js
// Mimics the SCORM 1.2 Runtime API that an LMS would expose

window.API = {
  _data: {},
  _initialized: false,
  _calls: [],

  LMSInitialize: function(param) {
    this._initialized = true;
    this._calls.push({ method: 'LMSInitialize', param, timestamp: Date.now() });
    console.log('[SCORM] LMSInitialize called');
    return "true";
  },

  LMSGetValue: function(key) {
    this._calls.push({ method: 'LMSGetValue', key, timestamp: Date.now() });
    return this._data[key] || "";
  },

  LMSSetValue: function(key, value) {
    this._data[key] = value;
    this._calls.push({ method: 'LMSSetValue', key, value, timestamp: Date.now() });
    console.log(`[SCORM] SetValue: ${key} = ${value}`);
    return "true";
  },

  LMSCommit: function(param) {
    this._calls.push({ method: 'LMSCommit', param, timestamp: Date.now() });
    return "true";
  },

  LMSFinish: function(param) {
    this._calls.push({ method: 'LMSFinish', param, timestamp: Date.now() });
    this._initialized = false;
    return "true";
  },

  LMSGetLastError: function() { return "0"; },
  LMSGetErrorString: function(code) { return "No error"; },
  LMSGetDiagnostic: function(code) { return ""; }
};

Enter fullscreen mode

Exit fullscreen mode

이 shim은 모든 SCORM 호출을 로그에 남기며, 이를 테스트 어설션 레이어로 활용할 수 있게 해줍니다.

Step 2: SCORM 패키지를 로컬에서 제공

SCORM 패키지를 압축 해제하고 간단한 HTTP 서버로 제공합니다. serve-scorm.js 파일을 생성합니다:

// serve-scorm.js
const express = require('express');
const path = require('path');
const app = express();

// Serve the SCORM API shim at the parent level (LMS frame)
app.get('/lms', (req, res) => {
  res.send(`
    
    
    
      Test LMS
      
    
    
      
      
    
    
  `);
});

app.use('/scorm-api-shim.js', express.static(path.join(__dirname, 'scorm-api-shim.js')));
app.use('/scorm-content', express.static(path.join(__dirname, 'unzipped-scorm-package')));

app.listen(3000, () => console.log('Test LMS running at http://localhost:3000/lms'));

Enter fullscreen mode

Exit fullscreen mode

실행:

npm install express
node serve-scorm.js

Enter fullscreen mode

Exit fullscreen mode

http://localhost:3000/lms에 접속하면 iframe 안에 SCORM 콘텐츠가 로드되고, 콘솔에 API 호출 로그가 표시됩니다.

Step 3: 첫 번째 Playwright 테스트 작성 — 콘텐츠 로드 및 초기화 확인

tests/scorm-basic.spec.js 파일을 만들고 다음 코드를 넣습니다:

// tests/scorm-basic.spec.js
const { test, expect } = require('@playwright/test');

test.describe('SCORM Package - Basic Validation', () => {

  test('should load content and call LMSInitialize', async ({ page }) => {
    await page.goto('http://localhost:3000/lms');

    // Wait for the content iframe to load
    const frame = page.frameLocator('#content-frame');
    await frame.locator('body').waitFor({ state: 'visible' });

    // Check that LMSInitialize was called
    const initCalled = await page.evaluate(() => {
      return window.API._calls.some(c => c.method === 'LMSInitialize');
    });

    expect(initCalled).toBe(true);
  });

  test('should set lesson_status to incomplete or browsed on load', async ({ page }) => {
    await page.goto('http://localhost:3000/lms');

    const frame = page.frameLocator('#content-frame');
    await frame.locator('body').waitFor({ state: 'visible' });

    // Give the content a moment to make its initial API calls
    await page.waitForTimeout(2000);

    const lessonStatus = await page.evaluate(() => {
      return window.API._data['cmi.core.lesson_status'];
    });

    // SCORM content typically sets status to 'incomplete' or 'browsed' on launch
    expect(['incomplete', 'browsed', 'not attempted']).toContain(lessonStatus);
  });

});

Enter fullscreen mode

Exit fullscreen mode

테스트 실행:

npx playwright test tests/scorm-basic.spec.js

Enter fullscreen mode

Exit fullscreen mode

Step 4: 퀴즈 상호작용 추적 테스트

SCORM 패키지에 퀴즈가 포함돼 있다면, 상호작용 데이터가 올바르게 기록되는지 확인해야 합니다. 대부분의 LMS 호환성 버그가 여기서 발생합니다.

// tests/scorm-quiz.spec.js
const { test, expect } = require('@playwright/test');

test.describe('SCORM Package - Quiz Interactions', () => {

  test('should record interaction data when answering a quiz question', async ({ page }) => {
    await page.goto('http://localhost:3000/lms');

    const frame = page.frameLocator('#content-frame');

    // Navigate to the quiz slide (adjust selectors to your content)
    // This will vary based on your authoring tool's output
    await frame.locator('[data-slide="quiz-1"]').click();

    // Select an answer
    await frame.locator('.answer-option').first().click();

    // Submit the answer
    await frame.locator('.submit-btn').click();

    // Verify interaction was recorded via SCORM API
0 조회
Back to Blog

관련 글

더 보기 »