How to test a SCORM package before the LMS does

A checklist for validating a SCORM course before you hand it to a customer: manifest, launch, bookmark, completion, commit timing, and the runtime quirks of the platform it is going to.

Why "it opened on my machine" is not a test

Opening index.html from the unzipped package proves the content renders. It proves nothing about SCORM, because there is no API object to find, so the content either fails silently or runs in a fallback mode that never writes a value. The failures that matter — a manifest the LMS rejects, a bookmark that never saves, a completion that arrives too late — only show up with an LMS-like player that exposes the API and records every call. Test in one of those, every time, before upload.

Step 1: validate the manifest

The LMS reads imsmanifest.xml before it does anything else, and a large share of import failures stop here. Validate it against the schema it declares. The errors that come up most:

  • The manifest is not at the root of the zip (it is inside a folder because the zip was made from a parent directory).
  • A resource href points to a file that is not in the package, or the case differs (Index.html vs index.html — fine on Windows, fatal on Linux-hosted LMSs).
  • Missing or duplicate identifier attributes.
  • A SCORM 2004 package declared with SCORM 1.2 namespaces, or the reverse.
  • Sequencing rules that reference an item that does not exist.

A validator that reports these in plain language, with the line number, turns a half-day of guessing into a two-minute fix.

Step 2: launch and watch the runtime log

Launch the package in a test player and read the calls as they happen. A healthy first launch looks like this:

00:00.04  Initialize("")                  → "true"
00:00.06  GetValue("cmi.learner_name")    → "Test Learner"
00:00.07  GetValue("cmi.entry")           → "ab-initio"
00:00.09  GetValue("cmi.suspend_data")    → ""
00:04.51  SetValue("cmi.location","p2")   → "true"
00:04.52  Commit("")                      → "true"

What you are looking for: Initialize is called exactly once and returns true; the content reads entry and suspend data before writing anything; and a SetValue for location or suspend data appears when you move to the second page. If nothing is written as you navigate, the course will not bookmark. If Initialize is called twice, some LMSs will reject the second call and the session falls apart.

Step 3: resume, then finish

Close the content partway through. Reopen it. Confirm that cmi.entry now returns "resume", that the content reads its suspend data and actually lands on the page you left, and that it did not reset your progress. Then go to the end and complete whatever the course defines as finished. You want to see the status values written, a final Commit, and a single Terminate — in that order, and before the window closes. A course that writes completion and then closes the window without committing will work on forgiving LMSs and lose completions on strict ones. This is the mechanism behind most "lost completion" tickets; Why SCORM completions go missing goes through the rest.

Step 4: check the order of score and status

Some LMSs treat the first arrival of completed or passed as final and ignore later writes to the same attempt. If the content sets status first and score second, those platforms record a pass with no score. The correct order is score, then success, then completion, then commit:

SetValue("cmi.score.scaled", "0.84")
SetValue("cmi.success_status", "passed")
SetValue("cmi.completion_status", "completed")
Commit("")

A conformance report should flag this ordering explicitly; it is cheap to check and expensive to discover in production.

Step 5: replay against the target platform

Every LMS implements the runtime slightly differently. Some throttle Commit to once every few seconds and drop calls in between. Some enforce the suspend-data limit strictly; others silently truncate; a few ignore it. Some reject unknown data model elements; others accept anything. A package that passes the generic player can still fail on the customer's platform because of these differences.

The practical answer is a saved profile per platform: a set of runtime behaviours — commit cadence, suspend ceiling, strictness on unknown elements, how a missing score is handled — that the test player applies when replaying your session. Running the same registration against the Moodle profile and then the SuccessFactors profile shows you which behaviours the package depends on. A passing profile means the package behaved correctly under those conditions; it is not a vendor certification and should not be described as one. SCORM Central ships profiles for the common platforms and lets you run a registration against each.

A checklist you can paste into a ticket

  1. Manifest at zip root; validates against declared schema; all hrefs resolve with matching case.
  2. First launch: one Initialize, entry is ab-initio, suspend data empty.
  3. Navigation writes location and/or suspend data, followed by Commit.
  4. Suspend data stays under the cap (4 KB for 1.2, 64 KB for 2004) with headroom.
  5. Close and reopen: entry is resume, content lands on the saved page.
  6. Completion is set exactly when the documented rule says, not earlier.
  7. Order at the end: score → success → completion → Commit → Terminate.
  8. Replayed against the target platform's profile with no failures, and any warnings understood.

Attach the runtime log and the conformance report to the delivery. When the customer's administrator asks why a learner shows incomplete, you will have the evidence rather than a theory.

Keep reading

How-to4 min Convert SCORM to video or PowerPoint? Can you convert SCORM to MP4, HTML5 or PowerPoint? What is inside a package, the routes that work, and what you lose with each one. Explainer4 min Does your LMS support xAPI? How to check What xAPI LMS support really means: launching xAPI content, a built-in LRS, or forwarding statements. The questions to ask and a quick test to run. Explainer4 min LMS vs LRS: what is the difference? LMS vs LRS: an LMS runs courses and learners; an LRS stores xAPI statements. Why SCORM does not use an LRS, and when you need both.

Start with one file.

Upload something you already have and see it as a package, with the conformance report and the runtime log alongside it.

→ upload  handbook.pdf
  parsing … 14 sections
  building manifest …
  validating … 0 errors, 2 notes
✓ handbook-scorm2004.zip
✓ preview link ready