Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
__pycache__/
*.pyc
.pytest_cache/

allure-results/
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Sprint_7

API-тесты для сервиса Яндекс Самокат.

## Технологии

- Python
- Pytest
- Requests
- Allure

## Запуск тестов

```bash
python -m pytest tests
28 changes: 28 additions & 0 deletions conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import pytest

from helpers import generate_courier_data
from courier_methods import (
create_courier,
login_courier,
delete_courier
)


@pytest.fixture
def created_courier():

payload = generate_courier_data()

create_courier(payload)

yield payload

login_response = login_courier(
payload["login"],
payload["password"]
)

courier_id = login_response.json()["id"]

delete_courier(courier_id)

35 changes: 35 additions & 0 deletions courier_methods.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import allure
import requests

from data import (
BASE_URL,
CREATE_COURIER_PATH,
LOGIN_COURIER_PATH,
DELETE_COURIER_PATH
)


@allure.step("Создать курьера")
def create_courier(payload):
return requests.post(
f"{BASE_URL}{CREATE_COURIER_PATH}",
data=payload
)


@allure.step("Авторизовать курьера")
def login_courier(login, password):
return requests.post(
f"{BASE_URL}{LOGIN_COURIER_PATH}",
data={
"login": login,
"password": password
}
)


@allure.step("Удалить курьера")
def delete_courier(courier_id):
return requests.delete(
f"{BASE_URL}{DELETE_COURIER_PATH}/{courier_id}"
)
13 changes: 13 additions & 0 deletions data.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
BASE_URL = "https://qa-scooter.praktikum-services.ru/api/v1"

CREATE_COURIER_PATH = "/courier"
LOGIN_COURIER_PATH = "/courier/login"
DELETE_COURIER_PATH = "/courier"

CREATE_ORDER_PATH = "/orders"
GET_ORDERS_PATH = "/orders"
CANCEL_ORDER_PATH = "/orders/cancel"
Comment on lines +3 to +9

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Можно лучше: адреса лучше вынести во внешний (например, urls). Они могут измениться, что затруднит поддержку тестов, плюс будет легче поддерживать несколько стендов если использовать конкатенацию адресов с базовым (BASE_URL)


CREATE_COURIER_ERROR = "Недостаточно данных для создания учетной записи"
LOGIN_ERROR = "Недостаточно данных для входа"
DUPLICATE_LOGIN_ERROR = "Этот логин уже используется. Попробуйте другой."
15 changes: 15 additions & 0 deletions helpers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import random
import string


def generate_random_string(length):
letters = string.ascii_lowercase
return ''.join(random.choice(letters) for _ in range(length))


def generate_courier_data():
return {
"login": generate_random_string(10),
"password": generate_random_string(10),
"firstName": generate_random_string(10)
}
24 changes: 24 additions & 0 deletions order_methods.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import allure
import requests

from data import (
BASE_URL,
CREATE_ORDER_PATH,
CANCEL_ORDER_PATH
)


@allure.step("Создать заказ")
def create_order(payload):
return requests.post(
f"{BASE_URL}{CREATE_ORDER_PATH}",
json=payload
)


@allure.step("Отменить заказ")
def cancel_order(track):
return requests.put(
f"{BASE_URL}{CANCEL_ORDER_PATH}",
params={"track": track}
)
3 changes: 3 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pytest==8.2.2
requests==2.32.3
allure-pytest==2.13.5
78 changes: 78 additions & 0 deletions tests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Sprint_7

## Автотесты API сервиса Яндекс Самокат

Проект содержит автоматизированные тесты API сервиса Яндекс Самокат.

### Используемые технологии

* Python 3.14
* pytest
* requests
* Allure

### Реализованные проверки

#### Создание курьера

* создание нового курьера;
* создание двух одинаковых курьеров;
* создание курьера без логина;
* создание курьера без пароля.

#### Логин курьера

* успешная авторизация;
* авторизация без логина;
* авторизация без пароля;
* авторизация с неверным паролем;
* авторизация несуществующего курьера.

#### Создание заказа

* заказ с цветом BLACK;
* заказ с цветом GREY;
* заказ с цветами BLACK и GREY;
* заказ без указания цвета.

#### Получение списка заказов

* получение списка заказов.

### Запуск тестов

Запуск всех тестов:

```bash
python -m pytest tests
```

### Генерация Allure-отчёта

Сформировать результаты:

```bash
python -m pytest tests --alluredir=allure-results
```

Открыть отчёт:

```bash
allure serve allure-results
```

### Структура проекта

```
Sprint_7
├── tests
│ ├── test_create_courier.py
│ ├── test_login_courier.py
│ ├── test_create_order.py
│ └── test_get_orders.py
├── conftest.py
├── data.py
├── helpers.py
├── requirements.txt
└── README.md
```
60 changes: 60 additions & 0 deletions tests/test_create_courier.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import allure

from helpers import generate_courier_data
from courier_methods import create_courier
from data import (
CREATE_COURIER_ERROR,
DUPLICATE_LOGIN_ERROR
)


class TestCreateCourier:

@allure.title("Успешное создание курьера")
def test_create_courier_success(self):

payload = generate_courier_data()

response = create_courier(payload)

assert response.status_code == 201
assert response.json() == {"ok": True}

@allure.title("Нельзя создать двух одинаковых курьеров")
def test_create_duplicate_courier(self):

payload = generate_courier_data()

create_courier(payload)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Можно лучше здесь и далее: создание курьера тут является предусловием, можно воспользоваться фикстурой created_courier


response = create_courier(payload)

assert response.status_code == 409
assert response.json()["message"] == DUPLICATE_LOGIN_ERROR

@allure.title("Создание курьера без логина")
def test_create_courier_without_login(self):

payload = {
"password": "12345",
"firstName": "Ivan"
}

response = create_courier(payload)

assert response.status_code == 400
assert response.json()["message"] == CREATE_COURIER_ERROR

@allure.title("Создание курьера без пароля")
def test_create_courier_without_password(self):

payload = {
"login": "test_login",
"firstName": "Ivan"
}

response = create_courier(payload)

assert response.status_code == 400
Comment on lines +35 to +58

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Можно лучше: шаги этих тестов схожи. Можно их объединить с помощью параметризации

assert response.json()["message"] == CREATE_COURIER_ERROR

44 changes: 44 additions & 0 deletions tests/test_create_order.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import allure
import pytest

from order_methods import (
create_order,
cancel_order
)


class TestCreateOrder:

@allure.title("Создание заказа с различными вариантами цвета")
@pytest.mark.parametrize(
"color",
[
["BLACK"],
["GREY"],
["BLACK", "GREY"],
[]
]
)
def test_create_order(self, color):

payload = {
"firstName": "Naruto",
"lastName": "Uzumaki",
"address": "Konoha",
"metroStation": 4,
"phone": "+79999999999",
"rentTime": 5,
"deliveryDate": "2026-06-10",
"comment": "Saske",
"color": color
}

response = create_order(payload)

assert response.status_code == 201
assert "track" in response.json()

track = response.json()["track"]

cancel_order(track)

Comment on lines +41 to +44

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Необходимо исправить: отмена заказа в тестах этого сценария - часть пост-условия, а не шаг теста. Лучше его вынести в фикстуры

22 changes: 22 additions & 0 deletions tests/test_get_orders.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import allure
import requests

from data import (
BASE_URL,
GET_ORDERS_PATH
)


class TestGetOrders:

@allure.title("Получение списка заказов")
def test_get_orders_returns_orders_list(self):

response = requests.get(
f"{BASE_URL}{GET_ORDERS_PATH}"
)

assert response.status_code == 200
assert "orders" in response.json()
assert isinstance(response.json()["orders"], list)

Loading