appium教程8
计算器模拟阶段2
在上一个教程中,我们看到了如何使用Python代码启动Appium会话:导入资源、通知所需的功能、webdriver。对于您将使用Appium实现的所有项目,这个起点基本相同(在结构上)。现在,让我们开始映射一些元素,如数字和运算符。 以下是Appium生成的代码:
el1 = driver.find_element_by_id("com.android.calculator2:id/digit_1")
el1.click()
el2 = driver.find_element_by_accessibility_id("plus")
el2.click()
el3 = driver.find_element_by_id("com.android.calculator2:id/digit_3")
el3.click()
el4 = driver.find_element_by_accessibility_id("equals")
el4.click()
el5 = driver.find_element_by_accessibility_id("multiply")
el5.click()
el6 = driver.find_element_by_id("com.android.calculator2:id/digit_2")
el6.click()
el7 = driver.find_element_by_accessibility_id("equals")
el7.click()
el8 = driver.find_element_by_accessibility_id("minus")
el8.click()
el9 = driver.find_element_by_id("com.android.calculator2:id/digit_1")
el9.click()
el10 = driver.find_element_by_accessibility_id("equals")
el10.click()
el11 = driver.find_element_by_accessibility_id("divide")
el11.click()
el12 = driver.find_element_by_id("com.android.calculator2:id/digit_2")
el12.click()
el13 = driver.find_element_by_accessibility_id("equals")
el13.click()
现在是时候组织我们的代码,并确定我们的应用程序的所有剩余元素。非常有用的提示:因为Calculator是一个小应用程序(只有很少的元素),所以我决定映射所有元素。然而,在一个自动化项目中,通常我们有大量复杂网页的大型应用程序,其中包含大量的流程或元素,请将您真正使用的内容映射到您的项目中。否则,您的工作将主要集中在元素映射上,而这不是我们想要的 经过一些基本调整后,我将代码组织如下:
from appium import webdriver
desired_cap = {
"platformName": "Android",
"deviceName": "emulator-5554",
"appPackage": "com.android.calculator2",
"appActivity": "com.android.calculator2.Calculator"
}
driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_cap)
num1 = driver.find_element_by_id("com.android.calculator2:id/digit_1")
num2 = driver.find_element_by_id("com.android.calculator2:id/digit_2")
num3 = driver.find_element_by_id("com.android.calculator2:id/digit_3")
num4 = driver.find_element_by_id("com.android.calculator2:id/digit_4")
num5 = driver.find_element_by_id("com.android.calculator2:id/digit_5")
num6 = driver.find_element_by_id("com.android.calculator2:id/digit_6")
num7 = driver.find_element_by_id("com.android.calculator2:id/digit_7")
num8 = driver.find_element_by_id("com.android.calculator2:id/digit_8")
num9 = driver.find_element_by_id("com.android.calculator2:id/digit_9")
num0 = driver.find_element_by_id("com.android.calculator2:id/digit_0")
op_mais = driver.find_element_by_accessibility_id("plus")
op_multi = driver.find_element_by_accessibility_id("multiply")
op_menos = driver.find_element_by_accessibility_id("minus")
op_div = driver.find_element_by_accessibility_id("divide")
op_igual = driver.find_element_by_accessibility_id("equals")
我们已经有了一些映射元素,但是我们如何执行算术运算呢?最基本、最简单的解决方案是以顺序方式再现测试行为,如下面的求和运算符示例:
num1.click()
op_mais.click()
num2.click()
op_igual.click()
print('O resultado da soma foi: ', result.text)
现在我们知道可以开始输出的验证了。因此,现在我们可以比较计算器输出上的返回值是否与使用Python代码执行求和操作时相同。简单地说,我是这样做的:
somapython = int(num1.text) + int(num2.text)
somaappium = int(result.text)
print('O resultado da soma via Appium foi: ', somaappium)
print('O resultado da soma via Python foi: ', somapython)
assert somapython == int(result.text), 'Resultados divergentes entre o python e o Appium'
我的解决方案是使用Python(somapython)创建一个变量来存储求和运算的结果,并使用Appium(somaappium)创建另一个变量来存储计算器应用程序的结果字段上的值。
然后,在屏幕上打印Appium和Python结果的结果,然后使用assert资源比较这些值。若结果相等,则验证通过,并且在屏幕上不返回任何内容;否则,这意味着,如果值不相等,则在终端上返回一条错误消息。
在自动化项目中使用断言非常重要。如果不使用断言,就不可能比较获得的结果和预期的结果,换句话说,不可能验证收集的结果是否符合预期的结果(如果这是一个bug)。
第3阶段:使用设计模式组织代码并生成功能测试流
好的,我们已经有了一个功能代码,但是没有应用任何模式。这种代码称为espaguette
现在是时候开始组织我们的代码,使用类、构造函数和其他一些Python和面向对象的编程概念对一些相关的操作进行分组了。
我要做的第一件事是开始使用一些设计模式概念(我们在这里不提供关于这个主题的更多信息),使我们的代码更清晰,更结构化,更易于自动化和维护。为此,我将在一个名为webdriver.py的单独文件中隔离负责Appium连接的代码,该文件位于同名路径中:
from appium import webdriver
class Driver:
def __init__(self):
desired_cap = {
'platformName': 'Android',
'deviceName': 'AppiumP',
'appPackage': 'com.android.calculator2',
'appActivity': 'com.android.calculator2.Calculator'
}
self.instance = webdriver.Remote('http://localhost:4723/wd/hub', desired_cap)
在这些代码中,我创建了一个名为Driver的类,并为这个类创建了一个名为init的构造函数,其中列出了与对象相关的所有特征。然后,我将启动服务的表达式从“drive”修改为“instance”,只是清楚地说明了读数。
然后,我创建了一个名为“pageobjects”的文件夹,在这个文件夹中,我将创建一个名为Calc.py的文件,在这里我将注册这个计算器主应用程序屏幕上的所有元素和操作。若模拟多个软件(或更多的活动),我们将为每个软件创建一个文件,以使代码更加有序和清晰。我们这样做是因为我们使用的是页面对象模式。
Calc.py文件开始导入一些Selenium库资源:
from webdriver.webdriver import Driver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from appium.webdriver.common.mobileby import MobileBy
预期条件>>我给他起了一个EC昵称。此资源用于指示预期条件的值。WebDriverWait>>此资源是一个极好的解决方案,可以从代码中消除非常著名的“time.sleep”。此资源可以等待某些特定元素可访问,并且可能还接收超时值。这称为隐式等待。MobileBy>>此资源负责指示我们处于移动环境中,因此我们可以使用特定的内容。
导入之后,是时候创建一个类了,我称之为Calculadora。对于这个类,我还创建了一个构造函数来标识负责描述我们的类的元素,以及我们将从中实例化的对象。除了元素之外,我们还将创建与该类(计算器)行为相关的方法,这些方法包括和、减、除和乘法。
在初始化元素的重构之前,值得一提的是,计算器中的所有数字(从0到9)都有前缀,只更改元素的最后一个数字。有了这些信息,我们可以尝试优化它。所以,我决定创建一个方法来处理这个问题。因此,我将首先只映射操作符元素和最一般的元素,如结果。我们的映射结构如下所示:
class Calculadora:
def __init__(self, driver):
self.driver = driver
self.result = WebDriverWait(self.driver.instance, 10).until(EC.presence_of_element_located(
MobileBy.ID, 'com.android.calculator2:id/result'
))
self.soma = WebDriverWait(self.driver.instance, 10).until(EC.presence_of_element_located(
MobileBy.ACCESSIBILITY_ID, 'plus'
))
self.divisao = WebDriverWait(self.driver.instance, 10).until(EC.presence_of_element_located(
MobileBy.ACCESSIBILITY_ID, 'divide'
))
self.multiplicacao = WebDriverWait(self.driver.instance, 10).until(EC.presence_of_element_located(
MobileBy.ACCESSIBILITY_ID, 'multiply'
))
self.subtracao = WebDriverWait(self.driver.instance, 10).until(EC.presence_of_element_located(
MobileBy.ACCESSIBILITY_ID, 'minus'
))
在映射这些元素之后,我需要启动计算器应用程序的主要方法。如前所述,我将使用一种特殊的方法来识别数字,因为它们共享相同的前缀,只更改最后一个数字。我的代码是这样的:
def clicknumber(self, numero):
_num = str(numero)
self.driver.instance.find_element(MobileBy.ID, 'com.android.calculator2:id/digit_' + _num).click()
assert _num in self.result.text, 'Resultado no result n?o é o esperado com o valor inserido'
这个解决方案只是一个优化代码的建议。您可以这样做或提出任何其他解决方案。
现在让我向您介绍unitTest库来控制我们应用程序的测试流。通过使用这个库,我们将使用两个非常重要的方法:setUp()和tearDown()。这些方法对于任何软件自动化项目都是必不可少的。设置方法的目标是准备开始测试所需的一切;tearDown方法通过关闭环境测试中使用的所有服务来完成测试执行。为了在设计模式中使用所有这些,我将创建一个名为“tests”的文件夹,并在该文件夹中创建一个名为CalculadoraTestes.py的Python文件,在该文件中,我将导入项目所需的所有文件,并且在构建类时,我将定义该类为测试用例类型(unittest.TestCase)。这是一个非常简单的文件,我们将在上面编写安装和拆卸方法(请注意),以及与测试用例相关的方法。每个以“test_”表达式开头的方法都将作为测试执行-这是UnitTest库中非常好的资源。此执行的顺序(如果您有超过1个带有“test_”的metho)是根据这些方法在代码中的分布来排序的。
好的,总结我们所做的工作,我们的项目由以下文件夹组成:
Webdriver>>我们的应用程序连接已隔离。
PageObjects>>这里是元素的映射位置。对于每个页面,我们都有一个类-不一定在单独的文件中。相关页面的所有元素和功能都在此处确定和解决。
测试>>这里我们将创建开始和结束方法以及所有必要的测试。安装程序是负责开始执行的方法。TearDown负责完成我们的执行。每个以“test_”表达式开头的方法都将像测试一样执行。这些功能是来自unitTest库的资源。
|