在大型項目中,將測試參數寫在代碼裡並不是最佳實踐。Locust 提供了配置文件機制,讓我們可以通過 locust.yml
等配置文件來管理測試參數,使測試更加靈活和可維護。
Locust 配置文件是使用 YAML 格式的檔案,專門用來定義各種測試參數,例如:
透過配置文件,你可以將測試邏輯(Python 程式碼)與測試參數(YAML 檔案)分開管理,讓專案結構更清晰。
一個基本的 locust.yml
檔案可以定義測試的核心設定。同時,你也可以在 env
區塊中定義自訂環境變數,這些變數在測試腳本中可以像一般的系統環境變數一樣被讀取和使用。
locust.yml
範例# locust.yml - 基本配置範例
host: "https://api.example.com"
users: 100
spawn-rate: 10
run-time: "5m"
headless: true
html: "report.html"
csv: "results"
loglevel: "INFO"
logfile: "locust.log"
# 自訂環境變數
env:
API_KEY: "your-api-key"
ENVIRONMENT: "staging"
DEBUG: "false"
在你的 Locust 測試腳本中,你可以使用 Python 的 os.environ.get()
方法來讀取這些環境變數。這使得測試腳本可以根據不同的配置檔案來動態調整其行為。
import os
from locust import HttpUser, task, between
class ConfigurableUser(HttpUser):
wait_time = between(1, 3)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# 從環境變數讀取配置
self.api_key = os.environ.get('API_KEY', 'default-key')
self.environment = os.environ.get('ENVIRONMENT', 'dev')
self.debug = os.environ.get('DEBUG', 'false').lower() == 'true'
def on_start(self):
"""測試開始時的初始化"""
if self.debug:
print(f"Starting test in {self.environment} environment")
# 使用 API Key 進行認證
response = self.client.post("/auth", json={"api_key": self.api_key})
if response.status_code == 200:
self.auth_token = response.json().get("token")
else:
print(f"Authentication failed: {response.status_code}")
@task
def api_request(self):
"""使用配置的認證令牌發送請求"""
headers = {}
if hasattr(self, 'auth_token'):
headers["Authorization"] = f"Bearer {self.auth_token}"
response = self.client.get("/api/data", headers=headers)
if self.debug and response.status_code != 200:
print(f"Request failed: {response.status_code}")
使用配置文件非常簡單,只需在執行命令中加上 --config
參數即可。
# 使用配置文件執行測試
locust -f test_script.py --config locust.yml
# 命令列參數會覆蓋配置文件中的設定
locust -f test_script.py --config locust.yml --users 200
延續第 10 天的分散式測試概念,你可以為 Main 和 Worker 節點分別創建不同的配置文件,讓部署更靈活。
main.yml
)main.yml
定義了主節點的行為,包含 Web UI 的相關設定、預期連接的 Worker 數量,以及主節點專用的參數。
# main.yml - Main 節點配置
host: "https://api.example.com"
master: true
master-bind-host: "0.0.0.0"
master-bind-port: 5557
web-host: "0.0.0.0"
web-port: 8089
expect-workers: 3 # 期待的 Worker 數量
headless: false # 啟用 Web UI
html: "distributed-report.html"
csv: "distributed-results"
loglevel: "INFO"
logfile: "main.log"
# 主節點專用設定
master-config:
heartbeat-interval: 3
worker-timeout: 60
stats-report-interval: 2
# 測試環境配置
env:
TEST_ENVIRONMENT: "production"
API_KEY: "prod-api-key"
worker.yml
)worker.yml
則專門用於工作節點,其中最重要的就是指定要連接的主節點位址。
# worker.yml - Worker 節點配置
host: "https://api.example.com"
worker: true
master-host: "192.168.1.100" # Main 節點 IP
master-port: 5557
loglevel: "WARNING"
logfile: "worker.log"
# 工作節點專用設定
worker-config:
heartbeat-interval: 3
reconnect-attempts: 5
# 工作節點特定環境變數
env:
WORKER_ID: "worker-1"
API_KEY: "prod-api-key"
為了應對不同環境(開發、測試、生產),你可以為每個環境創建專屬的配置文件,並在執行時切換使用。
# configs/development.yml
host: "http://localhost:8000"
users: 10
spawn-rate: 2
run-time: "2m"
loglevel: "DEBUG"
env:
API_KEY: "dev-key"
ENVIRONMENT: "development"
DEBUG: "true"
# configs/staging.yml
host: "https://staging-api.example.com"
users: 50
spawn-rate: 5
run-time: "10m"
loglevel: "INFO"
env:
API_KEY: "staging-key"
ENVIRONMENT: "staging"
DEBUG: "false"
# configs/production.yml
host: "https://api.example.com"
users: 1000
spawn-rate: 50
run-time: "30m"
headless: true
html: "prod-report.html"
csv: "prod-results"
loglevel: "WARNING"
env:
API_KEY: "prod-key"
ENVIRONMENT: "production"
ENABLE_MONITORING: "true"
Locust 的配置機制不僅僅是簡單的 YAML 檔案,還支援更複雜的用法,讓你的工作流程更高效。
你可以創建一個基礎配置文件 base.yml
,然後讓其他配置文件透過 extends
屬性來繼承它。這種方法能有效減少重複的設定。
# base.yml - 基礎配置
host: "https://api.example.com"
spawn-rate: 10
loglevel: "INFO"
headless: true
env:
API_VERSION: "v1"
# load-test.yml - 繼承基礎配置並覆寫部分設定
extends: "base.yml"
users: 500
run-time: "15m"
html: "load-test-report.html"
env:
TEST_TYPE: "load"
當你需要根據特定參數(例如環境或 Worker 數量)動態生成配置時,可以編寫 Python 腳本來處理。
# config_generator.py
import yaml
import sys
def generate_config(environment, worker_count=1):
"""動態生成配置文件"""
# ... 略 ...
return config
if __name__ == "__main__":
env = sys.argv[1] if len(sys.argv) > 1 else "development"
workers = int(sys.argv[2]) if len(sys.argv) > 2 else 1
config = generate_config(env, workers)
with open(f"generated-{env}.yml", "w") as f:
yaml.dump(config, f, default_flow_style=False)
print(f"Generated configuration for {env} with {workers} workers")
為了確保配置檔案格式正確,你可以使用 Cerberus 等函式庫來對 YAML 檔案進行驗證。這能避免因設定錯誤導致測試失敗。
# config_validator.py
import yaml
import sys
from cerberus import Validator
schema = {
'host': {'type': 'string', 'required': True},
'users': {'type': 'integer', 'min': 1, 'max': 10000},
'loglevel': {'type': 'string', 'allowed': ['DEBUG', 'INFO', 'WARNING', 'ERROR']},
'env': {
'type': 'dict',
'schema': {
'API_KEY': {'type': 'string', 'required': True},
'ENVIRONMENT': {'type': 'string', 'required': True}
}
}
}
def validate_config(config_file):
"""驗證配置文件格式"""
try:
with open(config_file, 'r') as f:
config = yaml.safe_load(f)
validator = Validator(schema)
if validator.validate(config):
print(f"✅ Configuration {config_file} is valid")
return True
else:
print(f"❌ Configuration {config_file} has errors:")
for field, error in validator.errors.items():
print(f" - {field}: {error}")
return False
except (FileNotFoundError, yaml.YAMLError) as e:
print(f"❌ Error loading {config_file}: {e}")
return False
if __name__ == "__main__":
config_file = sys.argv[1] if len(sys.argv) > 1 else "locust.yml"
validate_config(config_file)
良好的配置管理是大型專案的基石。
將配置文件納入版本控制,並建立清晰的目錄結構,方便管理和追蹤。
# 目錄結構範例
├── configs/
│ ├── environments/
│ │ ├── development.yml
│ │ ├── staging.yml
│ │ └── production.yml
│ ├── distributed/
│ │ ├── main.yml
│ │ └── worker.yml
│ └── templates/
│ └── base.yml
├── scripts/
│ ├── validate_config.py
│ └── generate_config.py
└── tests/
└── test_locust.py
永遠不要將密碼、API Key 或其他敏感資訊直接寫在配置文件中。應使用**環境變數(Environment Variables)**來注入這些資訊。
# locust.yml - 使用環境變數
host: "https://api.example.com"
env:
API_KEY: "${API_KEY}" # 從環境變數注入
SECRET_KEY: "${SECRET_KEY}" # 從環境變數注入
你可以使用 source .env
載入一個 .env
檔案,或是在 Docker 中直接透過 --env
參數傳遞。
總結來說,Locust 配置文件是高效能測試不可或缺的一環。透過本篇介紹的內容,你可以:
正確地使用和管理配置文件,能夠大幅提升你的效能測試效率和專案品質。