Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Ответ
Это самый важный вопрос в разработке. Как проверить что программа действительно работает — это основа качества. Рассмотрю систематичный подход.
1. Локальное тестирование
Unit тесты
Тестирую каждую функцию отдельно:
public class UserServiceTest {
private UserService userService;
private UserRepository repository;
@BeforeEach
void setup() {
repository = mock(UserRepository.class);
userService = new UserService(repository);
}
@Test
void shouldReturnUserById() {
// Arrange
User expected = new User(1L, "John", "john@example.com");
when(repository.findById(1L)).thenReturn(Optional.of(expected));
// Act
User actual = userService.getUser(1L);
// Assert
assertEquals(expected, actual);
verify(repository).findById(1L);
}
@Test
void shouldThrowExceptionWhenUserNotFound() {
// Arrange
when(repository.findById(999L)).thenReturn(Optional.empty());
// Act & Assert
assertThrows(UserNotFoundException.class,
() -> userService.getUser(999L)
);
}
}
Запуск:
mvn test
mvn test -Dtest=UserServiceTest
Integration тесты
Тестирую взаимодействие компонентов:
@SpringBootTest
@Transactional
public class UserRepositoryIntegrationTest {
@Autowired
private UserRepository repository;
@Autowired
private TestEntityManager em;
@Test
void shouldSaveAndRetrieveUser() {
// Arrange
User user = new User(null, "Jane", "jane@example.com");
// Act
User saved = repository.save(user);
em.flush();
em.clear();
User retrieved = repository.findById(saved.getId()).orElse(null);
// Assert
assertNotNull(retrieved);
assertEquals("Jane", retrieved.getName());
}
}
Запуск:
mvn integration-test
mvn test -Dgroups=integration
2. Code Coverage — проверка покрытия
Конфигурация:
<!-- pom.xml -->
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.10</version>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
<configuration>
<rules>
<rule>
<element>PACKAGE</element>
<excludes>
<exclude>*Test</exclude>
</excludes>
<limits>
<limit>
<counter>LINE</counter>
<value>COVEREDRATIO</value>
<minimum>0.80</minimum>
</limit>
</limits>
</rule>
</rules>
</configuration>
</plugin>
Запуск:
mvn test jacoco:report
# Отчёт в target/site/jacoco/index.html
3. Static Code Analysis
Проверка кода на ошибки без запуска:
SonarQube:
mvn clean verify sonar:sonar \
-Dsonar.projectKey=my-app \
-Dsonar.sources=src \
-Dsonar.host.url=http://localhost:9000
SpotBugs:
<plugin>
<groupId>com.github.spotbugs</groupId>
<artifactId>spotbugs-maven-plugin</artifactId>
<version>4.7.3.6</version>
<executions>
<execution>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
Lint (Checkstyle):
mvn checkstyle:check
4. Ручное тестирование
Локально
# Собрать
mvn clean package
# Запустить
java -jar target/myapp-1.0.0.jar
# Или для Spring Boot
mvn spring-boot:run
# Или запустить тесты в IDE
# IntelliJ IDEA: Right-click → Run
Функциональное тестирование
# Если это REST API
curl -X POST http://localhost:8080/api/users \
-H "Content-Type: application/json" \
-d '{"name": "John", "email": "john@example.com"}'
# Или использовать Postman/Insomnia
# Или писать скрипты
bash test_api.sh
Пример bash скрипта:
#!/bin/bash
BASE_URL="http://localhost:8080"
# Тест 1: GET /users
echo "Test 1: Getting users..."
RESPONSE=$(curl -s "$BASE_URL/api/users")
echo $RESPONSE | jq .
# Тест 2: POST /users
echo "Test 2: Creating user..."
curl -s -X POST "$BASE_URL/api/users" \
-H "Content-Type: application/json" \
-d '{"name": "Jane"}' | jq .
# Проверка результата
echo "Tests completed"
5. E2E тесты (Playwright)
Тестирую UI полностью:
// tests/auth.spec.ts
import { test, expect } from '@playwright/test';
test('User login flow', async ({ page }) => {
// Arrange
await page.goto('http://localhost:3000/login');
// Act
await page.fill('input[name="email"]', 'user@example.com');
await page.fill('input[name="password"]', 'password123');
await page.click('button[type="submit"]');
// Assert
await expect(page).toHaveURL('http://localhost:3000/dashboard');
await expect(page.locator('h1')).toContainText('Welcome');
});
Запуск:
npm run test:e2e
npx playwright show-report
6. Performance тестирование
JMH (Java Microbenchmark Harness)
public class StringConcatenationBenchmark {
@Benchmark
public String testStringConcat() {
String result = "";
for (int i = 0; i < 100; i++) {
result += "value";
}
return result;
}
@Benchmark
public String testStringBuilder() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 100; i++) {
sb.append("value");
}
return sb.toString();
}
}
Запуск:
mvn exec:java -Dexec.mainClass="org.openjdk.jmh.Main"
Load тесты (Apache JMeter)
# Скачать JMeter и создать test plan
jmeter -n -t test_plan.jmx -l results.jtl -j jmeter.log
7. Security проверки
OWASP Dependency Check
<plugin>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-maven</artifactId>
<version>8.0.0</version>
<executions>
<execution>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
mvn dependency-check:check
8. Логирование и мониторинг
public class UserService {
private static final Logger log = LoggerFactory.getLogger(UserService.class);
public User getUser(Long id) {
log.info("Fetching user with id: {}", id);
try {
User user = repository.findById(id)
.orElseThrow(() -> new UserNotFoundException(id));
log.info("User found: {}", user.getName());
return user;
} catch (Exception e) {
log.error("Error fetching user: {}", id, e);
throw e;
}
}
}
Проверка логов:
tail -f /var/logs/app.log | grep ERROR
9. Чеклист перед production
✓ Все юнит тесты проходят (mvn test)
✓ Integration тесты проходят
✓ Code coverage > 80%
✓ SonarQube issues исправлены
✓ Нет security vulnerabilities
✓ Performance acceptable
✓ E2E тесты пройдены
✓ Логирование работает
✓ Error handling везде
✓ Database migrations работают
✓ API документация актуальна
✓ Code review пройден
✓ Deployment процесс протестирован
10. Мониторинг в production
# Health check endpoint
curl http://production-server:8080/actuator/health
# Metrics
curl http://production-server:8080/actuator/metrics
# Logs
docker logs -f myapp
# Uptime
uptime
# Resource usage
htop
Мой процесс
- Локально: Юнит + интеграционные тесты
- CI/CD: Code coverage + static analysis + build
- Dev сервер: E2E тесты + manual smoke test
- Stage: Full smoke test + performance check
- Production: Health checks + monitoring
Аксиома
Программа, которая не протестирована, не работает.
Даже если она выглядит как работает, это просто потому что вы не нашли баг. Тестирование это не burden, это инвестиция в качество.