How to run the tests (moodle 45)

Versión 3 (Emilio Penna, Jueves, 19 de Marzo de 2026 10:08:03 -0300)

1 1
h2. JMeter script configuration
2 1
3 1
4 1
Tested with JMeter 5.6.3 and Moodle 4.5.
5 1
6 2 Emilio Penna
h3. User-defined variables (Test Plan level)
7 1
8 2 Emilio Penna
All parameters are configured as user-defined variables at the top of the Test Plan:
9 1
10 2 Emilio Penna
|_.Variable|_.Description|_.Example|
11 2 Emilio Penna
|@curso@|Course ID (numeric)|@2@|
12 2 Emilio Penna
|@prueba@|Quiz module ID (numeric, the @cmid@)|@2@|
13 2 Emilio Penna
|@host@|Server hostname (no protocol)|@eva-perf.seciu.edu.uy@|
14 2 Emilio Penna
|@servidor@|Server URL with protocol|@https://eva-perf.seciu.edu.uy@|
15 2 Emilio Penna
|@port@|HTTPS port|@443@|
16 2 Emilio Penna
|@csvfile@|Absolute path to the users CSV file|@/home/user/perftestusers5000.csv@|
17 2 Emilio Penna
|@twaitmin@|Minimum think time in milliseconds|@30000@|
18 2 Emilio Penna
|@twaitmax@|Maximum think time in milliseconds|@90000@|
19 2 Emilio Penna
|@assertiontext1@|Text asserted on quiz pages (English)|@page@|
20 2 Emilio Penna
|@assertiontext2@|Text asserted on quiz pages (Spanish)|@página@|
21 1
22 2 Emilio Penna
The @assertiontext1@/@assertiontext2@ pair handles Moodle installations in either language.
23 2 Emilio Penna
They verify that quiz attempt pages loaded correctly after each @processattempt.php@ call.
24 1
25 2 Emilio Penna
h3. Thread Group
26 1
27 2 Emilio Penna
Set the number of threads (VUs) and ramp-up time in the Thread Group. The script is configured
28 2 Emilio Penna
for a single iteration per thread (@LoopController.loops=1@): each virtual user logs in,
29 2 Emilio Penna
completes the quiz once, and exits. On error, the thread stops (@stopthread@).
30 1
31 2 Emilio Penna
We tested up to 3000 threads with a 180 s ramp-up.
32 1
33 2 Emilio Penna
Start with 1 thread to confirm the script runs without errors before scaling up.
34 1
35 2 Emilio Penna
h3. CSV Data Set Config
36 1
37 2 Emilio Penna
The script reads user credentials from the CSV file. Columns are: @user,n1,n2,mail,pwd@.
38 2 Emilio Penna
Set the @csvfile@ variable to the absolute path of your users file.
39 1
40 2 Emilio Penna
h3. Synchronizing Timer and Gaussian Random Timer
41 1
42 2 Emilio Penna
The script simulates students starting the exam at the same moment using two timers placed
43 2 Emilio Penna
inside the @startattempt@ transaction controller, just before the POST to @startattempt.php@:
44 1
45 2 Emilio Penna
* *Synchronizing Timer* (@groupSize=0@): holds all threads at this point until the entire
46 2 Emilio Penna
  thread group has arrived, then releases them simultaneously. This models the worst-case
47 2 Emilio Penna
  scenario of all students clicking "Start attempt" at exactly the same time.
48 2 Emilio Penna
* *Gaussian Random Timer* (deviation @30000@ ms, offset @5000@ ms): after release, each
49 2 Emilio Penna
  thread waits a random delay before actually sending the startattempt request. With these
50 2 Emilio Penna
  settings, approximately *66% of threads fire within the first 30 seconds*, and ~95% within
51 2 Emilio Penna
  the first minute. This models the real-world observation that in large exams, 55–75% of
52 2 Emilio Penna
  students tend to start in the first minute, making this a conservative worst-case scenario.
53 1
54 2 Emilio Penna
h3. Think time
55 1
56 2 Emilio Penna
Each quiz page uses a @TestAction@ pause of @${twait}@ milliseconds, where @twait@ is
57 2 Emilio Penna
initialized per thread at the start of the test by a JSR223 sampler (Groovy) that picks a
58 2 Emilio Penna
random value uniformly between @twaitmin@ and @twaitmax@. This means each virtual user has
59 2 Emilio Penna
a *fixed* think time for the entire test, but different users have different values — a
60 2 Emilio Penna
reasonable model for students answering at different speeds.
61 1
62 2 Emilio Penna
h3. Script coverage and limitations
63 2 Emilio Penna
64 2 Emilio Penna
The script covers the main HTTP interactions of the quiz flow: login, course page, quiz view,
65 2 Emilio Penna
exam start, answering all 16 questions across 8 pages (via @processattempt.php@), and
66 2 Emilio Penna
finishing the attempt. Quiz attempts and answers are saved correctly in Moodle — this has
67 2 Emilio Penna
been verified after each test run by reviewing the quiz results in the admin interface.
68 2 Emilio Penna
69 2 Emilio Penna
The script does not replicate every browser request. In particular, it omits most AJAX calls
70 2 Emilio Penna
(e.g. autosave, flag updates, analytics beacons) and does not fetch all embedded static
71 2 Emilio Penna
resources on each page. A real browser session generates significantly more requests per page.
72 2 Emilio Penna
However, the requests that drive server-side PHP processing — which is the actual bottleneck —
73 2 Emilio Penna
are all included. The "get static resources" controller in the script is disabled; static
74 2 Emilio Penna
asset delivery is better tested via @mod_cache@ or a dedicated CDN rather than through JMeter.
75 2 Emilio Penna
76 2 Emilio Penna
The @sesskey@ token (Moodle's CSRF protection) is extracted dynamically via regex after login
77 2 Emilio Penna
and after the quiz view page, and included in all subsequent POST requests. The @attempt@ ID
78 2 Emilio Penna
is similarly extracted after @startattempt.php@ and used throughout.