Ответ
Автотесты классифицируются по уровню тестирования и объекту проверки. Основные типы:
1. Unit-тесты (Модульные) Проверяют изолированно отдельные функции, методы или классы.
# Пример на Python (pytest)
def test_calculate_total():
result = calculate_total([100, 200, 300])
assert result == 600
2. API-тесты Проверяют корректность работы REST, GraphQL или других API.
// Пример на JavaScript (using axios and jest)
test('GET /users returns 200', async () => {
const response = await axios.get('https://api.example.com/users');
expect(response.status).toBe(200);
expect(Array.isArray(response.data)).toBe(true);
});
3. UI-тесты (E2E) Автоматизируют взаимодействие с пользовательским интерфейсом.
// Пример на Java (Selenium WebDriver)
@Test
public void userCanLogin() {
driver.findElement(By.id("email")).sendKeys("user@test.com");
driver.findElement(By.id("password")).sendKeys("secret");
driver.findElement(By.tagName("button")).click();
WebElement welcome = driver.findElement(By.className("welcome-msg"));
Assert.assertTrue(welcome.isDisplayed());
}
4. Интеграционные тесты Проверяют взаимодействие нескольких модулей или систем.
// Пример интеграционного теста для сервиса заказов
test('Order creation integrates with payment service', async () => {
const order = await orderService.create({ productId: 123 });
const paymentResult = await paymentService.process(order.id);
expect(paymentResult.status).toBe('SUCCESS');
expect(order.status).toBe('PAID');
});
5. Нагрузочные тесты Оценивают производительность и стабильность системы под нагрузкой.
# Пример сценария для Locust
from locust import HttpUser, task, between
class WebsiteUser(HttpUser):
wait_time = between(1, 3)
@task
def load_main_page(self):
self.client.get("/api/products")
@task(3)
def load_details(self):
self.client.get("/api/products/1")
Почему важна такая классификация? Она помогает построить тестовую пирамиду, где много быстрых и дешёвых unit-тестов в основании, и меньше медленных и дорогих UI-тестов на вершине. Это оптимизирует усилия и время выполнения.
Ответ 18+ 🔞
Да ты посмотри, какая хуйня развелась — классификация автотестов! Ну ладно, разберёмся, как эти штуки друг от друга отличаются, а то некоторые думают, что тест он и в Африке тест, ёпта.
1. Юнит-тесты (Модульные, они же самые мелкие) Вот это, блядь, основа основ! Берёшь одну функцию, один метод, один класс — и нахуй изолируешь от всего мира. Никаких баз данных, никаких внешних сервисов, чистая логика. Если тут всё ебёт — дальше можно не париться.
# Пример на Python (pytest)
def test_calculate_total():
result = calculate_total([100, 200, 300])
assert result == 600
Вот смотри: дали три числа, функция должна их сложить. Если не сложила — пидарас, иди переписывай. Всё просто, как три копейки.
2. API-тесты (Любимое дело всех интеграторов) Тут уже начинается веселье. Не трогаем интерфейс, а долбим прямо по заднице сервера — REST, GraphQL, да хоть SOAP, если ты мазохист. Проверяем, отвечает ли он как надо, не посылает ли нас нахуй с ошибкой 500.
// Пример на JavaScript (using axios and jest)
test('GET /users returns 200', async () => {
const response = await axios.get('https://api.example.com/users');
expect(response.status).toBe(200);
expect(Array.isArray(response.data)).toBe(true);
});
Типа, дай мне пользователей. Дал массив — молодец. Дал 404 — иди нахуй, сервер, у тебя ноги кривые.
3. UI-тесты (E2E, они же самые долгие и ненадёжные) О, ебать мои старые костыли, вот это уже цирк! Автоматизируем реального пользователя: тыкаем в кнопки, заполняем поля, ждём, пока страница прогрузится. Медленно, хрупко, но если работает — красота.
// Пример на Java (Selenium WebDriver)
@Test
public void userCanLogin() {
driver.findElement(By.id("email")).sendKeys("user@test.com");
driver.findElement(By.id("password")).sendKeys("secret");
driver.findElement(By.tagName("button")).click();
WebElement welcome = driver.findElement(By.className("welcome-msg"));
Assert.assertTrue(welcome.isDisplayed());
}
Смотри, вводим логин-пароль, жмём кнопку — если приветствие появилось, значит, не обосрались. Если нет — ну, пидарас, ищи багу, блядь.
4. Интеграционные тесты (Когда модули начинают общаться) А вот тут уже настоящая магия, блядь. Юниты работают по отдельности, но вместе-то они как? Вот, например, создали заказ — а платежная система его видит? Списала бабки? Обновила статус?
// Пример интеграционного теста для сервиса заказов
test('Order creation integrates with payment service', async () => {
const order = await orderService.create({ productId: 123 });
const paymentResult = await paymentService.process(order.id);
expect(paymentResult.status).toBe('SUCCESS');
expect(order.status).toBe('PAID');
});
Если один модуль говорит «заказ создан», а другой «денег нет» — это, сука, пиздец, а не интеграция. Надо чинить.
5. Нагрузочные тесты (Когда надо проверить, не сдохнет ли всё) А это, дружок, уже разговор на серьёзных щщах. Надо понять, выдержит ли твоё творение, когда на него навалится овердохуища народу. Не упадет ли сервер, не поплывут ли ответы.
# Пример сценария для Locust
from locust import HttpUser, task, between
class WebsiteUser(HttpUser):
wait_time = between(1, 3)
@task
def load_main_page(self):
self.client.get("/api/products")
@task(3)
def load_details(self):
self.client.get("/api/products/1")
Вот смотри: создаём виртуальных юзеров, которые как тараканы начинают ползать по апишке. Если всё быстро и без ошибок — красава. Если начались таймауты и 500-е — ну, извини, архитектор, иди переделывай, пизда тебе, а не система.
А зачем эта вся хуйня нужна? А затем, чувак, чтобы построить тестовую пирамиду, ёпта! Внизу — куча быстрых и дешёвых юнитов, они ловят косяки в логике. Выше — поменьше интеграционных и API-тестов, проверяют, что модули дружат. А на самом верху — совсем немного этих долгих и капризных UI-тестов, которые проверяют, что пользователь не обосрётся в процессе. Если делать наоборот — наверху гора, а внизу пусто — будешь ждать часами, пока все E2E отъебуться, и всё равно нихуя не поймёшь, где ошибка. Так что держи пирамиду в уме, и будет тебе счастье, в рот меня чих-пых!