-
Notifications
You must be signed in to change notification settings - Fork 0
Automatische testen
Als er extra checks moeten uitgevoerd worden om een indiening van een student te aanvaarden, kan je als lesgever automatische tests laten lopen wanneer een indiening gemaakt wordt. Deze tests zullen runnen in een Docker container op onze server.
We voorzien hiervoor twee mogelijkheden: tests met de standaard Docker image of met een eigen Docker image.
In de standaard image zijn verschillende tools en programma's voorzien. Een lijst daarvan vind je hier. Je uploadt een of meerdere scripts die elke keer uitgevoerd zullen worden in een container van deze image wanneer een indiening gemaakt wordt. We raden aan om deze methode te gebruiken indien mogelijk.
Als je voor het uitvoeren van de testscripts bijkomende programma's nodig hebt, kan je een eigen image laten bouwen op onze server met behulp van een Dockerfile. Gebruik deze methode wanneer de voorziene tools van de standaard image ontoereikend zijn.
Important
Installeer nooit programma's in een testscript. Dit zal namelijk elke keer opnieuw gebeuren wanneer het script wordt uitgevoerd. Installeer nodige tools in de Dockerfile. Een minimaal voorbeeld kan je hier vinden.
Om de standaard image te gebruiken, upload je een of meerdere scripts bij of na het aanmaken van een project. De enige vereiste is dat er een shell script genaamd run
aanwezig is. Dit bestand wordt automatisch aangeroepen en dient als entrypoint om eventuele andere testscripts te laten lopen.
Dit kan heel eenvoudig zijn. Om een testscript test.py
te runnen, is de inhoud van run
gewoon:
#!/bin/sh
python test.py
De standaard image zal de testscripts kopiëren naar de homedirectory van de container. De indiening van de student zal zich bevinden in ~/submission
. De structuur van de homedirectory ziet er dan bijvoorbeeld zo uit:
.
├── run
├── submission
│ └── submission.py
└── test.py
Om een eigen image te bouwen, volstaat het om een bestand genaamd Dockerfile
te uploaden samen met de testscripts. Een image zal op de server gebouwd worden met een commando ruwweg equivalent aan:
docker build .
waarbij alle geüploade bestanden zich in .
bevinden.
Bij het uivoeren van de tests kan je de volgende omgevingsvariabelen gebruiken:
-
$CORRECT
: Een pad naar het tekstbestand voor geslaagde testresultaten. -
$FAILED
: Een pad naar het tekstbestand voor gefaalde testresultaten. -
$EXIT_TEST_FAILED
: Een unieke exit code die je gebruikt om aan te geven dat de tests mislukt zijn. -
$ARTIFACT_DIR
: De directory waar gegenereerde artifacts naartoe kunnen geschreven worden als ze beschikbaar moeten gesteld worden na afloop van de automatische tests. -
$SUBMISSION_DIR
: De directory waar de indiening van de student geïnstalleerd wordt. Bij de standaard image wordt deze directory automatisch gekopiëerd naar de homedirectory.
Je kan aangeven dat een test geslaagd is door een lijn te schrijven naar het bestand $CORRECT
, en dat een test niet geslaagd is door een lijn te schrijven naar $FAILED
. De inhoud van deze bestanden wordt na het uivoeren van de container uitgelezen en opgeslagen in onze databank. Deze bestanden hebben geen invloed op de status van de indiening.
Deze bestanden gebruik je bijvoorbeeld zo:
# run first test...
echo "First test failed" >> "$FAILED"
# run second test...
echo "Second test succeeded" >> "$CORRECT"
of in python:
import os
with open(os.environ['CORRECT'], 'w') as correct:
# run first test...
correct.write("First test succeeded\n")
Important
Testresultaten worden gescheiden door newlines, vergeet ze niet.
De uiteindelijke status van een indiening hangt enkel af van de exit code van de container. Bij een exit 0
wordt de indiening aanvaard. Een exit $EXIT_TEST_FAILED
geeft aan dat de indiening geweigerd werd. Alle andere exit codes worden geïnterpreteerd als een crash.
Het is dus de verantwoordelijkheid van de lesgever om te programmeren welke voorwaarden moeten voldaan zijn om een indiening te accepteren.
Bestanden die naar $ARTIFACT_DIR
geschreven worden, worden na afloop van de container beschikbaar gesteld voor studenten en lesgevers om te downloaden.
We raden aan om testscripts in een zipbestand te uploaden. Elk zipbestand wordt meteen automatisch uitgepakt.
Eventuele zipbestanden die ingediend worden door studenten worden niet uitgepakt. Het is de verantwoordelijkheid van de lesgever om ze uit te pakken in de Docker container.
Een voorbeeld waarbij de lesgever een testscript in python uploadt.
# run
#!/bin/sh
python test.py
Dit script gaat ervan uit dat de student een bestand submission.py
indient.
# test.py
import os
from submission.submission import questionable_code
correct_path = os.environ['CORRECT']
failed_path = os.environ['FAILED']
failed = False
with open(correct_path, 'w') as correct, open(failed_path, 'w') as failed:
result = questionable_code()
if is_correct(result):
correct.write("Test succeeded.\n")
else:
failed.write("Test failed.\n")
failed = True
if failed:
exit(int(os.environ['EXIT_TEST_FAILED']))
In dit voorbeeld uploadt een lesgever tests met de volgende structuur:
.
├── Dockerfile
├── entrypoint
├── tests
│ └── test1.py
│ └── test2.py
│ └── ...
└── test.py
# Dockerfile
FROM python:3
WORKDIR /home/runner
# copy test scripts to docker image
COPY entrypoint test.py ./
COPY tests/ ./tests
# ...
RUN useradd -m runner
RUN chown -R runner:runner /home/runner/
RUN chmod +x ./entrypoint
# install unavailable python module
RUN pip install --no-cache-dir --upgrade obscure_python_module
ENTRYPOINT ["./entrypoint"]
# entrypoint
#!/bin/sh
cp -R "$SUBMISSION_DIR" "$PWD"
chmod a+wx "$ARTIFACT_DIR"
chmod a+wx "$CORRECT"
chmod a+wx "$FAILED"
su runner -c 'python test.py'
# test.py
...