مزود البيانات & TestNG XML: المعلمة في Selenium(مثال)
البارامترات في Selenium
البارامترات في Selenium هي عملية لتحديد معلمات البرامج النصية للاختبار من أجل تمرير بيانات متعددة إلى التطبيق في وقت التشغيل. إنها إستراتيجية تنفيذ تقوم تلقائيًا بتشغيل حالات الاختبار عدة مرات باستخدام قيم مختلفة. يسمى المفهوم الذي تم تحقيقه من خلال تحديد معلمات نصوص الاختبار اختبار يعتمد على البيانات.
نوع المعلمة في TestNG-
لجعل عملية تحديد المعلمات أكثر وضوحًا، سنستعرض خيارات تحديد المعلمات في أحد إطارات العمل الأكثر شيوعًا Selenium برنامج تشغيل الويب – TestNG.
هناك طريقتان والتي من خلالها يمكننا تحقيق المعلمة في TestNG
يمكن أن تكون المعلمات من Testng.xml على مستوى المجموعة أو الاختبار
يمكن للمعلمة من DataProvider أن تأخذ الطريقة وITestContext كمعلمة.
دعونا ندرسها بالتفصيل -
شرح المعلمات في TestNG
شرح المعلمات في TestNG هي طريقة تستخدم لتمرير القيم إلى طرق الاختبار كوسيطات باستخدام ملف .xml. قد يُطلب من المستخدمين تمرير القيم إلى طرق الاختبار أثناء وقت التشغيل. يمكن استخدام طريقة التعليق التوضيحي @Parameters في أي طريقة تحتوي على تعليق توضيحي @Test أو @Before أو @After أو @Factory.
شرح المعلمات باستخدام Testng.xml
حدد المعلمة باستخدام التعليقات التوضيحية عندما تريد التعامل مع التعقيد ويكون عدد مجموعات الإدخال أقل.
دعونا نرى كيف يعمل هذا
سيناريو الاختبار
الخطوة 1) قم بتشغيل المتصفح وانتقل إلى Google.com
الخطوة 2) أدخل كلمة البحث الأساسية
الخطوة 3) تحقق من أن القيمة المدخلة هي نفسها التي توفرها بيانات الاختبار الخاصة بنا
الخطوة 4) كرر 2 و 3 حتى يتم إدخال كافة القيم
مؤلف الاختبار | مفتاح البحث |
---|---|
Guru99 | الهند |
Krishna | الولايات المتحدة الأمريكية |
بهوبيش | الصين |
فيما يلي مثال لكيفية القيام بذلك بدون معلمات
package parameters; import org.testng.annotations.Test; import org.testng.AssertJUnit; import java.util.concurrent.TimeUnit; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.firefox.FirefoxDriver; public class NoParameterWithTestNGXML { String driverPath = "C:\\geckodriver.exe"; WebDriver driver; @Test public void testNoParameter() throws InterruptedException{ String author = "guru99"; String searchKey = "india"; System.setProperty("webdriver.gecko.driver", driverPath); driver= new FirefoxDriver(); driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); driver.get("https://google.com"); WebElement searchText = driver.findElement(By.name("q")); //Searching text in google text box searchText.sendKeys(searchKey); System.out.println("Welcome ->"+author+" Your search key is->"+searchKey); System.out.println("Thread will sleep now"); Thread.sleep(3000); System.out.println("Value in Google Search Box = "+searchText.getAttribute("value") +" ::: Value given by input = "+searchKey); //verifying the value in google search box AssertJUnit.assertTrue(searchText.getAttribute("value").equalsIgnoreCase(searchKey)); } }
دراسة، المثال أعلاه. تخيل فقط مدى تعقيد الكود عندما نفعل هذا لثلاث مجموعات إدخال
الآن، دعونا نحدد هذا باستخدام TestNG
للقيام بذلك، سوف تحتاج إلى
- قم بإنشاء ملف XML الذي سيقوم بتخزين المعلمات
-
في الاختبار، أضف تعليقًا توضيحيًا @Parameters
ها هو الكود الكامل
مستوى الاختبار TestNG. أكس
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd"> <suite name="TestSuite" thread-count="3" > <parameter name="author" value="Guru99" /> <parameter name="searchKey" value="India" /> <test name="testGuru"> <parameter name="searchKey" value="UK" /> <classes> <class name="parameters.ParameterWithTestNGXML"> </class> </classes> </test> </suite>
المعلمة معTestNGملف XML.java
package parameters; import org.testng.AssertJUnit; import java.util.concurrent.TimeUnit; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.firefox.FirefoxDriver; import org.testng.annotations.Optional; import org.testng.annotations.Parameters; import org.testng.annotations.Test; public class ParameterWithTestNGXML { String driverPath = "C:\\geckodriver.exe"; WebDriver driver; @Test @Parameters({"author","searchKey"}) public void testParameterWithXML( @Optional("Abc") String author,String searchKey) throws InterruptedException{ System.setProperty("webdriver.gecko.driver", driverPath); driver = new FirefoxDriver(); driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); driver.get("https://google.com"); WebElement searchText = driver.findElement(By.name("q")); //Searching text in google text box searchText.sendKeys(searchKey); System.out.println("Welcome ->"+author+" Your search key is->"+searchKey); System.out.println("Thread will sleep now"); Thread.sleep(3000); System.out.println("Value in Google Search Box = "+searchText.getAttribute("value") +" ::: Value given by input = "+searchKey); //verifying the value in google search box AssertJUnit.assertTrue(searchText.getAttribute("value").equalsIgnoreCase(searchKey)); } }
تعليمات تشغيل البرنامج النصي، حدد ملف XML وتشغيله كـ Test NG Suite
انقر بزر الماوس الأيمن على ملف .xml -> تشغيل كـ -> تستنج جناح (ملاحظة: جناح)
الآن، يمكن تعريف المعلمات على مستويين
- مستوى الجناح - المعلمات داخل علامة ل TestNG سيكون ملف XML بمثابة معلمة على مستوى المجموعة.
- مستوى الاختبار - المعلمات داخل ستكون علامة اختبار ملف XML هي معلمة مستوى الاختبار.
إليك نفس الاختبار مع معلمات مستوى المجموعة
NOTE: في حالة إذا كان اسم المعلمة هو نفسه في مستوى المجموعة ومستوى الاختبار، فستحصل معلمة مستوى الاختبار على الأفضلية على مستوى المجموعة. لذلك، في هذه الحالة، ستشارك جميع الفئات الموجودة داخل مستوى الاختبار هذا المعلمة المتجاوزة، وستشارك الفئات الأخرى التي تقع خارج مستوى الاختبار معلمة مستوى المجموعة.
[FAQ] الأسئلة الشائعة
العدد 1 لا يمكن تحويل قيمة المعلمة الموجودة في testng.xml إلى معلمة طريقة الاختبار المقابلة، وسوف يؤدي ذلك إلى حدوث خطأ.
خذ بعين الاعتبار المثال التالي
هنا، السمة "author" تساوي "Guru99" وهي سلسلة وفي طريقة الاختبار المقابلة تتوقع قيمة عددية، لذلك سنحصل على استثناء هنا.
العدد 2 لا تحتوي @Parameters الخاصة بك على قيمة مقابلة في test.xml.
يمكنك حل هذا الموقف عن طريق إضافة @خياري حاشية. ملاحظة في المعلمة المقابلة في طريقة الاختبار.
العدد رقم 3: تريد اختبار قيم متعددة لنفس المعلمة باستخدام Testng.xml
الجواب البسيط هو أن هذا لا يمكن القيام به! يمكن أن يكون لديك عدة معلمات مختلفة، ولكن يمكن أن تحتوي كل معلمة على قيمة واحدة فقط. يساعد هذا في منع القيم الثابتة في البرنامج النصي. وهذا يجعل التعليمات البرمجية قابلة لإعادة الاستخدام. فكر في الأمر كملفات تكوين للبرنامج النصي الخاص بك. إذا كنت تريد استخدام قيم متعددة لمعلمة، فاستخدم DataProviders
مزود البيانات في TestNG
مزود البيانات في TestNG هي طريقة تُستخدم عندما يحتاج المستخدم إلى تمرير معلمات معقدة. يجب إنشاء المعلمات المعقدة من Java يمكن تمرير كائنات معقدة مثل الكائنات من ملفات الخصائص أو من قاعدة البيانات بواسطة طريقة موفر البيانات. يتم شرح الطريقة بواسطة @DataProvider وهي تعيد مجموعة من الكائنات.
المعلمات باستخدام Dataprovider
يعد التعليق التوضيحي @Parameters أمرًا سهلاً ولكن للاختبار باستخدام مجموعات متعددة من البيانات نحتاج إلى استخدام موفر البيانات.
لملء الآلاف من نماذج الويب باستخدام إطار الاختبار الخاص بنا، نحتاج إلى منهجية مختلفة يمكن أن توفر لنا مجموعة بيانات كبيرة جدًا في تدفق تنفيذ واحد.
يتم تحقيق هذا المفهوم القائم على البيانات من خلال @DataProvider تعليق توضيحي في TestNG.
لديها واحد فقط اسم السمة'. إذا لم تقم بتحديد سمة الاسم، فسيكون اسم DataProvider هو نفس اسم الطريقة المقابلة.
يعود مزود البيانات كائن جافا ثنائي الأبعاد إلى طريقة الاختبار وطريقة الاختبار، سيتم استدعاء M مرات في نوع M * N من صفيف الكائنات. على سبيل المثال، إذا قام DataProvider بإرجاع مصفوفة مكونة من كائنات 2*3، فسيتم استدعاء حالة الاختبار المقابلة مرتين مع 2 معلمات في كل مرة.
مثال كامل
package parameters; import java.util.concurrent.TimeUnit; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.firefox.FirefoxDriver; import org.testng.Assert; import org.testng.annotations.BeforeTest; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; public class ParameterByDataprovider { WebDriver driver; String driverPath = "C:\\geckodriver.exe"; @BeforeTest public void setup(){ //Create firefox driver object System.setProperty("webdriver.gecko.driver", driverPath); driver = new FirefoxDriver(); driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); driver.get("https://google.com"); } /** Test case to verify google search box * @param author * @param searchKey * @throws InterruptedException */ @Test(dataProvider="SearchProvider") public void testMethod(String author,String searchKey) throws InterruptedException{ { WebElement searchText = driver.findElement(By.name("q")); //search value in google searchbox searchText.sendKeys(searchKey); System.out.println("Welcome ->"+author+" Your search key is->"+searchKey); Thread.sleep(3000); String testValue = searchText.getAttribute("value"); System.out.println(testValue +"::::"+searchKey); searchText.clear(); //Verify if the value in google search box is correct Assert.assertTrue(testValue.equalsIgnoreCase(searchKey)); } } /** * @return Object[][] where first column contains 'author' * and second column contains 'searchKey' */ @DataProvider(name="SearchProvider") public Object[][] getDataFromDataprovider(){ return new Object[][] { { "Guru99", "India" }, { "Krishna", "UK" }, { "Bhupesh", "USA" } }; } }
استدعاء DataProvider من فئة مختلفة
بشكل افتراضي، يوجد DataProvider في نفس الفئة التي توجد بها طريقة الاختبار أو فئتها الأساسية. لوضعها في فئة أخرى، نحتاج إلى جعل طريقة موفر البيانات ثابتة وفي طريقة الاختبار نحتاج إلى إضافة سمة dataProviderClass in @اختبار حاشية. ملاحظة.
مثال رمز
معلمة TestClassDataproviderWithClassLevel.java
package parameters; import java.util.concurrent.TimeUnit; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.firefox.FirefoxDriver; import org.testng.Assert; import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; public class ParameterDataproviderWithClassLevel { WebDriver driver; String driverPath = "C:\\geckodriver.exe"; @BeforeTest public void setup(){ System.setProperty("webdriver.gecko.driver", driverPath); driver = new FirefoxDriver(); driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); driver.get("https://google.com"); } @Test(dataProvider="SearchProvider",dataProviderClass=DataproviderClass.class) public void testMethod(String author,String searchKey) throws InterruptedException{ WebElement searchText = driver.findElement(By.name("q")); //Search text in google text box searchText.sendKeys(searchKey); System.out.println("Welcome ->"+author+" Your search key is->"+searchKey); Thread.sleep(3000); //get text from search box String testValue = searchText.getAttribute("value"); System.out.println(testValue +"::::"+searchKey); searchText.clear(); //verify if search box has correct value Assert.assertTrue(testValue.equalsIgnoreCase(searchKey)); } }
DataproviderClass.java
package parameters; import org.testng.annotations.DataProvider; public class DataproviderClass { @DataProvider(name="SearchProvider") public static Object[][] getDataFromDataprovider(){ return new Object[][] { { "Guru99", "India" }, { "Krishna", "UK" }, { "Bhupesh", "USA" } }; }}
أنواع المعلمات في Dataprovider
هناك نوعان من المعلمات التي تدعمها طريقة DataProvider.
خدمة التوصيل- إذا كان نفسه يجب أن يتصرف DataProvider بشكل مختلف مع طريقة اختبار مختلفة، واستخدام معلمة الطريقة.
في المثال التالي،
- نتحقق مما إذا كان اسم الطريقة هو testMethodA.
- إذا كانت الإجابة بنعم، قم بإرجاع مجموعة واحدة من القيمة
- وإلا قم بإرجاع مجموعة أخرى من القيمة
package parameters; import java.lang.reflect.Method; import java.util.concurrent.TimeUnit; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.firefox.FirefoxDriver; import org.testng.Assert; import org.testng.annotations.BeforeTest; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; public class ParameterByMethodInDataprovider{ WebDriver driver; String driverPath = "C:\\geckodriver.exe"; @BeforeTest public void setup(){ System.setProperty("webdriver.gecko.driver", driverPath); driver = new FirefoxDriver(); driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); driver.get("https://google.com"); } @Test(dataProvider="SearchProvider") public void testMethodA(String author,String searchKey) throws InterruptedException{ WebElement searchText = driver.findElement(By.name("q")); //Search text in search box searchText.sendKeys(searchKey); //Print author and search string System.out.println("Welcome ->"+author+" Your search key is->"+searchKey); Thread.sleep(3000); String testValue = searchText.getAttribute("value"); System.out.println(testValue +"::::"+searchKey); searchText.clear(); //Verify if google text box is showing correct value Assert.assertTrue(testValue.equalsIgnoreCase(searchKey)); } @Test(dataProvider="SearchProvider") public void testMethodB(String searchKey) throws InterruptedException{ { WebElement searchText = driver.findElement(By.name("q")); //Search text in search box searchText.sendKeys(searchKey); //Print only search string System.out.println("Welcome ->Unknown user Your search key is->"+searchKey); Thread.sleep(3000); String testValue = searchText.getAttribute("value"); System.out.println(testValue +"::::"+searchKey); searchText.clear(); //Verify if google text box is showing correct value Assert.assertTrue(testValue.equalsIgnoreCase(searchKey)); } } /** * Here DataProvider returning value on the basis of test method name * @param m * @return **/ @DataProvider(name="SearchProvider") public Object[][] getDataFromDataprovider(Method m){ if(m.getName().equalsIgnoreCase("testMethodA")){ return new Object[][] { { "Guru99", "India" }, { "Krishna", "UK" }, { "Bhupesh", "USA" } };} else{ return new Object[][] { { "Canada" }, { "Russia" }, { "Japan" } };} } }
هنا هو الإخراج
ITestContext– يمكن استخدامه لإنشاء معلمات مختلفة لحالات الاختبار بناءً على المجموعات.
في الحياة الواقعية، يمكنك استخدام ITestContext لتغيير قيم المعلمات بناءً على طرق الاختبار والمضيفين وتكوينات الاختبار.
في مثال الكود التالي
- لدينا مجموعتان أ و ب
- يتم تعيين كل طريقة اختبار لمجموعة
- إذا كانت قيمة المجموعة هي A، فسيتم إرجاع مجموعة بيانات معينة
- إذا كانت قيمة المجموعة هي B، فسيتم إرجاع مجموعة بيانات أخرى
package parameters; import java.util.concurrent.TimeUnit; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.firefox.FirefoxDriver; import org.testng.Assert; import org.testng.ITestContext; import org.testng.annotations.BeforeTest; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; public class ParameterByITestContextInDataprovider { WebDriver driver; String driverPath = "C:\\geckodriver.exe"; @BeforeTest(groups={"A","B"}) public void setup(){ System.setProperty("webdriver.gecko.driver", driverPath); driver = new FirefoxDriver(); driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); driver.get("https://google.com"); } @Test(dataProvider="SearchProvider",groups="A") public void testMethodA(String author,String searchKey) throws InterruptedException{ { //search google textbox WebElement searchText = driver.findElement(By.name("q")); //search a value on it searchText.sendKeys(searchKey); System.out.println("Welcome ->"+author+" Your search key is->"+searchKey); Thread.sleep(3000); String testValue = searchText.getAttribute("value"); System.out.println(testValue +"::::"+searchKey); searchText.clear(); //verify correct value in searchbox Assert.assertTrue(testValue.equalsIgnoreCase(searchKey)); } } @Test(dataProvider="SearchProvider",groups="B") public void testMethodB(String searchKey) throws InterruptedException{ { //find google search box WebElement searchText = driver.findElement(By.name("q")); //search a value on it searchText.sendKeys(searchKey); System.out.println("Welcome ->Unknown user Your search key is->"+searchKey); Thread.sleep(3000); String testValue = searchText.getAttribute("value"); System.out.println(testValue +"::::"+searchKey); searchText.clear(); //verify correct value in searchbox Assert.assertTrue(testValue.equalsIgnoreCase(searchKey)); } } /** * Here the DAtaProvider will provide Object array on the basis on ITestContext * @param c * @return */ @DataProvider(name="SearchProvider") public Object[][] getDataFromDataprovider(ITestContext c){ Object[][] groupArray = null; for (String group : c.getIncludedGroups()) { if(group.equalsIgnoreCase("A")){ groupArray = new Object[][] { { "Guru99", "India" }, { "Krishna", "UK" }, { "Bhupesh", "USA" } }; break; } else if(group.equalsIgnoreCase("B")) { groupArray = new Object[][] { { "Canada" }, { "Russia" }, { "Japan" } }; } break; } return groupArray; } }
ملاحظة: إذا قمت بتشغيل فئة الاختبار الخاصة بك مباشرةً، فسوف تقوم أولاً باستدعاء موفر البيانات الذي لا يمكنه الحصول على معلومات المجموعات لأن المجموعات غير متوفرة. ولكن بدلاً من ذلك، إذا قمت باستدعاء هذه الفئة عبر testng.xml، فسوف تتوفر بها معلومات المجموعات مع ITestContext. استخدم XML التالي لاستدعاء الاختبار
<!DOCTYPE suite SYSTEM "http://beust.com/testng/testng-1.0.dtd" > <suite name="test-parameter"> <test name="example1"> <groups> <run> <include name="A" /> </run> </groups> <classes> <class name="parameters.ParameterByITestContextInDataprovider" /> </classes> </test> <test name="example2"> <groups> <run> <include name="B" /> </run> </groups> <classes> <class name="parameters.ParameterByITestContextInDataprovider" /> </classes> </test> </suite>
الملخص
- البارامتر مطلوب لإنشاء اختبار يعتمد على البيانات.
- TestNG دعم نوعين من المعلمات، وذلك باستخدام @المعلمة+TestNG. أكس وباستخدام@DataProvider
-
In @المعلمة+TestNG. أكس يمكن وضع المعلمات في مستوى الجناح ومستوى الاختبار. لو
يتم الإعلان عن نفس اسم المعلمة في كلا المكانين؛ سوف تحصل معلمة مستوى الاختبار على الأفضلية على معلمة مستوى البدلة.
- باستخدام @Parameter+TestNG.xml يمكن تعيين قيمة واحدة فقط في المرة الواحدة، ولكن @DataProvider يعود مجموعة 2D من الكائن.
- إذا كان DataProvider موجودًا في فئة مختلفة عن الفئة التي توجد بها طريقة الاختبار،DataProvider ينبغي أن تكون طريقة ثابتة.
- هناك نوعان من المعلمات التي يدعمها DataProvider . خدمة التوصيل ITestContext.