Je m'appelle Lilia, je suis QA Lead dans l'un des projets du groupe financier BCS (un service de sélection d'offres avantageuses pour un client parmi un certain nombre de produits de prêt), et aujourd'hui je vais vous dire comment nous avons automatisé les tests de smock, quels problèmes nous avons rencontrés et quelle pile technologique nous utilisons.
Au début, nous avons décidé d'automatiser les tests de régression, mais au fil du temps, les fonctionnalités ont changé et nous avons réalisé que beaucoup de temps était consacré à la prise en charge des autotests déjà écrits. Par conséquent, ils ont décidé d'automatiser d'abord le test de fumée, puis de l'étendre pour effectuer automatiquement des tests de régression. Le département des tests a été chargé d'automatiser les tests de smocks dès que possible. le projet a continué de croître et d'acquérir des fonctionnalités supplémentaires.
Qu'est-ce que le test de fumée
Le test de fumée, comme on l'appelle également «test de fumée», est un test rapide des fonctionnalités les plus critiques.
Sur notre projet:
- Inscription / autorisation.
- Entrée
- Remplir le questionnaire.
- Offres de démonstration.
- Envoi d'une candidature / en cliquant sur le lien vers le site du partenaire.
- Rétroaction.
- Blocage.
Pile de technologies pour écrire des autotests
Nous écrivons des autotests sur une telle pile: Java + Selenium + Cucumber + reports dans Allure2.

Tests automatiques BDD pour tests de fumée
1. Fichier de fonctionnalité avec l'extension .feature avec une description des scripts de test dans Gerkin.
Un exemple:
: , @all : : : ********** : : **** : : : : : : :
2. Étapes étapes. Il contient des classes qui décrivent les actions avec des éléments sur la page et valident ces éléments.
Un exemple:
@When("^ (.*)") public void pressKey(String key) { webElementUtils.pressKey(key); } @When("^(.*): (.*)") public void press(String pageTitle, String elementName) { waitUtils.waitElementToBeClickable(getWebElementOnWebPageWithWaiter(elementName, pageTitle)).click(); } @When("^(.*): (.*)") public void checkCheckbox(String pageTitle, String elementName) { WebElement element = getWebElementOnWebPageWithWaiter(elementName, pageTitle); if (!webElementUtils.isCheckboxSelected(element)) { element.click(); } } @When("^(.*): (.*)") public void uncheckCheckbox(String pageTitle, String elementName) { WebElement element = getWebElementOnWebPageWithWaiter(elementName, pageTitle); if (webElementUtils.isCheckboxSelected(element)) { element.click(); } } @And("^(.*): (.*)$") public void erase(String pageTitle, String elementName) { WebElement element = getWebElementOnWebPageWithWaiter(elementName, pageTitle); webElementUtils.clearElement(element); } @And("^(.*): (.*) (.*)$") public void enterValue(String pageTitle, String elementName, String text) { WebElement element = getWebElementOnWebPageWithWaiter(elementName, pageTitle); webElementUtils.fillElementWithText(element, expressionUtils.parseString(text)); } @And("^(.*): (.*) (.*)$") public void selectValue(String pageTitle, String dropdownListName, String value) { WebElement element = getWebElementOnWebPageWithWaiter(dropdownListName, pageTitle); webElementUtils.selectValueFromCombobox(element, value); } @Then("^(.*): (.*) $") public void elementDoesNotContainAnyText(String pageTitle, String elementName) { WebElement element = getWebElementOnWebPageWithWaiter(elementName, pageTitle); assertEquals("", webElementUtils.getTextFromWebElement(element).trim()); } @Then("^(.*): (.*) (.*)$") public void checkSliderPosition(String pageTitle, String elementName, String expectedPosition) { WebElement element = getWebElementOnWebPageWithWaiter(elementName, pageTitle); String sliderTrackPosition = StringUtils.substringBetween(element.findElement(By.cssSelector(".rc-slider-track")).getAttribute("style"), "width: ", ";"); String sliderHandlePosition = StringUtils.substringBetween(element.findElement(By.cssSelector(".rc-slider-handle")).getAttribute("style"), "left: ", ";"); assertEquals(expectedPosition, sliderTrackPosition); assertEquals(expectedPosition, sliderHandlePosition); } @Then("^(.*): (.*)$") public void checkComponentIsDisplayed(String pageTitle, String component) { WebElement element = getWebElementOnWebPageWithWaiter(component, component); assertTrue(webElementUtils.isElementVisible(element)); } @When("^(.*): (.+) (.*)$") public void loadFileInField(String pageTitle, String fileName, String elementName) { WebElement element = getWebElementOnWebPage(elementName, pageTitle); File file = new File(Objects.requireNonNull(getClass().getClassLoader().getResource(fileName)).getFile()); element.sendKeys(file.getAbsolutePath()); } @Then("^(.+): (.+) (.+) (.+)$") public void checkAttributeInElement(String pageTitle, String elementName, String attributeName, String expectedValue) { WebElement element = getWebElementOnWebPage(elementName, pageTitle); String attribute = webElementUtils.getAttribute(element, attributeName); String message = String.format(" '%s' '%s' '%s' .\n" + " : '%s'.\n : '%s'.\n", attributeName, elementName, pageTitle, expectedValue, attribute); assertEquals(message, expectedValue, attribute); } @Then("^(.+): (.+) (.+)/$") public void checkValueTag(String pageTitle, String tagName, String expectedValue) { WebElement title = webDriver.findElement(By.tagName(tagName)); assertEquals(expectedValue, title.getAttribute("innerHTML").trim()); } }
3. Utilisation des localisateurs sur les pages (modèle PageObject)
Un exemple:
import org.openqa.selenium.WebElement; import org.openqa.selenium.support.FindBy; import ru.bcs.creditmarkt.acceptance.pageobject.annotation.PageObject; import ru.yandex.qatools.htmlelements.annotations.Name; @PageObject(title = "", path = "/entry/login") public class LoginPage extends WebPage { @Name(" ") @FindBy(xpath = "//a[text()='']") private WebElement registrationLink; @Name(" ") @FindBy(xpath = "//a[text()='']") private WebElement loginLink; @Name(" ") @FindBy(css = "#phone") private WebElement phoneInput; @Name(" ") @FindBy(css = "button[type=submit]") private WebElement receiveCodeButton; @Name(" ") @FindBy(css = "input#sms") private WebElement smsInput; @Name(" ") @FindBy(css = "button#personalAgreement") private WebElement personalAgreementCheckbox; @Name(" -") @FindBy(css = "div.wa-userpic") private WebElement chatBotIcon; }
4. Signaler dans Allure2

Configuration CI
Pendant que nous écrivions des autotests, le groupe financier BCS est apparu Selenoid, et nous avons pu configurer le lancement des tests en ligne de conduite GitLab
Organisation d'écriture d'autotests pour différents stands
Nous avons plusieurs stands où le développement, le débogage et l'acceptation ont lieu, et il y a aussi de nombreux stands de fonctionnalités où nous testons de nouvelles fonctions développées par des équipes distribuées.
Nous avons également plusieurs stands de branche qui correspondent à différents environnements de développement, lors du changement de fichiers sur le stand, le stand correspondant avec des tests automatiques démarre automatiquement.
Total
Maintenant dans notre projet, lors de la publication d'une version sur un stand d'acceptation, un ensemble complet de tests de fumée est automatiquement effectué en 15 minutes en mode automatique. En fonction des résultats, l'équipe de test décide d'accepter le candidat de sortie pour le test de régression.