Сведения о среде
Платформа: TestNG
Тип выполнения: параллельный
→
Тесты (parallel="tests")
Цель: запустить два полных независимых пользовательских потока (createLoanRequest и createLoanRequest2) одновременно, при этом каждый поток имеет строгую последовательную зависимость (перед началом входа в систему должна быть завершена регистрация).
Ожидаемое поведение (наблюдается в непараллельном режиме)
Когда я удаляю атрибут Parallel="tests" из тега, порядок выполнения в одном потоке правильный:
RegistrationTest выполняется полностью.
LoginTest выполняется полностью.
... и так далее.
Фактическая проблема в параллельном режиме
Когда установлен параметр Parallel="tests", два блока выполняются одновременно в отдельных потоках. Однако я заметил, что LoginTest в одном потоке может начинаться раньше или перекрывать завершение RegistrationTest в другом потоке или даже иногда в потоке выполнения того же потока.
Вот мой файл пакета testng.xml:
Код: Выделить всё
Регистрация:
Код: Выделить всё
public class RegistrationTest extends TestBase {
RegistrationPage registrationPage;
@BeforeClass
public void initPage() {
registrationPage = PageFactory.initElements(getDriver(), RegistrationPage.class);
}
@Test(priority = 1)
public void setupRegistrationTestData(){
SquadTestData1.userIDNumber = IDGenerator.getIdNumber(1); // new code
//SquadTestData1.userIDNumber = "1096407814";
GenericGenerator genericGenerator = new GenericGenerator();
String randomDigits = genericGenerator.generateRandomDigit(6);
SquadTestData1.userName = "FTest-" + randomDigits;
LocalBeneficiaryGenerator localBeneficiaryGenerator = new LocalBeneficiaryGenerator();
LocalBeneficiary randomLocalBeneficiary = localBeneficiaryGenerator.generateRandomLocalBeneficiary();
SquadTestData1.localBeneficiary = randomLocalBeneficiary;
SmartUIValidator.addStep("Test Data ↓↓↓↓");
SmartUIValidator.addStep("userIDNumber: " + SquadTestData1.userIDNumber);
SmartUIValidator.addStep("UserName: " + SquadTestData1.userName);
SmartUIValidator.addStep("userPassword: " + SquadTestData1.userPassword);
SmartUIValidator.addStep("Local Beneficiary: " + SquadTestData1.localBeneficiary.toString());
}
@Test(priority = 2)
public void registerNewUser() {
try {
/* MyTestClass myTestClass = new MyTestClass();
String methodID = myTestClass.getUniqueIdentifier(RegistrationPage.class, "registerNewUser");
TestCaseDependencyManager testCaseDependencyManager =TestCaseDependencyManager.logTestCaseDep(methodID);
testCaseDependencyManager.validateFailedDep();*/
registrationPage.navigateToCreateNewAccountRegistrationPage(FailureHandler.FailureHandling.STOP_ON_FAILURE);
registrationPage.insertUserName(SquadTestData1.userName, FailureHandler.FailureHandling.CONTINUE_ON_FAILURE);
registrationPage.insertPassword(SquadTestData1.userPassword, FailureHandler.FailureHandling.STOP_ON_FAILURE);
registrationPage.insertConfirmationPassword(SquadTestData1.userPassword, FailureHandler.FailureHandling.STOP_ON_FAILURE);
registrationPage.insertFirstNameAr(SquadTestData1.localBeneficiary.getFirstNameAR(), FailureHandler.FailureHandling.STOP_ON_FAILURE);
registrationPage.insertFatherNameAr(SquadTestData1.localBeneficiary.getFirstNameAR() + "أ", FailureHandler.FailureHandling.STOP_ON_FAILURE);
registrationPage.insertGrandFatherNameAr(SquadTestData1.localBeneficiary.getLastNameAR() + "ج" , FailureHandler.FailureHandling.STOP_ON_FAILURE);
registrationPage.insertLastNameAr(SquadTestData1.localBeneficiary.getLastNameAR() , FailureHandler.FailureHandling.STOP_ON_FAILURE);
registrationPage.insertFirstNameEn( SquadTestData1.localBeneficiary.getFirstNameEN(), FailureHandler.FailureHandling.STOP_ON_FAILURE);
registrationPage.insertFatherNameEn( SquadTestData1.localBeneficiary.getFirstNameEN() + "F" , FailureHandler.FailureHandling.STOP_ON_FAILURE);
registrationPage.insertGrandFatherNameEn( SquadTestData1.localBeneficiary.getFirstNameEN() + "G" , FailureHandler.FailureHandling.STOP_ON_FAILURE);
registrationPage.insertLastNameEn(SquadTestData1.localBeneficiary.getLastNameEN() , FailureHandler.FailureHandling.STOP_ON_FAILURE);
registrationPage.selectIdType("هوية", FailureHandler.FailureHandling.STOP_ON_FAILURE);
registrationPage.insertIdNumber(SquadTestData1.userIDNumber, FailureHandler.FailureHandling.STOP_ON_FAILURE);
registrationPage.selectGenderType("Male", FailureHandler.FailureHandling.CONTINUE_ON_FAILURE);
registrationPage.selectNationalityType("سعودي", FailureHandler.FailureHandling.CONTINUE_ON_FAILURE);
registrationPage.insertBirthDate("07152000", FailureHandler.FailureHandling.CONTINUE_ON_FAILURE); // mm/dd/yyy
registrationPage.clickOnCreateNewAccount(FailureHandler.FailureHandling.STOP_ON_FAILURE);
registrationPage.validateAccountRegistered(FailureHandler.FailureHandling.STOP_ON_FAILURE);
}
finally {
SmartUIValidator.assertAll();
}
//assertEquals(3, 5);
}
}
Код: Выделить всё
package com.sdb.tests.Systems.ProductiveFamiliesPortal.Login;
import com.sdb.base.*;
import com.sdb.base.testdata.SquadTestData1;
import com.sdb.pages.systems.ProductiveFamiliesPlatform.LoginPage.*;
import com.sdb.tests.Systems.CRMDynamics.AcceptLoanTest;
import com.sdb.tests.Systems.ProductiveFamiliesPortal.RegistrationNewAccountTest.RegistrationTest;
import org.openqa.selenium.support.PageFactory;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
public class LoginTest extends TestBase {
LoginPage loginPage;
@BeforeClass
public void initPage() {
loginPage = PageFactory.initElements(getDriver(), LoginPage.class);
}
@Test(priority = 1)
public void login() {
try {
/* MyTestClass myTestClass = new MyTestClass();
String methodID = myTestClass.getUniqueIdentifier(RegistrationTest.class, "registerNewUser");
TestCaseDependencyManager testCaseDependencyManager =TestCaseDependencyManager.logTestCaseDep(methodID);
testCaseDependencyManager.validateFailedDep();
*/
System.out.println("Is skip current test cases inside login ? " + getReportAttributes().isSkipCurrentTestCase());
loginPage.navigateToLoginPage(FailureHandler.FailureHandling.STOP_ON_FAILURE);
loginPage.insertUserName(SquadTestData1.userName, FailureHandler.FailureHandling.STOP_ON_FAILURE);
loginPage.insertPassword(SquadTestData1.userPassword, FailureHandler.FailureHandling.STOP_ON_FAILURE);
loginPage.clickOnLoginButton(FailureHandler.FailureHandling.STOP_ON_FAILURE);
System.out.println("I am here Update");
try {
Thread.sleep(9000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
finally {
SmartUIValidator.assertAll();
}
//assertEquals(3, 5);
}
}
Примечания:
1. Я намеренно удалил save-order="true" из тегов в этом примере, поскольку это поведение по умолчанию при использовании . Его обратное добавление не решило проблему.
2-
Примечание о выводе консоли (наблюдаемое прерывание потока)
Когда пакет работает параллельно, повторная регистрация вывода консоли появляется сначала при запуске, а затем исчезает, что указывает на критическое нарушение выполнения:
Начинают появляться журналы для RegistrationTest (указывая на его выполнение) начинается).
Вывод RegistrationTest внезапно останавливается или исчезает из представления консоли.
Журналы LoginTest начинают появляться немедленно.
Позже в выводах консоли появятся журналы RegistrationTest.
Вопросы
Зависит от порядка тегов в XML достаточно, чтобы гарантировать последовательное выполнение этих классов в рамках одного, когда пакет запускает параллельные="тесты"?
последовательный запуск на основе порядка классов, который я установил в xml
Подробнее здесь: https://stackoverflow.com/questions/797 ... ross-paral
Мобильная версия