Tutorial: Moodle VPL -- Testing a Bash Script
--D. Thiebaut (talk) 21:19, 23 March 2017 (EDT)
This tutorial illustrates how to setup a VPL activity that tests a Bash script that takes as input an integer and acts as a teller machine, returning the number of 20s, number of 10s, number of 5s, and number of 1s contained in the initial integer. The tutorial illustrates how to setup evaluation of the program so that the student will get 0 or 100 points depending on whether his/her program output is correct or not.
Setup
- Moodle Version 2.7 + (Build: 20140529)
- VPL Version 3.0.1
- For details on how Moodle and VPL were installed, go to this page.
Step-by-Step Instructions
- Login as Instructor for course where Python test is to be added
- Turn editing ON
Add New Activity
- Add new activity
- Set the following fields:
- Name: Teller Test
- Short description: Teller Machine Bash script
- Full description: You need to write a bash script that will break down an integer amount into 20s, 10s, 5s, and 1s. The integer amount is passed on the command line.
- Submission period: pick today's date for Available from and a date that is in your future for Due date, and click on Enable
- Submission restrictions/Max number of files: 1, and leave all the other fields with their default values.
- Grade: Use Point, 100, and pick the category of grades this should fall in (You need to create categories first, i.e. quizzes, homework, exam, etc.)
- Save and display
VPL Administration
Setup the VPL system to test the students programs
- Test cases: None needed
- Execution options: Run: Yes, Debug: No, Evaluate: Yes, Evaluate just on submission: No, Automatic Grade: Yes
- Requested files: teller.sh. Just enter this file name, and nothing in the edit window. Click on Save.
Testing as Admin
- Test activity. Click on Edit and enter this simple program:
#! /bin/bash amount=$1 no20s=$( expr $amount / 20 ) amount=$( expr $amount % 20 ) no10s=$( expr $amount / 10 ) amount=$( expr $amount % 10 ) no5s=$( expr $amount / 5 ) no1s=$( expr $amount % 5 ) echo "" echo $no20s echo $no10s echo $no5s echo $no1s
- Save
- Click on Run
- Close the console
- Click on Evaluate
- Verify that you get the message shown below, indicating that the program runs correctly and gets full mark.
TEST 1 Congrats, your output is correct. --------------------------------. 0 0 0 0 TEST 2 Congrats, your output is correct. --------------------------------. 3 1 1 2 TEST 3 Congrats, your output is correct. --------------------------------. 1 1 1 1
vpl_run
#! /bin/bash cat > vpl_execution <<EOF #! /bin/bash chmod a+rx teller.sh read var1 ./teller.sh \${var1} EOF chmod +x vpl_execution
vpl_evaluate
#! /bin/bash # D. Thiebaut # Smith College # vpl_evaluate.sh script looping through several tests, each test with # its own input file and its own expected output file. The output of the # student program is tested against the expected output file. # cat > vpl_execution <<EEOOFF #! /bin/bash # --- student program being tested --- prog1=teller.sh # --- compile student program --- chmod a+x \${prog1} # --- create test input files --- cat > data1.txt <<EOF 0 EOF cat > data2.txt <<EOF 77 EOF cat > data3.txt <<EOF 36 EOF #--- create expected outputs, one for each input file above --- #--- (make sure no extra blank lines) --- cat > data1.out <<EOF 0 0 0 0 EOF cat > data2.out <<EOF 3 1 1 2 EOF cat > data3.out <<EOF 1 1 1 1 EOF for i in 1 2 3 ; do echo "Comment :=>>-TEST \$i" # ============================================== # TEST i # ============================================== #--- run program, capture output, display to student --- command="head -n 1 data\${i}.txt" input=\$( \$command ) ./\${prog1} \${input} &> user.out cp user.out user.out.org #--- remove non numbers and non minus--- cat user.out | sed 's/[^0-9\ -]*//g' > dummy.out mv dummy.out user.out #--- remove multiple spaces --- cat user.out | sed 's/ */ /g' > dummy.out mv dummy.out user.out #--- remove blank lines --- cat user.out | sed '/^\s*$/d' > dummy.out mv dummy.out user.out #--- compute difference --- diff -y -w --ignore-all-space user.out data\${i}.out > diff.out #echo "----- diff.out ------" #cat diff.out #echo "---------------------" diff -y -w --ignore-all-space user.out data\${i}.out > diff.out #--- reject if different --- if ((\$? > 0)); then echo "Comment :=>>- Your output is incorrect." #--- display test file --- echo "Comment :=>>- Your program tested with:" echo "<|--" cat data\${i}.txt echo "--|>" echo "Comment :=>> ---------------" echo "Comment :=>>- Your output:" echo "Comment :=>> ---------------" echo "<|--" cat user.out.org echo "--|>" echo "" echo "Comment :=>> ---------------" echo "Comment :=>>- Expected output (only the numbers): " echo "Comment :=>> ---------------" echo "<|--" cat data\${i}.out echo "--|>" #--- consolation grade --- grade=\$((grade+10)) # --------------------- REWARD IF CORRECT OUTPUT ----------------- else #--- good output --- echo "Comment :=>>- Congrats, your output is correct." echo "Comment :=>> --------------------------------." echo "<|--" cat user.out.org echo "--|>" grade=\$((grade+100/i)) fi done if (( grade > 100 )); then grade=100 fi echo "Grade :=>> \$grade" EEOOFF chmod +x vpl_execution
This concludes this tutorial