Quizzes
52,985 views
31 min · 2 min read
9 steps
Advanced

How to create a multiple-choice coding quiz with auto-graded unit tests

Build a multiple-choice coding quiz that runs auto-graded unit tests to give learners instant, objective feedback. This guide walks you through planning questions, writing tests, integrating grading, and delivering results in a reliable, repeatable way.

Verified by pleasexplain editors
  1. Step 1: Define learning objectives clearly

    Write 3–6 specific objectives for the quiz, such as 'interpret for-loops' or 'use list comprehensions correctly.' Clear objectives let you design questions and tests that measure the exact skills you care about.

    [Illustration: clipboard with 5 bullet objectives and checkmarks]

  2. Step 2: Choose language and test framework

    Pick one programming language (e.g., Python) and a compatible test framework (e.g., pytest) so tests are consistent. Limiting to a single language reduces environment complexity and speeds grading by about 2x compared with multi-language setups.

    [Illustration: icons for a programming language and a test framework logo]

  3. Step 3: Design 8–12 multiple-choice items

    Create 8–12 questions that target the objectives and vary difficulty: 3 easy, 4 medium, 3 hard. For each question include one correct option and three plausible distractors that reveal common misconceptions.

    [Illustration: row of multiple-choice bubbles with one filled per question]

  4. Step 4: Write unit tests for each concept

    For every question theme, write 2–4 small unit tests that verify correct behavior; tests should run in under 200 ms each. Use deterministic inputs and assert exact outputs so auto-grader decisions are binary and reproducible.

    [Illustration: code editor window showing short unit test functions]

  5. Step 5: Map answers to test outcomes

    Define a clear mapping: each multiple-choice option corresponds to a specific test file or set. Selecting option A runs test set A; passing those tests yields full points for the item, enabling precise alignment between choice and behavior.

    [Illustration: diagram linking question choices to test files]

  6. Step 6: Implement secure execution environment

    Run tests in isolated containers or sandboxes with CPU and memory limits (e.g., 2 CPU cores, 512 MB RAM, 5 second timeout) to prevent infinite loops and protect the host. Isolation also ensures tests from different users do not interfere.

    [Illustration: server rack with shield and sandbox icon]

  7. Step 7: Build the grader and reporting UI

    Create a backend that executes tests, collects pass/fail results, and returns per-question scores and a summary report. Include timestamps and runtime per test; aim for overall grading latency under 3 seconds per submission.

    [Illustration: dashboard showing test results, scores, and runtime stats]

  8. Step 8: Pilot with 10–30 learners

    Run a 1–2 week pilot to collect failure modes, ambiguous distractors, and flaky tests. Use feedback to revise difficult questions and stabilize tests until test pass rates and learner feedback both rise by 20% or more.

    [Illustration: small group of users testing on laptops and writing notes]

  9. Step 9: Deploy and monitor at scale

    Deploy to production with logging, error alerts, and periodic re-run of tests to detect drift. Monitor metrics like average grading time, failure rate, and question difficulty monthly and iterate based on data.

    [Illustration: monitoring dashboard with charts and alerts]


  • Keep each unit test under 20 lines to stay focused and maintainable.
  • Seed tests with edge cases such as empty input and maximum size to discourage brittle solutions.
  • Use descriptive assertion messages so learners see why an answer failed in plain language.
  • Lock test dependencies to specific versions to avoid unexpected changes; pin versions for 6–12 months.
  • Provide a sample correct solution and expected outputs as a reference after quiz submission.
  • Limit file I/O in tests; prefer function-based inputs/outputs to simplify sandboxing.

  • Do not run untrusted code on the host machine without strong isolation; un-sandboxed code can leak data or consume resources.
  • Avoid ambiguous questions or multiple correct answers; they produce inconsistent grading and learner frustration.
  • Be wary of flaky tests that pass intermittently; they undermine trust—fix or remove any test with >1% non-deterministic failure rate.

Was this guide helpful?