🔥 0
0
Lesson 2 of 10 25 min +200 XP

JMeter Fundamentals

Apache JMeter is a powerful, open-source tool for performance testing. In this lesson, you'll understand how JMeter works and create your first test.

Installing JMeter

Prerequisites

JMeter requires Java 8 or higher:

# Check Java version
java -version

# Should show Java 8+ (1.8 or higher)

Download and Install

# Download JMeter (check apache.org for latest version)
wget https://downloads.apache.org/jmeter/binaries/apache-jmeter-5.6.3.zip

# Extract
unzip apache-jmeter-5.6.3.zip

# Run JMeter GUI
cd apache-jmeter-5.6.3/bin
./jmeter.sh  # Linux/Mac
jmeter.bat   # Windows
Memory Configuration

For larger tests, increase JMeter's heap size by editing jmeter.bat or jmeter.sh:
HEAP="-Xms1g -Xmx4g"

JMeter Architecture

Understanding JMeter's components is essential:

JMeter Test Plan Hierarchy

The Test Plan contains Thread Groups (virtual users), which contain Samplers (requests), Timers (think time), and Assertions (validation). Config Elements and Listeners can be added at various levels.

Core Components

Test Plan

The container for your entire test. Everything else goes inside the Test Plan.

<?xml version="1.0" encoding="UTF-8"?>
<jmeterTestPlan version="1.2">
  <hashTree>
    <TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="E-Commerce Load Test">
      <boolProp name="TestPlan.functional_mode">false</boolProp>
      <stringProp name="TestPlan.comments">Product catalog performance test</stringProp>
    </TestPlan>
    <hashTree>
      <!-- Thread Groups, Samplers, etc. go here -->
    </hashTree>
  </hashTree>
</jmeterTestPlan>

Thread Group

Defines how many virtual users (threads) will run and how they behave.

PropertyDescriptionExample
Number of ThreadsVirtual users100
Ramp-up PeriodTime to start all threads60 seconds
Loop CountIterations per thread10
<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Shoppers">
  <stringProp name="ThreadGroup.num_threads">100</stringProp>
  <stringProp name="ThreadGroup.ramp_time">60</stringProp>
  <intProp name="ThreadGroup.num_threads">10</intProp>
  <boolProp name="ThreadGroup.scheduler">false</boolProp>
</ThreadGroup>

Samplers

Samplers send requests to your server. The most common is the HTTP Request Sampler.

<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Get Product List">
  <stringProp name="HTTPSampler.domain">api.mystore.com</stringProp>
  <stringProp name="HTTPSampler.port">443</stringProp>
  <stringProp name="HTTPSampler.protocol">https</stringProp>
  <stringProp name="HTTPSampler.path">/api/products</stringProp>
  <stringProp name="HTTPSampler.method">GET</stringProp>
</HTTPSamplerProxy>

Listeners

Listeners collect and display test results. Common listeners:

View Results Tree

Debug individual requests and responses

Summary Report

Aggregate statistics per request

Aggregate Report

Detailed percentile data (P90, P95, P99)

Graph Results

Visual response time over time

Critical Warning

NEVER use graphical listeners during real load tests! They consume massive memory and CPU, skewing your results. Use them only for debugging with a few threads. For actual tests, run in CLI mode and write results to files.

Timers

Timers add delays between requests to simulate realistic user behavior (think time).

<ConstantTimer guiclass="ConstantTimerGui" testclass="ConstantTimer" testname="Think Time">
  <stringProp name="ConstantTimer.delay">3000</stringProp>
</ConstantTimer>

Assertions

Assertions validate responses. A passed assertion means the request worked correctly.

<ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Check Success">
  <stringProp name="Assertion.test_field">Assertion.response_code</stringProp>
  <stringProp name="Assertion.test_type">2</stringProp>
  <stringProp name="Assertion.test_strings">200</stringProp>
</ResponseAssertion>

JMeter GUI Tour

When you open JMeter, you'll see the interface layout:

JMeter GUI Interface

The interface includes: Menu Bar (File, Edit, Run, etc.), Toolbar (New, Open, Save, Start, Stop), Tree View (test plan hierarchy), Configuration Panel (settings for selected element), and Log Viewer (errors and warnings).

Adding Elements: Right-click on any tree item to add child elements.

Your First Test: Product API

Let's create a simple test against an e-commerce product API.

Step 1: Add Thread Group

