appium基本使用,appium菜鸟教程
测试脚本教程8计算器模拟阶段2在上一个教程中,我们看到了如何使用计算机编程语言代码启动实践和建议会话:导入资源、通知所需的功能、网络驱动程序。对于您将使用实践和建议实现的所有项目,这个起点基本相同(在结构上)。现在,让我们开始映射一些元素,如数字和运算符。
以下是实践和建议生成的代码:
el1=驾驶员。按id查找元素( com。安卓。计算器2:id/digit _ 1 )el1。单击()el2=驱动程序。find _ element _ by _ accessibility _ id( plus )el2。单击()el3=驱动程序。按id查找元素( com。安卓。计算器2:id/digit _ 3 )el3。单击()el4=驱动程序。find _ element _ by _ accessibility _ id( equals )el4。单击()el5=驱动程序。查找_元素_按_可访问性_ id现在是时候组织我们的代码,并确定我们的应用程序的所有剩余元素。非常有用的提示:因为计算器是一个小应用程序(只有很少的元素),所以我决定映射所有元素。然而,在一个自动化项目中,通常我们有大量复杂网页的大型应用程序,其中包含大量的流程或元素,请将您真正使用的内容映射到您的项目中。否则,您的工作将主要集中在元素映射上,而这不是我们想要的
经过一些基本调整后,我将代码组织如下:
从测试脚本导入web驱动程序desired _ cap={ 平台名称: Android , deviceName: emulator-5554 , app package : com。安卓。计算器2 ,应用活动: com。安卓。计算器2。计算器 }驱动程序=网络驱动程序.remote( http://localhost:4723/wd/hub ,desired _ cap)# numbers num 1=driver。按id查找元素( com。安卓。计算器2:id/digit _ 1’)num 2=驱动程序。按id查找元素( com。安卓。计算器2:id/digit _ 2’)num 3=驱动程序。按id查找元素( com。安卓。计算器2:id/digit _ 3’)num 4=驱动程序。按id查找元素( com我们已经有了一些映射元素,但是我们如何执行算术运算呢?最基本、最简单的解决方案是以顺序方式再现测试行为,如下面的求和运算符示例:
数字1。单击()op _ mais。点击()数字2。单击()操作图标。单击()print( O result ado da soma foi:,result.text)现在我们知道可以开始输出的验证了。因此,现在我们可以比较计算器输出上的返回值是否与使用计算机编程语言代码执行求和操作时相同。简单地说,我是这样做的:
soma Python=int(num 1 . text)int(num 2 . text)somaappium=int(result . text)print( O result ado da soma via app ium foi:,somaappium)print( O result ado da soma via Python foi:,soma Python)assert soma Python==int(result . text),result ados Divergence es Entre O Python e O app ium 我的解决方案是用Python(somapython)创建一个变量来存储求和运算的结果,用Appium(somaappium)创建另一个变量来存储
然后,在屏幕上打印Appium和Python结果的结果,然后使用assert resource比较这些值。如果结果相等,验证通过,屏幕上不返回任何内容;否则,这意味着如果值不相等,终端上将返回一条错误消息。
在自动化项目中使用断言非常重要。如果不使用断言,就不可能将获得的结果与预期的结果进行比较。换句话说,无法验证收集到的结果是否符合预期结果(如果这是bug的话)。
阶段3:使用设计模式组织代码并生成功能测试流。好了,我们已经有了一个功能代码,但是没有应用任何模式。这个代码叫做espaguette。
现在是时候开始组织我们的代码,并使用类、构造函数和其他一些Python和面向对象的编程概念来分组一些相关的操作。
我想做的第一件事是开始使用一些设计模式概念(在这里我们不会提供更多关于这个主题的信息)来使我们的代码更清晰,更结构化,更容易自动化和维护。为此,我将负责Appium连接的代码隔离在一个名为webdriver.py的单独文件中,该文件位于同名的路径中:
从appium导入web Driver class Driver:def _ _ init _ _(self):desired_cap={ platform name : Android , deviceName: AppiumP , com.android.calculator2 ,app activity : com . Android . calculator 2 . calculator } self . instance=web Driver . remote( 3358 localhost:4723/wd/hub ,desired _ cap)在这些代码中,我为这个类创建了一个名为Driver的类和一个名为init的构造函数。然后,我把启动服务的表述从“drive”改成了“instance”,正好把读数解释清楚了。
然后,我创建了一个名为“pageobjects”的文件夹。在这个文件夹中,我将创建一个名为Calc.py的文件,我将在这个计算器的主应用程序屏幕上注册所有元素和操作。如果我们模拟多个软件(或者多个活动),我们会为每个软件创建一个文件,让代码更加有序清晰。我们这样做是因为我们使用了页面对象模式。
Calc.py文件开始导入一些Selenium库资源:
从webdriver.webdriver导入驱动程序从selenium.webdriver.support导入预期条件作为EC从selenium . web driver . support . wait导入web dr Iverwaitfromappium.webdriver.com mon . mobile按预期条件导入mobile我给了他一个EC昵称。该资源用于指示预期条件的值。WebDriverWait这个资源是从代码中消除非常著名的“time.sleep”的优秀解决方案。该资源可以等待某些特定元素可访问,也可以接收超时值。这就是所谓的隐式等待。By这个资源负责表明我们处于一个MobileBy环境中,所以我们可以使用特定的内容。
导入之后,就该创建一个类了,我称之为Calculadora。对于这个类,我还创建了一个构造函数来标识负责描述我们的类的元素,以及我们将从中实例化的对象。除了元素,我们还将创建与这个类(calculator)的行为相关的方法。这些方法包括加法、减法、除法和乘法。
在初始化元素的重构之前,值得一提的是,计算器中的所有数字(从0到9)都有前缀,只有最后一个元素的数字被更改。有了这些信息,我们可以尝试优化它。所以,我决定创造一种方法来处理这个问题。因此,我将首先只映射操作符元素和最一般的元素,比如结果。我们的映射结构如下:
class calculatora:def _ _ init _ _(self,driver):self . driver=driver self . result=web driver wait(self . driver . instance,10)。直到(EC . presence _ of _ element _ located(mobile by。ID, com . Android . calculator 2:ID/result ))self . soma=web driver wait(self . driver . instance,10)。直到(EC . presence _ of _ element _ located(mobile by。ACCESSIBILITY_ID, plus ))self . divisao=web driver wait(self . driver . instance,10)。直到(EC . presence _ of _ element _ located(mobile by。ACCESSIBILITY_ID, divide ))self . multiplica cacao=web driver wait(self . driver . instance,10)。直到(EC . presence _ of _ element _ located(mobile by。ACCESSIBILITY_ID, multiply ))self . subtracao=web driver wait(self . driver . instance,10)。直到(ec。element _ located的存在(mobileby。accessibility _ id, minus ))映射完这些元素后,我需要启动计算器应用程序的main方法。如前所述,我会用一种特殊的方法来识别数字,因为它们共用同一个前缀,只改变最后一个数字。我的代码如下所示:
def clicknumber(self,numero):_ num=str(numero)self . driver . instance . find _ element(mobile by。ID,com . Android . calculator 2:ID/digit _ _ num)。单击self.result.text中的()assert _ num, Resultado no result noo esperado com o valor inserto 这个解决方案只是一个优化代码的建议。你可以这样做或者想出任何其他的解决方案。
现在让我向您介绍unitTest库,以控制我们应用程序的测试流程。对于这个库,我们将使用两个非常重要的方法:setUp()和tearDown()。这些方法对于任何软件自动化项目都是必不可少的。set方法的目标是准备开始测试所需的一切;TearDown方法通过关闭环境测试中使用的所有服务来完成测试执行。为了在设计模式中使用所有这些,我将在这个文件夹中创建一个名为“tests”的文件夹和一个名为CalculadoraTestes.py的Python文件。在这个文件中,我会导入项目所需的所有文件,在构建类时,我会将类定义为一个测试用例类型(unittest。测试用例)。这是一个很简单的文件,我们会在上面写安装和反汇编方法(请注意),以及测试用例相关的方法。每一个以“test_”表达式开头的方法都会作为一个测试来执行——这是UnitTest库中一个非常好的资源。这个执行的顺序(如果你有不止一个带有“test_”的方法)是根据这些方法在代码中的分布来排序的。
好了,总结一下我们所做的,我们的项目由以下文件夹组成:
Webdriver,我们的应用程序连接已被隔离。
这里的PageObjects是元素的映射位置。对于每个页面,我们都有一个类——不一定在单独的文件中。相关页面的所有元素和功能都在这里确定和解决。
测试这里我们将创建开始和结束方法以及所有必要的测试。安装程序是负责开始执行的方法。拆除负责完成我们的执行。每一个以“test_”表达式开头的方法都会像测试一样被执行。这些函数是unitTest库中的资源。