目录
许多新手自动化工程师想知道如何为Android应用程序编写他们的第一个自动测试。在这篇文章中,我想回答这个问题。
关于这个主题已经写了很多。有关于如何在测试写作中使用该PageObject模式的详细说明等等。但是我们的任务是用Java为授权屏幕编写第一个简单的测试。让我们深入了解一下如何解决这个问题!
移动应用测试简介
目前,在测试几乎任何移动应用程序时,您将不得不处理两个操作系统:iOS和Android。本文将探讨如何处理Android应用程序。
要选择合适的移动应用测试方法,我们必须清楚所涉及的应用类型。目前,有三种类型的应用:
- 本机应用程序——这些是直接在智能手机上安装和运行的应用程序。本机应用程序不涉及与浏览器和Internet一起工作或交互;
- 基于Web的应用程序——这些应用程序适用于桌面和移动版本;
- 混合应用程序——具有内置功能的本机应用程序,可打开网页。
确定要使用的移动应用程序类型后,我们可以安全地继续开发测试。测试通常被理解为由一系列步骤组成,一旦完成,就会使产品达到所需的状态。在测试过程中,将执行整套预先确定的测试。
软件质量保证测试通常包括两种类型:手动和自动。在手动测试中,测试由测试人员执行;这个职位通常被称为手动QA工程师。测试人员是测试和应用之间的链接。它看起来像这样:
说测试人员直接使用应用程序是不准确的。在运行测试时,他们按下按钮或在字段中输入数据。换句话说,它们与应用程序界面进行交互。此外,测试器还可以与服务API和网络接口、CLI、GUI等一起使用。客户端程序使用API与服务器交互,而GUI则由人类使用。
手动测试无疑是好的,但让我们看看用自动化流程代替人工。软件客户端不是测试人员,而是与应用程序交互。谁来运行测试?当然,没错!测试框架将负责运行测试。它运行测试,显示结果,存储测试运行的历史记录,并执行更多功能。
要使用GUI界面,我们需要特殊的适配器,也称为驱动程序(是的,你们中的许多人会记得,要在计算机上播放声音,或者,比方说,为了确保视频卡传输视频显示信号,必须安装一些驱动程序)。例如,我们的测试包括一个步骤,涉及点击“搜索”按钮。驱动程序收到点击“搜索”按钮的命令,然后将该命令传递到我们应用程序中的所需界面。这样可以确保按下“搜索”按钮并成功通过测试。但是,如果没有按钮可以按下,或者由于某种原因,它没有打包,就会出现错误,测试就会崩溃。
解决一些非标准任务通常需要驱动程序的功能,或者需要提高日志记录级别。然后,使用各种包装器来解决此类问题。例如,Kakao或Kaspresso。这些包装器可能会有很大差异,具体取决于所涉及的任务。有些只不过是语法糖(不影响软件行为但使语言更人性化的句法特性)。相比之下,其他任务涵盖的范围相对较广的复杂任务。
安装工具
选择语言
可以使用各种语言来自动化测试过程,例如Java、Python、Kotlin、Swift、JavaScript等等。这完全取决于您的喜好和您追求的目标。我们将在示例中使用Java。您需要从官方网站下载并安装它才能执行此操作。
Android Studio
Android应用可以在物理设备或模拟器上运行。大多数情况下,自动测试是在模拟器上运行的。您需要从官方网站下载并安装Android Studio才能执行此操作。
Appium
我们可以使用的以下工具是Appium(一种帮助自动化Android和iOS应用程序的开源工具)。运行Appium有两种选择:UI或基于控制台。要安装和运行控制台版本,我们还需要NodeJs。请注意,UI版本可以从官方网站下载,并立即准备就绪。
Appium检查器
我们需要一个GUI检查器来查找定位器(定位器是界面中某个项目的路径,自动测试(自动测试)可以使用它来查找它)。
Appium Inspector只是一个Appium 客户端,带有一个用户界面,显示正在测试的应用程序的屏幕,我们可以在其中查看项目的路径。
IntelliJ IDEA
我们将在IntelliJ IDEA中开发测试,也可以从官方网站下载,我建议您选择社区版。
应用程序
我们将为一个应用开发测试,您可以在Android Studio中自行下载和构建。可在此链接获得。或者,您可以下载该应用程序。
设置和安装Android Studio模拟器
选择用于自动化Android测试的操作系统并不是特别重要。您可以使用Windows、Linux或MacOS。
要开始测试,我们需要安装Android SDK和Android Studio。我们将不得不创建一个模拟器。我们在这里只讨论这方面很短的时间,因为配置模拟器的指南已经很好地阐述了,并在官方文档中提供了基本细节。
设置Appium
一旦我们设置了Android Studio,我们就可以设置Appium了。打开我们之前安装的Appium UI。我们必须在主机字段中输入地址0.0.0.0,在端口字段中输入地址4723。
接下来,转到“编辑配置”并指定ANDROID_HOME和JAVA_HOME路径,如下面的屏幕截图所示,然后单击“保存并重新启动”:
请注意,您的路径可能与屏幕截图中显示的路径不同,至少通过提供不同的用户。
接下来,转到Appium中的“高级”选项卡,并检查以确保“服务器地址”和“服务器端口”字段中的设置与以下屏幕截图中的设置相同:
设置完所有必填字段后,单击“启动服务器”按钮并确保Appium Server正在运行:
我们现在不需要对它做任何事情;让我们让Appium服务器保持运行。
设置Appium Inspector和定位器搜索
为了让我们的测试了解我们将与哪些接口项进行交互,我们需要知道如何访问这些元素。为此,请运行Appium Inspector并指定Remote Host:0.0.0.0以及Remote Path /wd/hub,如下面的屏幕截图所示:
现在让我们继续讨论功能。功能是一组用于启动Appium会话的参数和值。该集的信息描述了运行模拟器时所需的“功能”,例如,某个移动操作系统或某个版本的设备。功能表示为键值对;这些值可以是任何有效的JSON类型。
{
"appium:platformName": "Android,"
"appium:deviceName": "autoschool10",
"appium:app": "/Users/s.yakovlev/Desktop/login.apk"
}
在appium:platformName变量中,我们指定Android平台,而在appium:deviceName变量中,我们指定我们创建的Android模拟器的名称,在本例中为“autoschool10”,以及.apk文件的路径。
让我们保存指定的功能,并将此预设命名为loginAndroidApp。这个名字并不重要,但它应该有意义并且对你来说是可以理解的。
保存的功能可在“保存的功能”选项卡中访问:
现在我们只需要打开Android Studio,运行我们之前创建的模拟器,然后在Appium Inspector中单击Start Session。
这将启动Appium Inspector,在左侧显示屏幕截图,在右侧显示项目树。
我们将编写三个测试:
- 第一个将检查标签栏中是否显示登录名,
- 第二个测试将检查有利的授权方案,
- 第三个测试将检查逆授权场景。
为此,我们需要知道这些项目的路径。让我们从选项卡栏开始。单击“登录名”,您将看到此项的属性显示在右侧:
让我们写出这个项目的id,我们稍后会用到它:com.example.login:id/toolbar
对“电子邮件”和“密码”字段执行相同的操作。“电子邮件”字段的ID将是com.example.login:id/username而“密码”字段的ID将是com.example.login:id/password。
另外,让我们找出“登录”或“注册”按钮的ID:
它的id将是com.example.login:id/login。
如果用户输入以下有效的电子邮件数据:admin@admin.ru 和密码:1234,则将显示以下文本:欢迎! 用户。让我们联接字段中的数据,并检查以确保:
但是,正如你所看到的,检查器中没有任何变化,而我们需要找出这个文本字段的id。没关系;让我们点击刷新按钮。
并截取新的屏幕截图。我们拉出了一个新的屏幕截图,我们现在可以找出这个文本字段com.example.login:id/succestext的id:
如果在模拟器中输入了无效的密码或电子邮件,则会显示授权错误消息以及相应的文本。
您可能已经注意到此错误消息具有相同的ID,但如果您仔细观察,您会发现文本字段中的错误文本完全不同。这正是我们所需要的。
现在我们已经写出了项目的所有ID,让我们开始编写测试。
配置库
我们将在IntelliJ IDEA中开发测试。为此,请启动IDEA并在桌面上创建一个目录,并将其命名为 androidAutomation。
创建默认项目后,让我们将库连接到它:
为了您的方便,我们将所有库都集中在一个地方。
打开我们已经创建的项目,创建libs目录:
接下来,将下载的库放在我们的目录中:
现在,让我们进入项目,在“项目结构”下,从libs文件夹中添加库:
我们已经添加了与工作相关的所有库,现在我们必须创建一个目录,我们的应用程序将位于其中。创建apps目录并将我们的应用程序拖入其中:
开发测试
现在让我们转到前面的Java目录并创建我们的第一个类,称为LoginTest,我们将在其中编写测试:
为了成功运行测试,我们需要setUp()、tearDown()方法和测试本身。让我们编写setUp()方法,在该方法中,我们将编写测试运行所需的所有参数,具体来说:
- platformName:模拟器的操作系统版本,在本例中为Android;
- deviceName:Android Studio中显示的模拟器名称,在本例中为名称autoschool10(模拟器的名称可以是任何内容,但最好确保它不是用西里尔文编写的);
- platformVersion:我们的操作系统版本——Android 10;
- automationName:我们使用Appium实现自动化;
- appPackage:测试应用的包com.example.login;
- appActivity:活动,即将要启动的屏幕。我们的应用程序中只有一个屏幕,此活动称为.ui.login.LoginActivity;
- app:在这里,我们指定应用程序的完整路径,在本例中,它是”/Users/{user_name}/Desktop/androidAutomation/apks/login.apk."
我们用这条线来连接Android驱动程序(Appium Android Driver是Android设备的测试自动化工具。该驱动程序是Appium移动测试自动化工具的一部分):
driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);
Android.uiautomator.testrunner.UiAutomatorTestCase,放置在Android设备上,打开SocketServer上的端口4723。此服务器接收命令,将其转换为相应的Android UI Automator命令,并在设备上运行这些命令。
完整的代码清单如下所示:
public void setUp() throws Exception
{
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability("platformName", "Android");
capabilities.setCapability("deviceName", "autoschool10");
capabilities.setCapability("platformVersion", "10");
capabilities.setCapability("automationName", "Appium");
capabilities.setCapability("appPackage", "com.example.login");
capabilities.setCapability("appActivity", ".ui.login.LoginActivity");
capabilities.setCapability("app",
"/Users/s.yakovlev/Desktop/androidAutomation/apks/login.apk");
driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);
}
让我们在以下tearDown()方法中终止驱动程序:
public void tearDown()
{
driver.quit();
}
接下来,让我们为每个测试添加注释@before—在测试之前执行,@After—在测试之后执行,@Test—为每个测试添加注释。
我们现在所要做的就是自己编写测试。我们将只编写三个测试。第一个将检查以确定登录屏幕是否已打开。第二个测试将检查授权(使用有效数据),第三个逻辑测试将使用无效数据检查批准。
标签栏测试
让我们写一个积极的屏幕标题测试。我们将声明一个名为screenTitle的变量,我们将在其中保存我们的元素。我们将通过id编写findElementById来搜索此元素。为了确保元素(项目)确实存在,让我们调用该isDisplayed()方法。
@Test
public void checkTitleScreen()
{
WebElement screenTitle = driver.findElementById("com.example.login:id/toolbar");
screenTitle.isDisplayed();
}
有效数据授权测试
让我们继续使用有效数据编写授权测试。步骤的顺序将是相同的。我们设置变量emailInput和passInput,在其中保存我们之前找到的元素。
要用数据填充字段,必须先单击该字段。有click()方法可以做到这一点,而该sendKeys()方法将用于输入我们要插入字段中的传输数据。
@Test
public void validRegistrationTest()
{
WebElement emailInput = driver.findElementById("com.example.login:id/username");
emailInput.isDisplayed();
emailInput.click();
emailInput.sendKeys("admin@admin.ru");
WebElement passInput = driver.findElementById("com.example.login:id/password");
passInput.isDisplayed();
passInput.click();
passInput.sendKeys("1234");
WebElement signInButton = driver.findElementById("com.example.login:id/login");
signInButton.isDisplayed();
signInButton.click();
WebElement successAuthText = driver.findElementByXPath
("//*[contains(@text, 'Welcome ! user')]");
successAuthText.isDisplayed();
}
请注意,我们按id查找项,而对于文本“Welcome ! user”,我们按XPath进行搜索。这是查找定位器的第二个选项。XPath用于浏览元素和属性。以下构造findElementByXPath("//[contains@text, 'Welcome ! user')]");用于在屏幕上的任何位置搜索文本。该contains()方法不需要所有读者都正确识别项目;只有部分文本就足够了,但这部分文本必须是唯一的。
无效数据授权测试
同样,我们针对数据无效的情况编写一个授权测试:
@Test
public void validRegistrationTest()
{
WebElement emailInput = driver.findElementById("com.example.login:id/username");
emailInput.isDisplayed();
emailInput.click();
emailInput.sendKeys("user@user.ru");
WebElement passInput = driver.findElementById("com.example.login:id/password");
passInput.isDisplayed();
passInput.click();
passInput.sendKeys("1111");
WebElement signInButton = driver.findElementById("com.example.login:id/login");
signInButton.isDisplayed();
signInButton.click();
WebElement successAuthText = driver.findElementByXPath
("//*[contains(@text, 'Login failed')]");
successAuthText.isDisplayed();
}
我们的测试现在已经编写好了,可以运行了。要运行所有测试,请单击LoginTest类旁边的绿色三角形:
重要提示:在启动之前,请确保Appium Server GUI正在运行,并且模拟器也在运行。
我们的测试正在运行,我们可以观察模拟器以查看该过程的进展情况——字段填充了数据;如果测试成功,则会标有绿色复选标记。
运行完成后,我们可以查看默认报告。它可能提供更多信息,但它仍然表明我们的测试是成功的。
结论
因此,我们研究了如何使用Java为Android移动应用程序编写测试。当然,这些测试远非完美。项目通常涉及编写整个框架并使用PageObject模式。但是我们的任务是编写我们的第一个测试,您可以在不使用PageObject模式的情况下开始使用。
https://www.codeproject.com/Articles/5358822/How-to-Write-Your-First-autotest-for-an-Android-Ap