
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
gradingAutomatische Überprüfung von Programmieraufgaben, die über Moodle abgegeben wurden.
[[TOC]]
Unter Moodle wurde eine Aufgabe erstellt, die die Studenten lösen müssen. Die Lösung ist eine Zip-Datei, die über Moodle hochgeladen wird. Die Lösungen sollen nun irgendwie automatisch, meist mittels Tests, korrigiert werden und die Ergebnisse zu Punkten bzw. Noten umgerechnet werden. Die Bewertung soll dann in Form von Bewertungstabellen und PDFs wieder in Moodle den Studenten bereitgestellt werden.
Die Durchführung der Korrektur und die Bewertung sind Programmiersprachen unabhängig. Lediglich folgende Voraussetzungen müssen erfüllt sein:
Folgende Tools müssen vorliegen:
Das Tool geht davon aus, dass die eigentliche Korrektur einer Docker-Umgebungen durchgeführt wird, da so eindeutige Bedingungen geschaffen werden können und Zugriff des studentischen Codes auf das System des Korrektors verhindert wird. Falls Docker verwendet wird, sollte mind. Version 20 eingesetzt werden, da ansonsten Probleme beim Mounten der Verzeichnisse (mit Leerzeichen) auftreten können.
Das Tool trifft weitere Annahmen, die aber über Konfigurationseinstellungen geändert werden können:
check/tests der Musterlösung liegen.check/exam.grading.jsonEs gibt drei Möglichkeiten:
Grading global installieren: npm install --global grading. Nun kann Grading einfach über grading aufgerufen werden.
Falls Grading aktualisiert wurde, kann das Update mit npm update -g grading installiert werden.
Grading direkt ausführen über npx grading
Grading klonen und im Verzeichnis des Klons (also grading)
npm run build
und
npm link
aufrufen. Nun kann Grading einfach über grading aufgerufen werden. Diese Variante ist sinnvoll, wenn an Grading selbst Änderungen durchgeführt werden sollen.
Falls der Ordner des Klons gelöscht wurde oder grading nicht mehr global erreichbar sein soll, kann dies mit
npm unlink -g grading
gelöscht werden (unlink ist ein Alias für rm bzw uninstall).
Im Folgenden wird davon ausgegangen, dass Grading mittels grading aufgerufen werden kann.
Von Moodle beim der Aufgabe (unter "Alle Abgaben anzeigen" > "Bewertungsvorgang") folgende Dateien laden:
Achtung: Die Bewertungstabelle enthält je nach Konfiguration der Aufgabe unterschiedliche Spalten. Es ist wichtig, dass die Bewertungseinstellung wie folgt konfiguriert ist:
Beide Dateien am besten nach gradingIn verschieben.
Zur initialen Erstellung des Bewertungsschemas und der Ordnerstruktur für die Tests kann
grading init
aufgerufen werden.
Im allgemein ist der letzte Schritt nicht notwendig, da man meist die Dateien aus einem vorherigen Aufgabenblatt übernimmt.
Die automatische Überprüfung besteht aus drei bzw. vier Schritten:
grading prepare
Damit wird die Musterlösung geprüft. Dies dient v.a. zum Test, ob generell eine Bewertung durchgeführt werden kann.
U.a. kann hier auch ein Cache erstellt werden, in diesem Fall ist dieser Schritt notwendig.
So kann bspw. gradingOut/cache/node_modules in Docker gemounted werden (Setting ' --volumes'), womit man sich dann bei eigentlichen Check das npm install spart.
grading check «gradingIn/submissions.zip»
Wenn keine Zip-Datei angegeben wird, wird im Standard-Eingabeverzeichnis (gradingIn) automatisch eine Zip-Datei gesucht. Vorbereitung der Einreichung und Starten der Tests
git reset --hard (prepareSubmission), ggf. Patch einspielennpm installnpm buildnpm test -- Tests in der Einreichungnpm test --config checks/jest.check.config.js -- Tests zum GradingDa der Check sehr lange dauern kann (bspw. 30 Minuten bei 80 Einreichungen), sollte man dies unter macos mit dem Tool caffeinate starten, damit der Rechner in den 30 Minuten nicht
in den Sleep-Mode geht. Also:
caffeinate grading check «gradingIn/submissions.zip»
Tipp: Zur Optimierung bietet es sich an, bspw. das node_modules-Verzeichnis beim Vorbereiten (grading prepare) zu erstellen und dann beim Check wiederzuverwenden.
Dazu muss das Verzeichnis (am besten im Cache-Ordner von gradingOut) in Docker gemountet werden (mittels --volumes). Und natürlich muss als erstes grading prepare aufgerufen werden.
In den Skripten kann die Phase mittels der Umgebungsvariablen PHASE abgefragt werden.
In jedem Fall wird unter gradingOut ein Log des Check-Laufs erstellt.
Bewerten (grading) der Einreichungen
grading grade
Wenn keine CSV-Datei angegeben wird, wird im Standard-Eingabeverzeichnis (gradingIn) automatisch eine SV-Datei gesucht.
Mit Latex-Template und Latex-Fragment für jeden Studenten ein Ergebnis PDF erstellen.
grading pdf
Diese Schritte sind mit dem CLI-Tool grading alle auszuführen.
Obige Schritte können auch gezielt für eine Abgabe durchgeführt werden, siehe dazu unten unter Verwendung.
Upload der Ergebnisse nach Moodle (ebenfalls unter (unter "Alle Abgaben anzeigen" > "Bewertungsvorgang")
gradingOut/Bewertungen-«Aufgabenname»_graded_«Zeitstempel».csv;
Wichtig: Update von Datensatzen zulassen unbedingt im Moodle-Upload ankreuzen! Die Tabelle ist UTF-8 mit Komma getrennt.gradingOut/pdfReports_«Zeitstempel».zipZur Bewertung wird ein Grading-Schema benötigt. Dies muss in JSON spezifiziert werden. Mit
grading prepare -cg «somename.grading.json»
wird ein initiales Schema aus den Check-Tests erstellt.
Im Schema können Kommentare angegeben werden. Damit in VSCode der Editor dort keine Fehler anzeigt, empfiehlt sich die folgende Einstellung:
"files.associations": {
"*.grading.json": "jsonc"
}
{
"$schema": "https://gitlab.bht-berlin.de/nodepackages/grading/-/raw/main/src/grade/grading.schema.json",
"course": "Web-Engineering 1",
"term": "SS 2024",
"exam": "Blatt 03",
"points": 100,
"minCoverageStatements": 95,
"penaltiesCoverageMax": 15,
"extraCoverageMax": 5,
"tasks": [
{
"name": "inverseCaseSingleLetter",
"suite": "inverseCaseSingleLetter.check.ts",
"points": 20,
"preconditions": [
{
"test": "Funktion inverseCaseSingleLetter wurde implementiert",
"suite": "isImplemented.check.ts"
}
],
"grading": [
{
"points": 15,
"text": "Positivtests für inverseCaseSingleLetter",
"tests": [
"A -> a",
"Z -> z",
]
},
{
"points": 5,
"text": "Negativtests für inverseCaseSingleLetter",
"tests": [
"Fehler weil kein Zeichen",
"Fehler weil mehr als ein Zeichen"
]
}
],
"penalties": [
{
"points": -5,
"text": "Keine Verwendung von Arrays",
"suite": "implementationConstraintsInverseCase.check.ts",
"tests": [
"inverseCaseSingleLetter darf kein Array verwenden."
]
}
],
"manual": false
},
...
]
}
Zusätzlich können manuelle Korrekturen vorgenommen werden. Diese müssen ebenfalls in einer JSON-Datei angegeben werden.
Am besten sollte die Datei mit manuellen Korrekturen angelegt werden, wenn bereits ein Check und ein Grading gelaufen ist. Dann wird die Datei mit Einträgen für alle Abgaben vorgefüllt (ansonsten ist die Datei leer). Die Datei kann erzeugt werden mit
grading init --generateCorrectionsFile
In der Korrektur-Datei können Kommentare angegeben werden. Damit in VSCode der Editor dort keine Fehler anzeigt, empfiehlt sich die folgende Einstellung:
"files.associations": {
"*.correction.json": "jsonc"
}
Die manuelle Korrektur sollte unter dem Namen manual.corrections.json abgelegt werden. Sie könnte bspw. so aussehen:
{
"exam": "Blatt x",
"course": "Web-Engineering",
"term": "WS 2022/23",
"corrections": [
{
"submissionID": "123456",
"userName": "Some Name",
"general": [
{
"points": -5
"reason": "Die Formatierung des Codes ist insgesamt grauenhaft"
}
],
"tasks": [
{
"name": "Some Task",
"points": 10
"reason": "Extrem elegante Lösung!"
}
]
}
]
}
Man kann bei den Punkten in General auch "absolute"=true angeben, um als Korrektor vollkommen manuell die Note zu setzen!
Der Reason kann als einzelner String oder Array angeben werden -- dies ist aber nur zur besseren Lesbarkeit und hat ansonsten keine Auswirkungen.
{
…
"corrections": [
{
"submissionID": "123456",
"userName": "Some Name",
"general": [
{
"points": 0,
"absolute": true,
"reason": "Plagiat erkannt"
}
]
},
{
"submissionID": "7891233",
"userName": "Another Student",
"general": [
{
"points": 50,
"absolute": true,
"reason": [
"Nach manueller Sichtung gerade noch bestanden.",
"Task x wurde grundsätzlich schon gelöst, aber die Korrektur kann nicht ausgeführt werden."
]
}
]
}
]
}
Es müssen keine Punkte angegeben werden, dann ist die manuelle Korrektur (reason) ein reiner Kommentar.
Manchmal ist es notwendig, eine Submission für die Korrektur leicht zu bearbeiten. Dies kann der Fall sein, wenn in der Submission irgendeine kleinere Sache bewirkt, dass die Korrektur nicht ausgeführt werden kann. Damit die Korrektur dokumentiert und reproduziert werden kann, muss diese irgendwie gespeichert werden.
Tatsächlich werden normalerweise bei jedem Aufruf von grading check die Projektverzeichnisse aller Abgaben gelöscht und neu erstellt. D.h. in diesem Fall geht eine Korrektur verloren.
Damit dies sinnvoll möglich ist, muss die Submission ein git-Repository sein. Nur so können die Änderungen sinnvoll verwaltet werden.
Wenn Korrekturen durch den Dozenten vorgenommen werden soll, ist wie folgt vorzugehen:
grading check (evtl. auch einfach grading check --prepareSubmission) werden die Projektverzeichnisse der Submission erstellt.--patchGradingBranch konfiguriert werden. Per Default ist dieser grading:
git checkout -b grading
grading check --skipPrepareSubmission --selected ...
wird ein Check-Lauf gestartet, wobei das Projektverzeichnis nicht verändert wird.jest --config check/tests/jest.check.config.js
git commit -am "fixed something"
Die Commit-Message erscheint nirgends und ist daher irrelevant.
Natürlich können auch mehrere Commits durchgeführt werden.grading diff
für alle Submissions Patch-Files erstellt werden. Diese werden per Default in gradingIn/patches erstellt, die kann mit patchFolder konfiguriert werden.
Der Diff wird zwischen dem Branch der Submission, normalerweise main (konfigurierbar mit patchSubmissionBranches) und dem Grading-Branch berechnet.Wenn bei grading check ein Patch für die Submission gefunden wird, wird diese automatisch angewendet. Falls dies nicht erfolgen soll, kann dies mit -no-patch ausgeschaltet werden.
Tatsächlich wird der Patch auf den automatisch erstellen Grading-Branch angewendet und dort auch committed. Auf diese Weise können so bei Bedarf weitere Korrekturen nach obigem Schema durchgeführt werden.
Die Patches werden nicht automatisch beim Grading oder im Report berücksichtigt. Bei Bedarf ist im Korrektur-File ein Eintrag zu machen, dort können auch ggf. Punkte abgezogen werden.
Falls mehrere Abgaben in einem Semester erfolgen, sollen die Ergebnisse in einer Tabelle zusammengefasst werden. Dazu kann mit
grading conclude
eine Excel-Tabelle erstellt werden.
Dabei werden auch vorangegangene Ergebnisse berücksichtigt. Diese werden in einem Verzeichnis resultsDir gesucht. Dorthin wird dann auch das aktuelle Ergebnis sowie die Zusammenfassung kopiert.
Je nach Endung des conclusionFile wird eine CSV oder Excel-Tabelle erzeugt.
Mehr Hilfe findet man unter
grading conclude --help
Mit
grading init --generateManualConclusionFile
kann außerdem eine JSON-Datei mit manuellen Eintragungen für die Zusammenfassung erzeugt werden. In dieser Datei kann man manuell Noten eintragen (bspw. für Plagiate) oder Aliases erfassen (es kommt manchmal vor, dass in Moodle während des Semesters der Name von Studenten geändert wird).
{
"course": "Web-Engineering 2",
"term": "SS 2024",
"conclusions": [
// {"userName": "Max Muster", "totalGrading": 0.0, "gradingReason": "", "generalRemark": "" },
// ...
{
"userName": "Mickey Mouse",
"totalGrading": 5.0,
"gradingReason": "Plagiate Blatt 06 und 07",
"generalRemark": ""
}
],
"aliases": [ // for renamed students (or names changed otherwise, e.g., typos)
[
"Twix Sun",
"Raider Sonne"
]
]
}
Die PDF-Reports (Kommando grading pdf) werden mit LaTeX erstellt. Dazu wird ein LaTeX-Fragment (bspw. gradingOut/reports/results.tex) erstellt, welches dann in eine LaTeX-Datei eingebunden wird.
Es können Bilder und Listings (bspw. Konsolen-Ausgaben) eingebunden werden. Diese müssen im Grading-Schema definiert werden, bspw.
"image": {
"src": "someScreenshot.png",
"text": "Screenshot der App",
"width": "5cm"
}
Ein Bild kann entweder einen Task oder einem Grading zugeordnet werden, entsprechend werden die Bilder auch in der Ausgabe im PDF positioniert.
Neben Bildern (PDF, PNG, JPG) können auch Text-Ausgaben mit Listings eingebunden werden. Grundsätzlich werden diese wie Grafiken behandelt, d.h. sie müssen im Grading-Schema definiert werden, bspw.
"image": {
"src": "someOutput.txt",
"text": "Konsolenausgabe"
}
Anhand der Endung wird versucht, eine Sprache von lstlistings zu erkennen. Folgende Sprachen werden unterstützt (und ggf. werden eigene Sprachdefinitionen benötigt): Java, JavaScript, TypeScript, HTML, CSS, Bash, XML, JSON, EBNF.
Die Bilder oder Ausgaben müssn im Verzeichnis gradingOut/reports/_${submissionID}_img liegen, damit sie in das PDF eingebunden werden können. Typischerweise wird man die Bilder während der Testausführung speichern und dann im Script, dass die Ausführung steuert (checkInDocker.sh) kopieren, also
echo "6.1. Copy out (screenshots)................................................"
[ -d "out" ] && rm -rf "/reports/_${SUBMISSIONID}_img"
[ -d "out" ] && cp -r out "/reports/_${SUBMISSIONID}_img"
Neben den Repors für einzelene Aufgaben können auch Summaries erstellt werden (Kommand grading summary).
Hierbei werden für alle Teilnehmer, die in irgendeiner Abgabe auftauchen, die Ergebnisse zusammengefasst.
Die Regeln für die Bewertung entsprechen den Regeln der Conclusions -- im Grunde ist das Summary also nichts anderes, als jede Zeile der Concludions für einzelne Teilnehmer entsprechend aufgebereitet.
Grading bietet mehrere "Commands" an, jedes "Command" hat wieder eigene Optionen.
Die allgemeine Hilfe (siehe unten) kann mit
grading --help
ausgegeben werden.
Für jedes Command kann man eine eigene Hilfe ausgeben, bspw.
grading check --help
Usage: grading [options] [command]
Automatically grade submissions in the context of Moodle and programming classes.
Options:
-V, --version output the version number
-h, --help display help for command
Commands:
init [options] Create check folder with default docker script and latex template
check [options] [zipFile] Starts docker container for each student and runs students and check tests to create reports
grade [options] [moodleFile] Grades submissions based on grading schema, submissions and unit reports previously created via check.
pdf [options] Create PDF reports using LaTeX based on results previously created via grade.
prepare [options] [solutionFolder] Prepare grading based on solution.
selected [options] <selected...> Grade selected submissions, similar to using check, grade and pdf with selected option.
compare [options] <oldCSV> <newCSV> Compares two result showing changes in grading.
diff [options] Uses git diff to create patch files from the diff between the submitter's branch and a branch created by the
lecturer. Theses patch files can be then applied later on when the submission is checked again, i.e. after the
submission has been recreated from the submissions zip file. In order to work, the submissions must have been
prepared and the lecturer must have created a branch with the changes. This feature only works if submissions
include a git repository.
conclude [options] Concludes final results from multiple exam results.
help [command] display help for command
Fast alle Einstellungen können über die Kommandozeile verändert werden.
Alternativ können in einer Datei .grading/setting.json Einstellungen definiert werden.
Diese Datei (bzw. der Ordner .grading) wird in der Verzeichnisstrutkur auch in darüber liegenden Verzeichnissen gesucht und die dortingen Einstellungen gemerged.
Dadurch kann man bspw. im User-Verzeichnis persönliche Einstellungen speichern, im Kurshauptverzeichnis die meisten Einstellungen für den Kurs. Meistens benötigt man nicht mehr.
Dann entfallen fast immer alle Kommandozeilenoptionen und man kann den ganzen Vorgang einfach durchführen mit
grading check
grading grade
grading pdf
Um eine Settings-Datei mit Hilfe zu erzeugen, einfach
grading init --generateSettings
aufrufen. Es wird dann im aktuellen Verzeichnis unter .grading/settings.json eine Datei erzeugt.
Achtung: Änderungen sind in neueren Versionen möglich.
{ /* Settings file for grading, values maybe overwritten in subfolder settings or command line arguments, overwrites values in parent folders. */
/* init, check, grade, pdf, prepare, selected, compare, diff, conclude */
// "debug": false, /* Emit debug messages (which may be different from verbose) (boolean)*/
// "quiet": false, /* Quiet mode, emit only errors (boolean)*/
// "verbose": false, /* Emit verbose messages (boolean)*/
/* check, grade, pdf, prepare, selected, compare, conclude */
// "colored": true, /* Use colored output (boolean)*/
// "colorError": "3", /* Color for error output (string)*/
// "colorPost": "35", /* Color for post script (string)*/
// "colorPre": "34", /* Color for pre script (string)*/
// "colorSection": "1;97;44", /* Color for heading (start of each submission) (string)*/
// "colorSubsection": "1;34", /* Color for sub section, detected by ^[0-9]+. (string)*/
/* check, grade, prepare, selected, diff, conclude */
// "dry": false, /* Dry run, do not write any files and do not start scripts (boolean)*/
/* check, grade, pdf, selected, diff */
// "submissionsDir": "./gradingOut/submissions", /* submissions directory (where zip is extracted) (folder)*/
/* init, grade, selected, compare, conclude */
// "encoding": "macroman", /* Encoding used for reading and writing result, statistic files and conclusion file (see iconv - lite for encodings), e.g.UTF - 8 or macroman (name)*/
// "resultCSVDelimiter": ";", /* Delimiter used in CSV with the results (and conclusion) (string)*/
/* check, pdf, compare, diff */
// "selected": [], /* Process only on given ids or students with given name (prefix). Existing files of other submitters are not overwritten (...string)*/
/* check, pdf, selected, diff */
// "patchFolder": "./gradingIn/patches", /* Name of the folder in which patch files are searched or created. (folder)*/
/* grade, pdf, prepare, selected */
// "workDir": "./gradingOut/_working", /* Name of working folder, this folder is cleaned before and after) (folder)*/
/* init, check, grade, selected */
// "stdInFolder": "gradingIn", /* Name of folder to be created for (moodle) input files(and added to.gitignore). (folder)*/
/* init, check, prepare, selected */
// "checkDir": "./check", /* Check tests folder, this is mounted in docker as /check (folder)*/
/* init, grade, prepare, selected */
// "gradingSchemaFile": "./check/exam.grading.json", /* JSON file with grading schema(*.grading.json) (file)*/
/* init, grade, selected, conclude */
// "resultFile": "./gradingOut/results_${examName}_${date}-${time}.csv", /* Name of the CSV (.csv) file with the results, with variables in ${..} (examName, date, time), used as pattern in some cases (file)*/
/* check, grade, selected */
// "reportsDir": "./gradingOut/reports", /* folder for generated JUnit and coverage reports, mounted in docker as /reports (folder)*/
/* check, pdf, compare */
// "max": "0", /* Maximal number of submissions to be processed, all others are skipped; use 0 for no limit. (int)*/
/* check, prepare, selected */
// "cacheDir": "./gradingOut/cache", /* folder with cache (mounted as .cache if not "") (folder)*/
// "clipDir": "./gradingOut/clip", /* folder for temporarily stored files and folders, a subfolder with the submission id is mounted in docker as /clip. After check, this folder should be empty. (folder)*/
// "dockerArgs": [], /* Additional arguments used to run docker (...string)*/
// "dockerImage": "node:18.10-alpine", /* Docker image name (name)*/
// "dockerScript": "check/checkInDocker.sh", /* Script to run in docker, this must be path in the vm (file)*/
// "dockerShellCmd": "sh", /* Name of shell used to run in docker (name)*/
// "dockerUserDir": "root", /* Docker user dir (used for npmcache folder) (folder)*/
// "ignoredDirs": ["node_modules"], /* Folders ignored when looking for project folder.Hidden folders(starting with ".") are ignored anyway. (...folder)*/
// "npmCacheDir": "./gradingOut/npmcache", /* folder with NPM cache (mounted as .npm if not "") (folder)*/
// "postCheckScript": "check/postCheck.sh", /* Script to run after docker has run. Environment variables: CLIP (if clipDir is set, this folder with submissionID), PROJECT (student project folder), CHECK (check folder) (file)*/
// "preCheckScript": "check/preCheck.sh", /* Script to run before docker is started. Environment variables: CLIP (if clipDir is set, this folder with submissionID), PROJECT (student project folder), CHECK (check folder) (file)*/
// "projectFile": ".git", /* Project file to identify project folder, the project folder is mounted in docker as / testee (file)*/
// "timeoutPerDockerRun": "300s", /* Timeout per docker run(for each submission) (string)*/
// "volumes": [], /* Additional volumes to be mounted in docker during check (besides submission, reports, clip, cache and npmCache), e.g. node_modules:/testee/node_modules. Host path is made absolut if specified relative to the project folder (...string)*/
/* check, selected, diff */
// "patchGradingBranch": "grading", /* The name of the branch used by the grader (string)*/
/* grade, pdf, selected */
// "latexFragmentFile": "./gradingOut/reports/results.tex", /* Name of LaTeX fragment (previously created via grade) (file)*/
/* grade, prepare, selected */
// "testOutputEndMarker": "§§§", /* End marker containing text to be added to test line in output (string)*/
// "testOutputStartMarker": "§§§", /* Start marker containing text to be added to test line in output (string)*/
/* init, grade, selected */
// "manualCorrectionsFile": "./${stdInFolder}/manual.corrections.json", /* Name of the manual corrections JSON file; with variables in ${..} (stdInFolder). (file)*/
/* pdf, prepare, selected */
// "latex": "xelatex", /* Name of LaTeX tool (name)*/
// "latexConsole": false, /* Show LaTex console output (boolean)*/
// "latexMainFile": "check/latex/grading.tex", /* Name of LaTeX main file(importing fragment via input) (file)*/
/* check, pdf */
// "selectPatched": false, /* Process only submission which have been patched (boolean)*/
/* check, selected */
// "cleanBefore": false, /* Enforce clean before running tests when selected is active. Warning: This removes all reports for existing submissions (boolean)*/
// "onlyPrepareSubmission": false, /* Do only run prepare submission, skip docker (boolean)*/
// "patch": true, /* Applies patch files in the patchFolder to student projects. If no diff file is found, nothing happens. If skipPrepareSubmission is true, no patches are applied (boolean)*/
// "prepareSubmissionCmd": "git reset --hard", /* Bash commands to prepare submission folder, one string that is split into command and args (string)*/
// "skipPrepareSubmission": false, /* Do not run prepare submission (use this in order to keep manual changes in submission (boolean)*/
/* grade, selected */
// "compareResults": true, /* When a new result file has been created, show comparison with previous one if found. (boolean)*/
// "gradedMoodleFile": "./gradingOut/${moodleFile}_graded_${date}-${time}${selected}.csv", /* Name of the Moodle CSV file with the results; with variables in ${..} (moodleFile -- base name without extension, examName, date, time, selected-- add with preceding dot), just "${moodleFile} will override the exported Moodle file. (file)*/
// "gradingValue": "points", /* Use either grade or points for grading in CSV file (grade or points) (string)*/
// "noStatisticsCSV": false, /* Do not create statistics file. (boolean)*/
// "statisticsFile": "./gradingOut/statistics_${examName}_${date}-${time}.csv", /* Name of the statistics CSV file; with variables in ${..} (examName, date, time). If result file is an Excel file, instead of a statistics file a worksheet in results is created (file)*/
/* init, conclude */
// "manualConclusionFile": "${resultsDir}/manual.conclusion.json", /* Name of the manual conclusion JSON file with total grades and aliases; with variables in ${..} (stdInFolder, resultsDir). (file)*/
// "resultsDir": "./gradingOut", /* Path to folder with results to be concluded (folder)*/
/* pdf, selected */
// "noPDFZip": false, /* Do not zip PDF folder(required for upload) (boolean)*/
// "pdfDir": "./gradingOut/pdfReports", /* The folder into which the PDF report is generated (using Moodle's folder structure). (folder)*/
// "pdfZipFile": "./gradingOut/pdfReports_${date}-${time}.zip", /* File name of created zip file to be uploaded to Moodle(Alle Abgaben Anzeigen / Bewertungsvorgang: Mehrere Feedbackdateien in einer Zip - Datei hochladen); with variables in ${..} (date, time). (file)*/
/* check */
// "fromSubmission": "0", /* Index (1-based) of submission (included) which is the first one to be checked (int)*/
// "logOutput": "./gradingOut/check_${date}-${time}.log", /* Name of log file with complete output, no log is created if file is empty. Variables: with variables in ${..} (date, time) (file)*/
// "skipStudentTests": false, /* Do not run student tests (SKIP_STUDENT_TESTS in env set to "true"), existing student test reports are not deleted (boolean)*/
// "toSubmission": "0", /* Index (1-based) of submission (included) which is the last one to be checked. (int)*/
/* compare */
// "showUnchanged": false, /* Show also individual grading results which have not change (boolean)*/
// "summaryOnly": false, /* Show only summary, no individual changes (boolean)*/
/* conclude */
// "autoCopyConclusion": true, /* Automatically copy conclusion file to results dir (boolean)*/
// "autoCopyResult": true, /* Automatically copy result file to results dir (boolean)*/
// "conclusionFile": "./gradingOut/conclusion_${date}-${time}_${firstExam}-${lastExam}.xlsx", /* Name of the concluded results CSV (.csv) or Excel (.xlsx), may use variables in ${..} (date, time, firstExam, lastExam) (file)*/
// "deprecatedResultsDir": "${resultsDir}/deprecated", /* Path to folder with deprectated (old) result, may use variable ${resultsDir} (folder)*/
// "keepOldResult": true, /* Automatically copy old result file to deprecated results dir (boolean)*/
// "maxFailed": 3, /* Number of failed submissions (not submitted or 5) before total failure, if -1 this is ignored (number)*/
// "noFinalGradeBefore": "Blatt 03", /* Number of exam which means exam is started. That is, if only exams before that number are submitted, the final grade will be "-" (not participated). The exams before still count, though! If empty, this is ignored. (string)*/
// "selectBest": 9, /* Select n best result for each student (number)*/
// "totalExams": 11, /* Total number of exams per student at end of term (number)*/
/* diff */
// "patchSubmissionBranches": ["main","master"], /* The names of the branches used in the submission, the first one found is used (...string)*/
/* grade */
// "noLatex": false, /* Do not create LaTeX fragment(required for PDF reports) (boolean)*/
// "noMoodleCSV": false, /* Do not create Moodle grading file. (boolean)*/
// "noResultCSV": false, /* Do not create CSV with results(for your own statistics) (boolean)*/
/* init */
// "generateCorrectionsFile": false, /* If set to true, a correction file is created as well. It is created in the standard in folder. If a grading scheme already exists, nothing else is generated and the correction files uses information found in the grading schema. If results already exists, the file is populated with the students. (boolean)*/
// "generateManualConclusionFile": false, /* If set to true, a manual conclusion file is created as well. (boolean)*/
// "generateSettings": false, /* Generate .grading/settings.json (boolean)*/
// "noFolders": false, /* Do not create standard input folder (boolean)*/
// "noGitignore": false, /* Do not add input and output folders to.gitignore (boolean)*/
// "stdOutFolder": "gradingOut", /* Name of folder to be created for output files(and added to.gitignore). (folder)*/
// "taskInGeneratedCorrectionsFile": false, /* If set to true, templates for tasks are created in correction file as well. Usually this is not required. (boolean)*/
/* pdf */
// "clean": false, /* Automatically clean folder with PDFs (boolean)*/
/* prepare */
// "createGradingFile": "", /* If provided, instead of grading, create grading scheme based on checks run on solution (file)*/
// "latexFragmentFileSolution": "./gradingOut/solution/reports/results.tex", /* Name of LaTeX fragment for solution(previously created via prepare) (file)*/
// "pdfDirSolution": "./gradingOut/solution/pdfReport", /* The folder into which the PDF report for the solution is generated (using Moodle's folder structure). (folder)*/
// "preserveContainer": false, /* Preserves the container after run, u.e. - rm is not passed to Docker (boolean)*/
// "reportsDirSolution": "./gradingOut/solution/reports", /* folder for generated JUnit and coverage reports of solution, mounted in docker as / reports (folder)*/
// "skipDocker": false, /* Do not run docker and tests, just adjust grading and report (boolean)*/
// "validateOnly": false, /* Do not run tests, only validate grading schema (boolean)*/
}
Zum Erstellen der Dockerfiles, in Verzeichnis dockerfiles wechseln und Hinweisen in dortiger README.md folgen.
Für Jest muss die Erweiterung jest-junit installiert werden, damit JUnit-kompatible Reports erstellt werden. Dort sollte folgende Konfiguration definiert werden:
reporters: [
"default",
["jest-junit", { suiteNameTemplate: "{filename}", "classNameTemplate": "{filename}", "titleTemplate": "{title}" }],
],
This program and the accompanying materials are made available under the terms of the Eclipse Public License v. 2.0 which is available at https://www.eclipse.org/legal/epl-2.0.
FAQs
Grading of student submissions, in particular programming tests.
We found that grading demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.