Right-click Test Plan → Add → Threads (Users) → Thread Group

Configure:

  • Name: Product Browsers
  • Number of Threads: 10
  • Ramp-up Period: 10 seconds
  • Loop Count: 5

Step 2: Add HTTP Request

Right-click Thread Group → Add → Sampler → HTTP Request

Configure:

  • Name: Get Products
  • Protocol: https
  • Server Name: fakestoreapi.com
  • Path: /products
  • Method: GET

Step 3: Add Listener

Right-click Thread Group → Add → Listener → View Results Tree

Step 4: Run the Test

Click the green Start button (or press Ctrl+R).

Understanding Results

In the View Results Tree, click on a request:

Request:
GET https://fakestoreapi.com/products

Response Headers:
HTTP/1.1 200 OK
Content-Type: application/json

Response Body:
[
  {"id": 1, "title": "Fjallraven Backpack", "price": 109.95, ...},
  {"id": 2, "title": "Mens Casual T-Shirt", "price": 22.30, ...},
  ...
]

Response Time: 245 ms

Complete Test Plan XML

Here's the complete test plan in JMeter's XML format:

<?xml version="1.0" encoding="UTF-8"?>
<jmeterTestPlan version="1.2">
  <hashTree>
    <TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Product API Test">
      <boolProp name="TestPlan.functional_mode">false</boolProp>
      <boolProp name="TestPlan.serialize_threadgroups">false</boolProp>
    </TestPlan>
    <hashTree>
      <ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Product Browsers">
        <stringProp name="ThreadGroup.num_threads">10</stringProp>
        <stringProp name="ThreadGroup.ramp_time">10</stringProp>
        <elementProp name="ThreadGroup.main_controller" elementType="LoopController">
          <boolProp name="LoopController.continue_forever">false</boolProp>
          <stringProp name="LoopController.loops">5</stringProp>
        </elementProp>
      </ThreadGroup>
      <hashTree>
        <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Get Products">
          <stringProp name="HTTPSampler.domain">fakestoreapi.com</stringProp>
          <stringProp name="HTTPSampler.port"></stringProp>
          <stringProp name="HTTPSampler.protocol">https</stringProp>
          <stringProp name="HTTPSampler.path">/products</stringProp>
          <stringProp name="HTTPSampler.method">GET</stringProp>
          <boolProp name="HTTPSampler.follow_redirects">true</boolProp>
          <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
        </HTTPSamplerProxy>
        <hashTree>
          <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Check 200 OK">
            <collectionProp name="Asserion.test_strings">
              <stringProp name="49586">200</stringProp>
            </collectionProp>
            <stringProp name="Assertion.test_field">Assertion.response_code</stringProp>
            <intProp name="Assertion.test_type">2</intProp>
          </ResponseAssertion>
        </hashTree>
        <ResultCollector guiclass="ViewResultsFullVisualizer" testclass="ResultCollector" testname="View Results Tree">
          <boolProp name="ResultCollector.error_logging">false</boolProp>
        </ResultCollector>
      </hashTree>
    </hashTree>
  </hashTree>
</jmeterTestPlan>

Test Execution Modes

GUI Mode (Development Only)

./jmeter.sh

Use for:

  • Building test plans
  • Debugging with small thread counts
  • Learning and exploration

CLI Mode (Production Tests)

./jmeter.sh -n -t test_plan.jmx -l results.jtl -e -o report_folder
FlagMeaning
-nNon-GUI mode
-tTest plan file
-lResults log file
-eGenerate report after test
-oReport output folder
Best Practice

Always run actual performance tests in CLI mode. GUI mode is only for building and debugging tests with minimal load.

Key Takeaways

  • Thread = Virtual User: Each thread simulates one user making requests.
  • Test Plan hierarchy: Test Plan → Thread Group → Samplers → Assertions/Timers.
  • Listeners for debugging only: Never use graphical listeners in real load tests.
  • CLI for production: Run actual performance tests in non-GUI mode with -n flag.

Next Lesson

You've created your first test! Next, we'll dive deep into Thread Groups and Realistic Load - configuring virtual users, ramp-up periods, and think times to simulate real user behavior.

🧠 Quick Quiz

Test your understanding of this lesson.

1

What is a Thread in JMeter terminology?

2

What is the primary purpose of a Sampler in JMeter?

3

Why should you NOT use Listeners in production load tests?

Why Performance Testing Matters