Skip to content

Instantly share code, notes, and snippets.

@ktimothy
Last active October 18, 2020 12:13
Show Gist options
  • Save ktimothy/5feab54c486a145f59efb2b86e5a0c6f to your computer and use it in GitHub Desktop.
Save ktimothy/5feab54c486a145f59efb2b86e5a0c6f to your computer and use it in GitHub Desktop.
locust test suite
  1. устанавливаем locust.io (для него нужен python >=2.7):
python3 -m pip install locust
  1. запускаем командой
locust 
  -f ./load_test.py \    # файл с описанием теста
  -u 100 \               # количество параллельных юзеров и
  -r 100 \               # прирост юзеров (u=100 r=100 значит что все 100 создадутся одновременно)
  -H http://api.tapheroes.atlas.wake-app.net \    # хост, который тестируем
  -t 5m \                # время теста
  --headless             # запускаем в консоли, без ui
import time, uuid
from locust import HttpUser, task, between
# В этом классе содержатся все действия: которые будет выполнять юзер
class QuickstartUser(HttpUser):
# сколько времени юзер ждет, прежде чем сделать следующий запрос
wait_time = between(1, 2)
# здесь и ниже - запросы, который делают юзер
# чтобы добавить новую команду - нужно добавить аналогичный метод
# например, добавляем запрос DELETE v2/[uuid]/logout:
#
# @task(1)
# def logout(self):
# self.make_request('logout', method='DELETE')
#
# если нужны параметры в GET-запрос, они добавляются через params={'key':'value'}:
# self.make_request('something', params={'key':'value'})
#
# если нужны json-данные в POST/PUT/PATCH - нужно исполбзовать json=:
# self.make_request('something', method='POST', json={'key':'value'})
#
@task(1) # 1 - это вес запроса, чем он больше - чем чаще этот запрос будет выполняться относительно других
def profile(self):
self.make_request('profile')
@task(1)
def configuration(self):
self.make_request('configuration')
@task(1)
def quest_daily(self):
self.make_request('quest/daily')
@task(1)
def profile_dailyBonus(self):
self.make_request('profile/dailyBonus')
@task(1)
def profile_message(self):
self.make_request('profile/message')
@task(1)
def achievement(self):
self.make_request('achievement')
@task(1)
def shop(self):
self.make_request('shop')
@task(1)
def roulette(self):
self.make_request('roulette')
@task(1)
def quest_expedition(self):
self.make_request('quest/expedition?type=free', params={"type":"free"})
@task(1)
def level(self):
self.make_request('level')
@task(1)
def level_idleReward_proportion(self):
self.make_request('level/idleReward/proportion')
@task(1)
def level_idleReward(self):
self.make_request('level/idleReward')
@task(1)
def post_level_idleReward(self):
self.make_request('level/idleReward', method='POST')
# здесь все, что происходит при создании нового юзера
# - получение токена
# - создание аккаунта
# - логин
def on_start(self):
self.uuid = str(uuid.uuid4())
self.authToken = ''
# client configuration
self.make_request(
'clientConfiguration',
params={"applicationVersion": "0.0.1", "applicationPackageName": "com.wakeappgames.worldofheroes" },
)
# client version
self.make_request(
'clientVersion',
params={"version":"0.0.1","applicationPackageName":"com.wakeappgames.worldofheroes"}
)
# get the token
response = self.make_request(
'token',
json={
"sessionId": str(uuid.uuid4()),
"installId": str(uuid.uuid4()),
"applicationPackageName":"com.wakeappgames.worldofheroes",
"applicationVersion":"0.0.1",
"appsflyerId":"",
"idfa":"",
"locale":"ru",
"model":"MacBookPro11,5",
"osVersion":"10.15.7",
"platform":"Iphone",
"pushToken":"",
"udid":self.uuid
},
method='POST'
)
self.authToken = response.json()['data']['token']
# create the user
self.make_request(
'account',
json={
"login":self.uuid,
"password":"",
"type":"Device"
},
method='POST'
)
# login
self.make_request(
'login',
json={
"login":self.uuid,
"password":"",
"type":"Device"
},
method='PUT'
)
# через этот метод делаются все запросы к бэку, сделан для удобства:
# - сам генерирует url по заданному action и uuid пользователя
# - подставляет авторизационный токен
# - обрабатывает json-ответ от сервера и проверяет его успешность
def make_request(self, action, params={}, data={}, json={}, method='GET'):
with self.client.request(
method,
f'/v2/{self.uuid}/{action}',
data=data,
json=json,
params=params,
name=f'/v2/[uuid]/{action}',
headers={"SignatureDisable": "1", "Authorization":f'Bearer {self.authToken}'},
catch_response=True,
timeout=10
) as response:
if response.status_code != 200:
response.failure(str(response.text) or str(response.status_code))
return response
message = response.json()['message']
if message == 'Successfully' or message == 'Успешно':
response.success()
else:
response.failure(message)
return response
Response time percentiles (approximated)
Type Name 50% 66% 75% 80% 90% 95% 98% 99% 99.9% 99.99% 100% # reqs
--------|------------------------------------------------------------|---------|------|------|------|------|------|------|------|------|------|------|------|
POST /v2/[uuid]/account 3600 3800 4100 4200 4400 4500 4700 4900 4900 4900 4900 100
GET /v2/[uuid]/achievement 2300 2600 2700 2800 3100 3300 3600 3700 6100 6100 6100 660
GET /v2/[uuid]/clientConfiguration 2200 2300 2400 2400 2500 2600 2600 2700 2700 2700 2700 100
GET /v2/[uuid]/clientVersion 2200 2400 2500 2600 2600 2700 2800 2800 2800 2800 2800 100
GET /v2/[uuid]/configuration 3300 3700 4100 4500 6200 7600 9500 11000 14000 14000 14000 681
GET /v2/[uuid]/level 2300 2500 2700 2800 3000 3300 3600 3800 4100 4100 4100 673
GET /v2/[uuid]/level/idleReward/proportion 2200 2400 2600 2700 2900 3100 3400 3500 4100 4100 4100 627
PUT /v2/[uuid]/login 2600 2800 3000 3100 3300 3400 3500 3700 3700 3700 3700 100
GET /v2/[uuid]/profile 2200 2500 2600 2700 3000 3200 3500 3700 4900 4900 4900 685
GET /v2/[uuid]/profile/dailyBonus 1900 2000 2200 2200 2500 2700 2900 3000 3400 3400 3400 691
GET /v2/[uuid]/profile/message 1900 2100 2200 2300 2500 2700 2900 2900 3500 3500 3500 680
GET /v2/[uuid]/quest/daily 2300 2500 2700 2800 2900 3200 3400 3600 4800 4800 4800 724
GET /v2/[uuid]/quest/expedition?type=free 2300 2600 2700 2800 3100 3300 3800 4000 5800 5800 5800 656
GET /v2/[uuid]/roulette 2200 2500 2600 2700 2900 3000 3300 3600 3900 3900 3900 674
GET /v2/[uuid]/shop 2300 2500 2600 2700 2900 3100 3400 3500 4300 4300 4300 673
POST /v2/[uuid]/token 2300 2500 2500 2500 2600 2700 2800 2800 2800 2800 2800 100
--------|------------------------------------------------------------|---------|------|------|------|------|------|------|------|------|------|------|------|
None Aggregated 2300 2500 2700 2800 3200 3600 4500 6000 11000 14000 14000 7924
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment