java - 如果在 testng.xml 中使用两个或多个类,Appium 应用程序会给出空指针异常
问题描述
如果在 testng.xml 中使用两个或更多类,Appium 应用程序将给出空指针异常 附件是以下代码。如果我使用 testng.xml 文件中的任何一个类,它工作正常。但是如果我在 testng.xml 文件中定义这两个类,它会给出空指针异常。请帮助...应用程序驱动程序类:
package wikipedia_app_setup;
import java.net.URL;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.testng.annotations.AfterSuite;
import org.testng.annotations.BeforeSuite;
import io.appium.java_client.AppiumDriver;
import io.appium.java_client.MobileElement;
public class Wikipedia_app_launch {
//public static AppiumDriver<MobileElement> driver;
public WebDriver driver;
@BeforeSuite
public WebDriver openWikipedia() throws Exception
{
DesiredCapabilities dc=new DesiredCapabilities();
dc.setCapability("deviceName", "Moto g5 plus");
dc.setCapability("udid","ZY223XXDVV");
dc.setCapability("platformName","Android");
dc.setCapability("platformVersion","8.1.0");
dc.setCapability("app","C:\\Users\\Keshavgoyal\\Downloads\\org.wikipedia.apk");
/* dc.setCapability("appPackage","com.google.android.calculator");
dc.setCapability("appActivity","com.android.calculator2.Calculator");*/
URL url=new URL("http://127.0.0.1:4723/wd/hub");
driver=new AppiumDriver<MobileElement>(url,dc);
System.out.println("Application Started");
Thread.sleep(10000);
return driver;
}
@AfterSuite
public void closeWikipedia() throws Exception
{
driver.quit();
}
}
一流的定位器类:
package wikipedia_login_page;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import junit.framework.Assert;
public class Login_test_elements {
//public AppiumDriver<WebElement> driver;
public WebDriver driver;
public final String wrongCredentialMessage = "Incorrect username or password entered";
// Form Elements
@FindBy(id ="org.wikipedia:id/menu_overflow_button")
public WebElement menuOverflowButton;
@FindBy(id = "org.wikipedia:id/explore_overflow_account_container")
public WebElement logOnButton;
@FindBy(id = "org.wikipedia:id/login_username_text")
public WebElement usernameTextbox;
@FindBy(xpath = "/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.view.ViewGroup/android.widget.FrameLayout[2]/android.widget.FrameLayout/android.widget.ScrollView/android.widget.LinearLayout/TextInputLayout[2]/android.widget.FrameLayout/android.widget.EditText")
public WebElement passwordTextbox;
@FindBy(id = "org.wikipedia:id/login_button")
public WebElement loginButton;
@FindBy(id = "org.wikipedia:id/snackbar_text")
public WebElement wrongCredentialToastMessage;
@FindBy(id = "org.wikipedia:id/explore_overflow_account_name")
public WebElement displayUsername;
@FindBy(xpath = "//android.widget.ImageButton[@content-desc=\"Navigate up\"]")
public WebElement navigateButton;
public Login_test_elements click_menu_overflow_button() {
menuOverflowButton.click();
return this;
}
public Login_test_elements click_logon_button() {
logOnButton.click();
return this;
}
public Login_test_elements enter_wrong_username_to_login() {
usernameTextbox.click();
usernameTextbox.sendKeys("rite2keshav");
return this;
}
public Login_test_elements enter_wrong_password_to_login() {
passwordTextbox.click();
passwordTextbox.sendKeys("rite2keshav");
return this;
}
public Login_test_elements click_login_button() throws InterruptedException {
loginButton.click();
Thread.sleep(5000);
return this;
}
public Login_test_elements validate_wrong_credential_message() {
Assert.assertTrue(wrongCredentialToastMessage.isDisplayed());
Assert.assertTrue(wrongCredentialToastMessage.getText().contains(wrongCredentialMessage));
return this;
}
public Login_test_elements enter_username_to_login() {
usernameTextbox.clear();
usernameTextbox.sendKeys("rite2keshav44");
return this;
}
public Login_test_elements enter_password_to_login() {
passwordTextbox.clear();
passwordTextbox.sendKeys("rite2keshav55");
return this;
}
public Login_test_elements click_navigate_button() throws InterruptedException {
navigateButton.click();
Thread.sleep(2000);
return this;
}
public Login_test_elements validate_successful_login() {
Assert.assertTrue(displayUsername.isDisplayed());
Assert.assertTrue(displayUsername.getText().contains(displayUser));
return this;
}
public Login_test_elements(WebDriver driver) {
this.driver=driver;
// PageFactory.initElements(this.driver, this);
}
}
一级测试班:
package wikipedia_login_page;
import org.openqa.selenium.support.PageFactory;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import wikipedia_app_setup.Wikipedia_app_launch;
public class Functional_login_tests extends Wikipedia_app_launch {
public Login_test_elements loginTestElements;
@BeforeClass
public void initElementsBeforeClass() {
loginTestElements = PageFactory.initElements(driver, Login_test_elements.class);
}
@Test(priority = 1, groups={"regression"}, description = "Login to wikipedia App with wrong credentials.\n"
+ "1. Click on menu button.\n"
+ "2. Click on logon button.\n"
+ "3. Enter wrong username.\n"
+ "4. Enter wrong password.\n"
+ "5. Click on login button.\n"
+ "6. Validate if app is showing wrong credential message.")
public void validate_login_to_wikipedia_app_with_wrong_credential() throws InterruptedException {
System.out.println("##### Current Function ####### " + new Functional_login_tests() {
}.getClass().getEnclosingMethod().getName() + "()");
loginTestElements
.click_menu_overflow_button()
.click_logon_button()
.enter_wrong_username_to_login()
.enter_wrong_password_to_login()
.click_login_button()
.validate_wrong_credential_message();
}
@Test(priority = 2, groups={"regression"}, description = "Login to wikipedia App.\n"
+ "1. Click on menu button.\n"
+ "2. Click on logon button.\n"
+ "3. Enter username.\n"
+ "4. Enter password.\n"
+ "5. Click on login button.\n"
+ "6. Validate if login is success.")
public void validate_login_to_wikipedia_app() throws InterruptedException {
System.out.println("##### Current Function ####### " + new Functional_login_tests() {
}.getClass().getEnclosingMethod().getName() + "()");
loginTestElements
.enter_username_to_login()
.enter_password_to_login()
.click_login_button()
.click_menu_overflow_button()
.validate_successful_login();
}
}
二等定位器类:
package wikipedia_search_bookmark;
import java.util.List;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.FindBys;
import junit.framework.Assert;
public class Search_bookmark_test_elements {
public WebDriver driver;
public final String searchedTitle = "Java";
public final String bookmarkName = "ProgLangArticles";
public final String articleAddedMessage = "Added to";
public final String articleRemovedMessage = "removed from list";
// Form Elements
@FindBy(id = "org.wikipedia:id/explore_overflow_account_name")
public WebElement displayUsername;
@FindBy(id = "org.wikipedia:id/search_container")
public WebElement searchArticleBox;
@FindBy(id = "org.wikipedia:id/search_src_text")
public WebElement searchTextbox;
@FindBys({ @FindBy(id = "org.wikipedia:id/page_list_item_container") })
private List<WebElement> searchedItems;
@FindBy(id = "org.wikipedia:id/view_page_title_text")
public WebElement searchedItemTitle;
@FindBy(xpath = "/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.support.v4.widget.DrawerLayout/android.view.ViewGroup/android.view.ViewGroup/android.widget.HorizontalScrollView/android.widget.LinearLayout/android.support.v7.app.ActionBar.Tab[1]")
public WebElement bookmarkButton;
@FindBy(id = "org.wikipedia:id/onboarding_button")
public WebElement gotItButton;
@FindBy(id = "org.wikipedia:id/text_input")
public WebElement bookmarkNameTextbox;
@FindBy(id = "android:id/button1")
public WebElement saveBookmarkButton;
@FindBy(id = "org.wikipedia:id/snackbar_text")
public WebElement addedToBookmarkListMessage;
@FindBy(xpath = "/hierarchy/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.ListView/android.widget.LinearLayout[2]")
public WebElement removeArticleFromListButton;
@FindBy(xpath = "/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.support.v4.widget.DrawerLayout/android.view.ViewGroup/android.view.ViewGroup/android.widget.FrameLayout[2]/android.widget.LinearLayout/android.widget.TextView")
public WebElement removedFromBookmarkListMessage;
public Search_bookmark_test_elements click_display_username() {
displayUsername.click();
return this;
}
public Search_bookmark_test_elements click_search_article_textbox() {
searchArticleBox.click();
return this;
}
public Search_bookmark_test_elements enter_article_to_search() throws InterruptedException {
searchTextbox.sendKeys("java");
Thread.sleep(5000);
return this;
}
public Search_bookmark_test_elements select_searched_item() throws InterruptedException {
searchedItems.get(1).click();
Thread.sleep(5000);
return this;
}
public Search_bookmark_test_elements validate_selected_item_title() {
Assert.assertTrue(searchedItemTitle.isDisplayed());
Assert.assertTrue(searchedItemTitle.getText().contains(searchedTitle));
return this;
}
public Search_bookmark_test_elements click_bookmark_button() {
bookmarkButton.click();
return this;
}
public Search_bookmark_test_elements click_gotit_button() {
gotItButton.click();
return this;
}
public Search_bookmark_test_elements enter_bookmark_name() {
bookmarkNameTextbox.clear();
bookmarkNameTextbox.sendKeys(bookmarkName);
return this;
}
public Search_bookmark_test_elements click_save_bookmark_button() {
saveBookmarkButton.click();
return this;
}
public Search_bookmark_test_elements validate_article_added_to_bookmark() {
Assert.assertTrue(addedToBookmarkListMessage.isDisplayed());
Assert.assertTrue(addedToBookmarkListMessage.getText().contains(articleAddedMessage));
searchedItemTitle.click();
return this;
}
public Search_bookmark_test_elements click_remove_article_from_list_button() {
removeArticleFromListButton.click();
return this;
}
public Search_bookmark_test_elements validate_article_removed_from_list() {
Assert.assertTrue(removedFromBookmarkListMessage.isDisplayed());
Assert.assertTrue(removedFromBookmarkListMessage.getText().contains(articleRemovedMessage));
return this;
}
public Search_bookmark_test_elements(WebDriver driver) {
this.driver=driver;
//PageFactory.initElements(new AppiumFieldDecorator(driver), this);
}
}
二等考试班:
package wikipedia_search_bookmark;
import org.openqa.selenium.support.PageFactory;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import wikipedia_app_setup.Wikipedia_app_launch;
public class Functional_search_bookmark_tests extends Wikipedia_app_launch {
public Search_bookmark_test_elements searchbookmarkTestElements;
@BeforeClass
public void initElementsBeforeClass() {
searchbookmarkTestElements = PageFactory.initElements(driver, Search_bookmark_test_elements.class);
}
@Test(priority = 1, groups={"regression"}, description = "Validate search item and its title.\n"
+ "1. Search for an item.\n"
+ "2. Validate searched item title.")
public void validate_search_article_and_title() throws InterruptedException {
System.out.println("##### Current Function ####### " + new Functional_search_bookmark_tests() {
}.getClass().getEnclosingMethod().getName() + "()");
searchbookmarkTestElements
// .click_display_username()
.click_search_article_textbox()
.enter_article_to_search()
.select_searched_item()
.validate_selected_item_title();
}
@Test(priority = 2, groups={"regression"}, description = "Validate add bookmark.\n"
+ "1. Search for an item.\n"
+ "2. Add item to bookmark.")
public void validate_search_article_add_bookmark() throws InterruptedException {
System.out.println("##### Current Function ####### " + new Functional_search_bookmark_tests() {
}.getClass().getEnclosingMethod().getName() + "()");
searchbookmarkTestElements
.click_bookmark_button()
.click_gotit_button()
.enter_bookmark_name()
.click_save_bookmark_button()
.validate_article_added_to_bookmark();
}
@Test(priority = 3, groups={"regression"}, description = "Validate remove article from bookmark.\n"
+ "1. Click on bookmark button.\n"
+ "2. Remove Item from bookmark.")
public void validate_search_article_remove_bookmark() throws InterruptedException {
System.out.println("##### Current Function ####### " + new Functional_search_bookmark_tests() {
}.getClass().getEnclosingMethod().getName() + "()");
searchbookmarkTestElements
.click_bookmark_button()
.click_remove_article_from_list_button()
.validate_article_removed_from_list();
}
}
测试ng.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite">
<test name="Functional_login_tests" preserve-order="true" parallel="none" verbose="2">
<!-- <groups>
<run>
<include name="regression"
</run>
</groups> -->
<classes>
<class name="wikipedia_login_page.Functional_login_tests" />
</classes>
</test>
<test name="Functional_search_bookmark_tests" preserve-order="true" parallel="none" verbose="2">
<!-- <groups>
<run>
<include name="regression" />
</run>
</groups> -->
<classes>
<class
name="wikipedia_search_bookmark.Functional_search_bookmark_tests" />
</classes>
</test>
<!-- <test name="Functional_rotate_app_tests" preserve-order="true" parallel="none"
verbose="2"> <groups> <run> <include name="preProdSanity" /> <include name="prodSanity"
/> <include name="regression" /> </run> </groups> <classes> <class name="wikipedia_rotate_app.Functional_rotate_app_tests"
/> </classes> </test> -->
</suite> <!-- Suite -->
解决方案
你需要改变
public WebDriver driver;
至
public static WebDriver driver;
说明:所以在上述设置中,两个 TestNG 类都有自己的 Setup 类实例。TestNG@BeforeSuite
在作为一个套件运行时,会将来自 Setup 类的两个实例的方法仅作为一个方法。因此,当该@BeforeSuite
方法运行时,它会初始化第一个 TestNG 类的公共变量driver
,该变量由@Test
First TestNG 类的方法使用。当第二个 TestNG 类开始执行时,@BeforeSuite
将不会再次执行,这导致driver
SecondTestNGClass 中自己的变量副本未初始化,并且它保持为 NULL。
从这里http://makeseleniumeasy...为我解决了同样的问题,请访问该网站以获取完整的示例说明
推荐阅读
- android - 如何将 Activity 对象传递给 onBindViewHolder 方法以在 getScaledBitmap 方法中使用该对象
- c++ - 使用较新的 boost 库和使用旧版本的预编译二进制文件
- php - 无法从数据库中获取 int 并使用它 PHP
- azure - 如何使用我在 Azure Active Directory 中创建的应用程序注册本地创建的应用程序?
- python - Pygame 蛇吃自己
- r - 打印数据集的 2 个连续数据条目的第一个和最后一个值以绘制差异 - 在 R 中
- javascript - 在 Ajax 上获取 PDF 的输出流并在另一个文档上打开它
- python - 安装 cx_Freeze
- angular - 如何在角度测试用例中模拟 @viewchild
- sql - SQL 行抛出错误 3134(插入语法)