Участвовал ли в разработке Automation Test
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Участвовал ли в разработке Automation Test
Да, я имею опыт разработки автоматизированных тестов и понимаю важность качественного автотестирования в разработке. Это критическая часть современного подхода к качеству кода.
Мой опыт с Automation Testing
Unit тестирование
Я регулярно пишу unit-тесты с использованием JUnit и Mockito:
public class UserServiceTest {
@ExtendWith(MockitoExtension.class)
static class FindByIdTests {
@Mock
private UserRepository userRepository;
@InjectMocks
private UserService userService;
@Test
void testFindUserById_Success() {
User expectedUser = new User(1L, "John Doe", "john@example.com");
when(userRepository.findById(1L)).thenReturn(Optional.of(expectedUser));
User actualUser = userService.findById(1L);
assertThat(actualUser).isEqualTo(expectedUser);
verify(userRepository, times(1)).findById(1L);
}
@Test
void testFindUserById_NotFound() {
when(userRepository.findById(999L)).thenReturn(Optional.empty());
assertThatThrownBy(() -> userService.findById(999L))
.isInstanceOf(UserNotFoundException.class);
}
}
}
Integration тестирование
Я использую Spring Boot TestContainers для интеграционного тестирования:
@SpringBootTest
@Testcontainers
class UserRepositoryIntegrationTest {
@Container
static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:15")
.withDatabaseName("testdb")
.withUsername("testuser")
.withPassword("testpass");
@Autowired
private UserRepository userRepository;
@Test
void testSaveAndFindUser() {
User user = User.builder()
.name("Alice")
.email("alice@example.com")
.build();
userRepository.save(user);
User found = userRepository.findByEmail("alice@example.com").orElseThrow();
assertThat(found).isNotNull();
assertThat(found.getName()).isEqualTo("Alice");
}
}
API тестирование
Для тестирования REST API использую RestAssured и Spring Test:
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class UserControllerTest {
@LocalServerPort
private int port;
@BeforeEach
void setUp() {
RestAssured.port = port;
}
@Test
void testGetUserById_ReturnsOk() {
given()
.pathParam("id", 1)
.when()
.get("/api/users/{id}")
.then()
.statusCode(HttpStatus.OK.value())
.body("id", equalTo(1))
.body("name", notNullValue());
}
@Test
void testGetNonExistentUser_Returns404() {
given()
.pathParam("id", 999)
.when()
.get("/api/users/{id}")
.then()
.statusCode(HttpStatus.NOT_FOUND.value());
}
}
Selenium и E2E тестирование
Для браузерного тестирования пользовался Selenium и WebDriver:
public class LoginPageTests {
private WebDriver driver;
private LoginPage loginPage;
@BeforeEach
void setUp() {
System.setProperty("webdriver.chrome.driver", "/path/to/chromedriver");
driver = new ChromeDriver();
loginPage = new LoginPage(driver);
}
@Test
void testSuccessfulLogin() {
loginPage.navigateTo("https://example.com/login");
loginPage.enterUsername("testuser");
loginPage.enterPassword("testpass");
loginPage.clickLoginButton();
assertThat(driver.getCurrentUrl()).contains("/dashboard");
}
@AfterEach
void tearDown() {
driver.quit();
}
}
Page Object Pattern
Для удобства и переиспользования кода применяю Page Object Model:
public class LoginPage {
private WebDriver driver;
@FindBy(id = "username")
private WebElement usernameField;
@FindBy(id = "password")
private WebElement passwordField;
@FindBy(xpath = "//button[@type='submit']")
private WebElement loginButton;
public LoginPage(WebDriver driver) {
this.driver = driver;
PageFactory.initElements(driver, this);
}
public void enterUsername(String username) {
usernameField.sendKeys(username);
}
public void enterPassword(String password) {
passwordField.sendKeys(password);
}
public void clickLoginButton() {
loginButton.click();
}
}
Best Practices в автотестировании
1. Принцип 80/20
- 80% тестов — юнит тесты (быстрые, надёжные)
- 10% тестов — интеграционные тесты
- 10% тестов — E2E тесты (медленные, хрупкие)
2. DRY принцип
- Создаю test utilities и helpers для повторяемого кода
- Использую фиксчуры и factories для создания тестовых данных
- Вынимаю магические строки в константы
3. Правильное наименование
// ✅ Хорошо
void testTransferMoney_WhenFromAccountHasInsufficientFunds_ThrowsException()
// ❌ Плохо
void test1()
4. Независимость тестов
- Каждый тест должен быть независимым
- Нет зависимостей между тестами
- Используются отдельные базы данных для тестов
5. Управление тестовыми данными
public class UserFixture {
public static User defaultUser() {
return User.builder()
.id(1L)
.name("Test User")
.email("test@example.com")
.build();
}
}
CI/CD интеграция
Тесты запускаются автоматически в CI/CD пайплайне:
stages:
- test
- build
- deploy
unit_tests:
stage: test
script:
- mvn test
coverage: '/Coverage: \d+\.\d+%/'
integration_tests:
stage: test
script:
- mvn verify -Pintegration
only:
- merge_requests
Инструменты, которые использую
- JUnit 5 — фреймворк для юнит-тестов
- Mockito — моков и стабов
- TestContainers — контейнеризация БД для тестов
- RestAssured — API тестирование
- Selenium — браузерное тестирование
- Jacoco — измерение покрытия кода
- Gradle/Maven — сборка и запуск тестов
Автоматизированное тестирование — это не роскошь, а необходимость в современной разработке. Хороший набор тестов даёт уверенность в коде и позволяет быстро выявлять регрессии.