Playwright를 활용한 SCORM e러닝 패키지 자동 테스트 — 단계별 가이드
출처: 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