自动化测试介绍

自动化框架

selenium

selenium工作原理

WebDriver提供了另外一种方式与浏览器进行交互。那就是利用浏览器原生的API,封装成一套更加面向对象的Selenium WebDriver API,直接操作浏览器页面里的元素,甚至操作浏览器本身(截屏,窗口大小,启动,关闭,安装插件,配置证书之类的)。由于使用的是浏览器的原生API,速度大大提高,而且调用的稳定性交给了浏览器厂商本身,显然是更加科学。然而带来的一些副作用就是,不同的浏览器厂商,对Web元素的操作和呈现存在不同程度的差异,这就要求Selenium WebDriver要分浏览器厂商的不同,提供不同的实现,例如Chrome有专门的ChromeDriver,Firefox有FirefoxDriver等等。

WebDriver Wire协议是通用的,也就是说不管是FirefoxDriver还是ChromeDriver,启动之后都会在某一个端口启动基于这套协议的Web Service。例如ChromeDriver初始化成功之后,默认会从http://localhost:46350开始,而FirefoxDriver从http://localhost:7055开始。后续我们调用WebDriver的任何API,都需要借助一个ComandExecutor发送一个命令,实际上是一个HTTP request给监听端口上的Web Service。在我们的HTTP request的body中,会以WebDriver Wire协议规定的JSON格式的字符串来告诉Selenium我们希望浏览器接下来做什么事情

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WzpXkbt6-1647764171020)(C:\Users\d\AppData\Roaming\Typora\typora-user-images\image-20211007221011625.png)]

具体过程如下:

(1)实例化WebDriver,Selenium首先会确认浏览器的native component是否存在可用而且版本匹配。若匹配则在目标浏览器里启动一整套Web Service。这套Web Service使用了Selenium自己设计定义的协议,名字叫做The WebDriver Wire Protocol。这套协议非常之强大,几乎可以操作浏览器做任何事情,包括打开、关闭、最大化、最小化、元素定位、元素点击、文件上传等等

(2)发送请求时,用WebDriver的HttpCommandExecutor类将命令转换为URL作为value,命令作为key一起存入map作为request,同时会在request的body中存放相应的By Xpath、id、name。实际发送的URL都是相对路径,后缀多以/session/:sessionId开头,这也意味着WebDriver每次启动浏览器都会分配一个独立的sessionId,多线程并行的时候彼此之间不会有冲突和干扰。比如我们常用到的find_element_by_class_name这个接口,会转化为/session/:sessionId/element这个url,然后在发出Http Request Body内再附上具体的参数,比如class name的值。比如我们要访问某一个网站,请求地址为:http://localhost:46350/wd/hub/session/sessionId/url,请求json内容:{"url":"http://www.qq.com"}。比如查找一个classname为test的元素,请求地址后缀为/session/sessionId/element,json内容{"using":"class_name","value":"test"}

(3)收到并执行了这个操作之后,也会回复一个Http Response。内容也是Json,会返回找到的element的各种细节,比如text、CSS selector、tag name、class name等等。比如:

{"sessionId":"XXXXX","status":0,"state":"success","value":
{"ELEMENT":"2"},"class":"XXX","hCode":"XXX"}

python+selenium环境搭建

(1)python的安装

官网地址:https://www.python.org

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KbIu7o2N-1647764171023)(C:\Users\d\AppData\Roaming\Typora\typora-user-images\image-20211007203108993.png)]

python安装包后,需要配置环境变量,其实在3.7的安装过程中,第一个界面有一个“add python to path”的选项可以勾选(大概是这个名字)。勾选之后会自动将python添加到系统环境变量Path中。当然你也可以选择手动添加,添加方法如下:

我的电脑右键选择属性–>高级系统设置–>环境变量–>环境变量–>系统变量:找到path变量并修改,在Path路径的最前面加入:C:\Python37;C:\Python37\Scripts; (如果你的python安装在其他路径请做相应的改动,笔者这里是默认路径)

特别要注意:很多新手会把Path中原来的内容删除掉,笔者提醒一下这个绝对不能这样做,慎重!慎重!慎重!

安装之后,运行CMD窗口,输入python指令,用于校验python是否安装成功。如下图表示成功!

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-k1JpJPf4-1647764171024)(C:\Users\d\AppData\Roaming\Typora\typora-user-images\image-20211007203154058.png)]

(2)selenium的安装

selenium可以通过pip命令进行安装,安装方法如下:

  1. 打开cmd窗口

  2. 输入:pip install selenium

  3. 等待cmd窗口提示successful,则selenium安装成功,如中途中断了继续输入pip install selenium重新安装,不影响!

(3)chrome浏览器

Chrome官网:https://www.google.cn/chrome/

(4)安装chrome浏览器驱动

当Selenium提出了WebDriver的概念之后,它提供了利用浏览器原生的接口,封装成一套更加面向对象的Selenium WebDriver API,直接操作浏览器页面里的元素,甚至操作浏览器本身(截屏,窗口大小,启动,关闭,安装插件)。

​ 由于使用的是浏览器原生的接口,速度大大提高,而且调用的稳定性交给了浏览器厂商本身,显然是更加科学。然而带来的一些副作用就是,不同的浏览器厂商,对Web元素的操作和呈现多少会有一些差异,这就直接导致了Selenium WebDriver要分浏览器厂商不同,而提供不同的实现。例如Firefox就有专门的geckoDriver驱动,Chrome就有专门的Chrome驱动等。

这里特别要注意:chrome浏览器驱动必须和安装的chrome浏览器版本对应。那么如何保证对应呢?

1.先检查chrome浏览器的版本:点击chrome浏览器右上角的三个点–>帮助–>关于Google Chrome,如下图所示

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pyLiZwob-1647764171025)(C:\Users\d\AppData\Roaming\Typora\typora-user-images\image-20211007204144539.png)]

2.chrome浏览器驱动下载地址:

Chromedriver驱动下载地址:http://npm.taobao.org/mirrors/chromedriver/

python+selenium自动化之旅

#demo
from selenium import webdriver
import os
import json
cookies = {'name': 'NEWOPPOSID',
           'value': 'eyJpdiI6IlU0MkRaS0s2RGRobkxCcG5ZdGRYN2c9PSIsInZhbHVlIjoicC9nTVFhWldvTllhTUQ4bVVLQkVxcktEWTFpemFkVG81amVYVWM3d2lDclZPVGVlbWhYeWh3TTNlM0JnbWsvYnorMUowRVpYUzBmODhpczVsY0NwWVdMY2JqNXU4NUtCK2FxTUNsZWNHREZrQ1Y3Slh2THZNckcybldlMWdqb0YiLCJtYWMiOiIwMjczZTBjYWY0M2RkZWFiYzM4MmU3OTdiNmRjMzRlNDEwOGVjMDNhODU5NTRiMDM0NjRjNWJkYmQ3Y2UyYzk2In0='}
dir = os.path.dirname(os.path.abspath('.'))
chrome_driver_path = dir + '/tools/chromedriver_94.exe'
driver = webdriver.Chrome(executable_path=chrome_driver_path)
driver.get('https://store.oppo.com/cn/m/order/list')
# driver.delete_all_cookies()
driver.add_cookie(cookies)
driver.refresh()
print(driver.get_cookies())

appium

appium工作原理

介绍

Appium是一个开源工具,用于自动化iOS、Android设备和Windows桌面平台上的原生、移动Web和混合应用。

"原生应用"指那些用iOS、Android或者WindowsSDK编写的应用。

"移动web应用"是用移动端浏览器访问的应用(Appium支持iOS上的Safari、Chrome和Android上的内置浏览器)。

"混合应用"带有一个"webview"的包装器——用来和Web内容交互的原生控件。

重要的是:Appium是跨平台的:它允许你用同样的API对多平台写测试,做到在iOS、Android和Windows测试套件之间复用代码。

Appium关键词

Appium是基于nodejs的HTTP服务器,用于创建和处理基JSON wire protocol协议的多webdriver会话,支持IOS和android平台。

以下为Appium架构中关键词:

会话(session):标识Appium客户端和Appium服务器端惟一交互

Desired Capabilities:用于告诉Appium服务端要启动一个什么类型的自动化测试会话

Appium服务器:基于nodejs写的HTTP服务器,实现了对JSON wire protocol的处理

Appium客户端:支持多语言(python、ruby、java、php、javascript、C#)API,提供给测试或开发人员编写appium自动化测试脚本,另外还提供了Inspector用于查看APP的层级结构,便于分析APP的UI结构

APPIUM IOS端工作原理

下面我们通过一张图来看下IOS端APPIUM全过程工作原理:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GwmbzH7H-1647764171025)(C:\Users\d\AppData\Roaming\Typora\typora-user-images\image-20211007221429115.png)]

APPIUM Android端工作原理

下面我们通过一张图来看下android端APPIUM全过程工作原理:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qJuCkBKi-1647764171026)(C:\Users\d\AppData\Roaming\Typora\typora-user-images\image-20211007221506853.png)]

说明

  1. 整个箭头指向为一个完成的指令循环
  2. webdriver script需要自动化测试人员自己编写对应的测试脚本
  3. 建议大家去了解下JSON wire protocol
  4. 建议大家去了解下instruments
  5. 建议大家去了解下UiAutomator

windows+python+appium环境搭建

Appium 官网: http://appium.io/

安装方式一: 使用NodeJS 安装

首先到NodeJS官网下载安装最新的NodeJS,Windows下属于傻瓜安装。安装好之后你可以配置NodeJS的安装源,在国内一般都用taobao的镜像,速度还不错

在个人目录下新建一个 .npmrc 文件,写入

registry=https://registry.npm.taobao.org/
使用npm命令安装 Appium
npm install -g appium
安装appium-doctor

通过运行appium-doctor命令可以快速检查appium的环境问题

npm install -g appium-doctor

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2ssd1UAP-1647764171027)(C:\Users\d\AppData\Roaming\Typora\typora-user-images\image-20211007212010670.png)]

如果安装成功,那么就可以通过 appium 命令启动 appium server

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HLPcR7l2-1647764171028)(C:\Users\d\AppData\Roaming\Typora\typora-user-images\image-20211007211809108.png)]

安装方式二: 使用Appium安装包

Appium 目前托管在github,正确的下载地址应该为:

  • https://github.com/appium/appium-desktop/releases
  • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wB74DXyG-1647764171028)(C:\Users\d\AppData\Roaming\Typora\typora-user-images\image-20211007212233809.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-S9cnr9dp-1647764171029)(C:\Users\d\AppData\Roaming\Typora\typora-user-images\image-20211007214637614.png)]

注意,你可以不安装Appium 桌面版,但是命令行版应该还是需要安装的,因为自动化测试运行时一般都是通过命令启动和关闭Appium,桌面版并不提供命令行功能,只是为了调试方便

关于appium的介绍文档

http://appium.io/docs/cn/about-appium/intro/

安装 Appium-Client

讨论Python实现的Appium测试

pip install Appium-Python-Client

如果需要使用其他编程语言,下表供参考:

语言/框架Github版本库以及安装指南
Rubyhttps://github.com/appium/ruby_lib
Pythonhttps://github.com/appium/python-client
Javahttps://github.com/appium/java-client
JavaScript (Node.js)https://github.com/admc/wd
Objective Chttps://github.com/appium/selenium-objective-c
PHPhttps://github.com/appium/php-client
C# (.NET)https://github.com/appium/appium-dotnet-driver
RobotFrameworkhttps://github.com/jollychang/robotframework-appiumlibrary
环境变量设置
环境变量
ANDROID_HOMEAndroid SDK 的安装位置
JAVA_HOMEJDK 或者 JRE 的安装位置
加入 PATH%ANDROID_HOME%\tools
加入 PATH%ANDROID_HOME%\platform-tools
加入 PATH%JAVA_HOME%\bin
加入 PATH%ANDROID_HOME%\build-tools??version?? (可选)

完成第一个自动化测试

启动appium服务并连接手机

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-92a3ZQak-1647764171030)(C:\Users\d\AppData\Roaming\Typora\typora-user-images\image-20211007213424471.png)]

import time
from appium import webdriver

capabilities = {}
# Android平台测试
capabilities['platformName'] = 'Android'
# 测试手机版本为11
capabilities['platformVersion'] = '11'
capabilities['deviceName'] = '73185eaf'
# 系统手机中的联系人app的包名
capabilities['appPackage'] = 'com.android.contacts'
# 系统手机中的联系人app的主入口activity
capabilities['appActivity'] = '.activities.PeopleActivity'
capabilities['unicodeKeyboard'] = True
capabilities['resetKeyboard'] = True
# 连接测试机所在服务器服务器
driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', capabilities)
try:
    # com.android.contacts:id/floating_action_button为通过uiautomatorviewer截取联系人界面获取到的
    element = driver.find_element_by_id('com.android.contacts:id/floating_action_button')
    #如果找到该id所指定控件,则进行点击操作
    element.click()
except:
    print("exit")
    pass
time.sleep(2)
#断开连接
driver.quit()

常见问题

1:An unknown server-side error occurred while processing the command

selenium.common.exceptions.WebDriverException: Message: An unknown server-side error occurred while processing the command. Original error: Unable to find an active device or emulator with OS 10. The following are available: 73185eaf (11)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hgAvEQKG-1647764171031)(C:\Users\d\AppData\Roaming\Typora\typora-user-images\image-20211007213654910.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-muqmpiil-1647764171032)(C:\Users\d\AppData\Roaming\Typora\typora-user-images\image-20211007214108581.png)]

1、先检查包名是否正确(正常情况下包名不会错误)通过命令行查看包名:aapt dump badging shoujibaidu.apk

package: name='com.baidu.searchbox' versionCode='96732800' versionName='11.17.0.13' platformBuildVersionName=''
launchable-activity: name='com.baidu.searchbox.SplashActivity'  label='Baidu' icon=''

2、检查对应包的appActivity是否正确:如果与命令行的activity不一致改过来就ok了

android版本改成11,问题解决

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-22X6hUUr-1647764171033)(C:\Users\d\AppData\Roaming\Typora\typora-user-images\image-20211007223910719.png)]

unittest

pytest

Pytest安装和介绍

pip install -U pytest
C:\Users\d>pytest --version  #会展示当前自己安装的版本
pytest 6.2.4

官方文档:

https://docs.pytest.org/en/latest/contents.html

https://www.osgeo.cn/pytest/contents.html

setup和teardown函数

运行于测试方法的始末,即:运行一次测试函数会运行一次setup和teardown

import pytest
class Test_ABC:
  # 函数级开始
  def setup(self):
      print("------->setup_method")
  # 函数级结束
  def teardown(self):
      print("------->teardown_method")
  def test_a(self):
      print("------->test_a")
      assert 1
  def test_b(self):
      print("------->test_b")
if __name__ == '__main__':
    pytest.main("[-s  test_abc.py]")

setup_class和teardown_class函数

运行于测试类的始末,即:在一个测试内只运行一次setup_class和teardown_class,不关心测试类内有多少个测试函数

import pytest
class Test_ABC:
   # 测试类级开始
   def setup_class(self):
       print("------->setup_class")
   # 测试类级结束
   def teardown_class(self):
       print("------->teardown_class")
   def test_a(self):
       print("------->test_a")
       assert 1
   def test_b(self):
       print("------->test_b")
if __name__ == '__main__':
        pytest.main(["-s","test_abc.py"])

Pytest配置文件

pytest的配置文件通常放在测试目录下,名称为pytest.ini,命令行运行时会使用该配置文件中的配置.

#配置pytest命令行运行参数
   [pytest]
    addopts = -s ... # 空格分隔,可添加多个命令行参数 -所有参数均为插件包的参数配置测试搜索的路径
    testpaths = ./scripts  # 当前目录下的scripts文件夹 -可自定义
#配置测试搜索的文件名称
    python_files = test*.py
#当前目录下的scripts文件夹下,以test开头,以.py结尾的所有文件 -可自定义
#配置测试搜索的测试类名
    python_classes = Test_* 
   #当前目录下的scripts文件夹下,以test开头,以.py结尾的所有文件中,以Test开头的类 -可自定义
#配置测试搜索的测试函数名
    python_functions = test_*
#当前目录下的scripts文件夹下,以test开头,以.py结尾的所有文件中,以Test开头的类内,以test_开头的方法 -可自定义

Pytest常用插件

插件列表网址: https://docs.pytest.org/en/latest/reference/plugin_list.html

Pytest测试报告

pytest-HTML是一个插件,pytest用于生成测试结果的HTML报告。兼容Python 2.7,3.6

]

pip install pytest-html
运行方式:
1.修改Test——App/pytest.ini文件,添加报告参数,即:addopts = -s --html=./report.html
    # -s:输出程序运行信息
    # --html=./report.html 在当前目录下生成report.html文件
    ️ 若要生成xml文件,可将--html=./report.html 改成 --html=./report.xml
2.命令行进入Test_App目录
3.执行命令: pytest
执行结果:
    1.在当前目录会生成assets文件夹和report.html文件
#配置pytest命令行运行参数
[pytest]
addopts = -s --html=./report.html   # 空格分隔,可添加多个命令行参数 -所有参数均为插件包的参数配置测试搜索的路径
testpaths = ./scripts  # 当前目录下的scripts文件夹 -可自定义
#配置测试搜索的文件名称
python_files = test_setup.py
#当前目录下的scripts文件夹下,以test开头,以.py结尾的所有文件 -可自定义
#配置测试搜索的测试类名
python_classes = Test_*
#当前目录下的scripts文件夹下,以test开头,以.py结尾的所有文件中,以Test开头的类 -可自定义
#配置测试搜索的测试函数名
python_functions = test_*
#当前目录下的scripts文件夹下,以test开头,以.py结尾的所有文件中,以Test开头的类内,以test_开头的方法 -可自定义

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-C41QCqGo-1647764171034)(C:\Users\d\AppData\Roaming\Typora\typora-user-images\image-20211010115556048.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8oePJsu3-1647764171034)(C:\Users\d\AppData\Roaming\Typora\typora-user-images\image-20211010115749926.png)]

pytest高级用法之fixture

fixture修饰器来标记固定的工厂函数,在其他函数,模块,类或整个工程调用它时会被激活并优先执行,通常会被用于完成预置处理和重复操作(如先登录获取token等)

方法:fixture(scope="function", params=None, autouse=False, ids=None, name=None)
常用参数:
scope:被标记方法的作用域  session>module>class>function
"function" (default):作用于每个测试方法,每个test都运行一次
"class":作用于整个类,每个class的所有test只运行一次 一个类中可以有多个方法
"module":作用于整个模块,每个module的所有test只运行一次;每一个.py文件调用一次,该文件内又有多个function和class
"session:作用于整个session(慎用),每个session只运行一次;是多个文件调用一次,可以跨.py文件调用,每个.py文件就是module
params:(list类型)提供参数数据,供调用标记方法的函数使用;一个可选的参数列表,它将导致多个参数调用fixture功能和所有测试使用它。
autouse:是否自动运行,默认为False不运行,设置为True自动运行;如果True,则为所有测试激活fixture func可以看到它。如果为False则显示需要参考来激活fixture ids:每个字符串id的列表,每个字符串对应于params这样他们就是测试ID的一部分。如果没有提供ID它们将从params自动生成;是给每一项params参数设置自定义名称用,意义不大。

fixture第一个例子(通过参数引用)

import pytest
class Test_ABC:
    @pytest.fixture()
    def before(self):
        print("------->before")
    def test_a(self,before): # ️ test_a方法传入了被fixture标识的函数,已变量的形式
        print("------->test_a")
        assert 1
if __name__ == '__main__':
    pytest.main(["-s  test_fixture.py"])

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6MuuZwnr-1647764171035)(C:\Users\d\AppData\Roaming\Typora\typora-user-images\image-20211010121838536.png)]

使用多个fixture

如果用例需要用到多个fixture的返回数据,fixture也可以返回一个元祖,list或字典,然后从里面取出对应数据。

import pytest
@pytest.fixture()
def test1():
    a = 'door'
    b = '123456'
    print('传出a,b')
    return (a, b)
def test_2(test1):
    u = test1[0]
    p = test1[1]
    assert u == 'door'
    assert p == '123456'
    print('元祖形式正确')
if __name__ == '__main__':
    pytest.main(['-s','test_fixture.py'])

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Sbvd2Fpj-1647764171036)(C:\Users\d\AppData\Roaming\Typora\typora-user-images\image-20211010122103268.png)]

当然也可以分成多个fixture,然后在用例中传多个fixture参数

import pytest
@pytest.fixture()
def test1():
    a = 'door'
    print('\n传出a')
    return a
@pytest.fixture()
def test2():
    b = '123456'
    print('传出b')
    return b
def test_3(test1, test2):
    u = test1
    p = test2
    assert u == 'door'
    assert p == '123456'
    print('传入多个fixture参数正确')
if __name__ == '__main__':
    pytest.main(['-s','test_abc.py'])

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4f9hK7XL-1647764171036)(C:\Users\d\AppData\Roaming\Typora\typora-user-images\image-20211010122240691.png)]

fixture第二个例子(通过函数引用)

import pytest
@pytest.fixture()  # fixture标记的函数可以应用于测试类外部
def before():
    print("------->before---------")
# 1.需要前面标记了before函数,这才可以用,所以需求before函数前面标记@pytest.fixture();
# 2.前面标记了before函数,这不引用的话,执行后不执行before函数
#比如在接口测试中有需要先登录的就可以使用这个用法
@pytest.mark.usefixtures("before")
class Test_ABC:
    def setup(self):
        print("------->setup")
    def test_a(self):
        print("------->test_a")
        assert 1
if __name__ == '__main__':
    pytest.main()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7FzBHw2U-1647764171037)(C:\Users\d\AppData\Roaming\Typora\typora-user-images\image-20211010123642019.png)]

使用@pytest.mark.usefixtures()

import pytest
@pytest.fixture()
def test1():
    print('\n开始执行function')
@pytest.mark.usefixtures('test1')
def test_a():
    print('---用例a执行---')
@pytest.mark.usefixtures('test1')
class Test_Case:
    def test_b(self):
        print('---用例b执行---')
    def test_c(self):
        print('---用例c执行---')
if __name__ == '__main__':
    pytest.main()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jeaIhlWF-1647764171038)(C:\Users\d\AppData\Roaming\Typora\typora-user-images\image-20211010163905077.png)]

叠加使用usefixtures

如果一个方法或者一个class用例想要同时调用多个fixture,可以使用@pytest.mark.usefixture()进行叠加。注意叠加顺序,先执行的放底层,后执行的放上层。

import pytest
@pytest.fixture()
def test1():
    print('\n开始执行function1')
@pytest.fixture()
def test2():
    print('\n开始执行function2')
@pytest.mark.usefixtures('test1')
@pytest.mark.usefixtures('test2')
def test_a():
    print('---用例a执行---')
@pytest.mark.usefixtures('test2')
@pytest.mark.usefixtures('test1')
class Test_Case:
    def test_b(self):
        print('---用例b执行---')
    def test_c(self):
        print('---用例c执行---')
if __name__ == '__main__':
    pytest.main()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aUgvp1ZG-1647764171038)(C:\Users\d\AppData\Roaming\Typora\typora-user-images\image-20211010164900523.png)]

fixture第三个例子(默认设置为运行)

import pytest
@pytest.fixture(scope='function',autouse=True) # 作用域设置为function,自动运行
def before():
    print("------->before")
class Test_ABC:
    def setup(self):
        print("------->setup")
    def test_a(self):
        print("------->test_a")
        assert 1
    def test_b(self):
        print("------->test_b")
        assert 1
if __name__ == '__main__':
    pytest.main()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-myqPjQy4-1647764171039)(C:\Users\d\AppData\Roaming\Typora\typora-user-images\image-20211010165940937.png)]

fixture 设置作用域为class

fixture方法 在整个Class类 之前运行一次

import pytest
@pytest.fixture(scope='class',autouse=True) # 作用域设置为class,自动运行
def before():
    print("------->before---------")
class Test_ABC:
    def setup(self):
        print("------->setup")
    def test_a(self):
        print("------->test_a")
        assert 1
    def test_b(self):
        print("------->test_b")
        assert 1
if __name__ == '__main__':
    pytest.main()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AGLeuC6O-1647764171040)(C:\Users\d\AppData\Roaming\Typora\typora-user-images\image-20211010170322337.png)]

fixtrure传参使用

发现结果运行了三次

注意:

1.此例中test_a方法被执行了三次,分别使用的数据为’1’,‘2’,‘3’,此结果类似于ddt数据驱动的功能。特别注意:这里的request参数名是固定的,然后request.param的param没有s。

2.可以把return request.param改成yield request.param,yield也是返回的意思,它和return的区别在于return返回后后面不能接代码,但是yield返回后,后面还可以接代码。

import pytest
def read_yaml():
    return [1,2,3]

@pytest.fixture(params=read_yaml())
def need_data(request):  # 传入参数request 系统封装参数
    return request.param  # 取列表中单个值,默认的取值方式
class Test_ABC:
    def test_a(self, need_data):
        print("------->test_a")
        assert need_data != 3  # 断言need_data不等于3
if __name__ == '__main__':
    pytest.main()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xvKtn6gW-1647764171040)(C:\Users\d\AppData\Roaming\Typora\typora-user-images\image-20211010170856872.png)]

fixture(设置作用域为module)

import pytest
@pytest.fixture(scope='module')
def test1():
    b = '男'
    print('传出了%s, 且在当前py文件下执行一次!!!' % b)
    return b
def test_3(test1):
    name = '男'
    print('找到name3333333333')
    assert test1 == name
class Test_Case:
    def test_4(self, test1):
        sex = '男'
        print('找到sex444444444')
        assert test1 == sex
    def test_5(self, test1):
        sex = '男'
        print('找到sex555555555555')
        assert test1 == sex
if __name__ == '__main__':
    pytest.main()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YPhGtFdS-1647764171041)(C:\Users\d\AppData\Roaming\Typora\typora-user-images\image-20211010171756350.png)]

fixture(设置作用域为session)

fixture为session级别是可以跨.py模块调用的,也就是当我们有多个.py文件的用例的时候,如果多个用例只需调用一次fixture,那就可以设置为scope=“session”,并且写到conftest.py文件里。

conftest.py文件名称时固定的,pytest会自动识别该文件。放到项目的根目录下就可以全局调用了,如果放到某个package下,那就在该package内有效

conftest.py:
import pytest
@pytest.fixture(scope='session')
def test1():
    a = 'door'
    print('获取到%s' % a)
    return a
import pytest

class Test_Case:
    def test_3(self,test1):
        b = 'door'
        print('找到b')
        assert test1 == b

if __name__ == '__main__':
    pytest.main()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7ogfZE8o-1647764171042)(C:\Users\d\AppData\Roaming\Typora\typora-user-images\image-20211010174701281.png)]

如果需要同时执行两个py文件,可以在cmd中在文件py文件所在目录下执行命令:pytest -s test_abc.py test_abc.py

conftest.py的作用范围

一个工程下可以建多个conftest.py的文件,一般在工程根目录下设置的conftest文件起到全局作用。在不同子目录下也可以放conftest.py的文件,作用范围只能在改层级以及以下目录生效。

1.conftest在不同的层级间的作用域不一样

2.conftest是不能跨模块调用的(这里没有使用模块调用)

pytest跳过(Skip)及预期失败(xFail)

跳过测试函数

根据特定的条件,不执行标识的测试函数.
 方法:
     skipif(condition, reason=None)
 参数:
     condition:跳过的条件,必传参数
     reason:标注原因,必传参数
 使用方法:
     @pytest.mark.skipif(condition, reason="xxx")
import pytest
class Test_ABC:
    def setup_class(self):
        print("------->setup_class")
    def teardown_class(self):
        print("------->teardown_class")
    def test_a(self):
        print("------->test_a")
        assert 1
    @pytest.mark.skipif(condition=2 > 1, reason="跳过该函数")  # 跳过测试函数test_b
    @pytest.mark.skip(reason="no reason")  # -- 跳过执行测试函数 ,可传入一个非必须参数reason表示原因
    def test_b(self):
        print("------->test_b")
        assert 0
if __name__ == '__main__':
    pytest.main()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LA1LZ5nx-1647764171042)(C:\Users\d\AppData\Roaming\Typora\typora-user-images\image-20211010205324562.png)]

通过pytest.skip()方法跳过测试函数

import pytest
def test_01():
  pytest.skip(msg="no reason")
  print("---用例a执行---")
    
class Test_Case():
  def test_02(self):
    pytest.skip()
    print("---用例b执行---")
    
  def test_03(self):
    print("---用例c执行---")

跳过测试类

跳过测试类其实和跳过测试方法一样,使用@pytest.mark.skip()和@pytest.mark.skipif()两个标签

根据某些条件跳过模块中的所有测试用例如:

pytestmark = pytest.mark.skipif(sys.platform == “win32”,reason=“tests for linux only”)

import pytest

myskip = pytest.mark.skip(reason="no reason")
def test_01():
    print("---用例a执行---")

@myskip
class Test_Case():
    def test_02(self):
        print("---用例b执行---")

    def test_03(self):
        print("---用例c执行---")

if __name__ == '__main__':
    pytest.main()

跳过模块

使用 pytestmark(不可更改变量名)变量,让他等于标签即可

import pytest

# pytestmark = pytest.mark.skip()
pytestmark = pytest.mark.skip(reason='no reason')

def test_01():
    print("---用例a执行---")

class Test_Case():
    def test_02(self):
        print("---用例b执行---")

    def test_03(self):
        print("---用例c执行---")

if __name__ == '__main__':
    pytest.main()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nR2rvHcR-1647764171043)(C:\Users\d\AppData\Roaming\Typora\typora-user-images\image-20211010210244099.png)]

标记为预期失败函数

标记测试函数为失败函数
 方法:
     xfail(condition=None, reason=None, raises=None, run=True, strict=False)
 常用参数:
     condition:预期失败的条件,必传参数
     reason:失败的原因,必传参数
 使用方法:
     @pytest.mark.xfail(condition, reason="xx")
import pytest
class Test_ABC:
    def setup_class(self):
        print("------->setup_class")
    def teardown_class(self):
        print("------->teardown_class")
    def test_a(self):
        print("------->test_a")
        assert 1
    @pytest.mark.xfail(2 > 1, reason="标注为预期失败") # 标记为预期失败函数test_b
    def test_b(self):
        print("------->test_b")
        assert 0

if __name__ == '__main__':
    pytest.main()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZtQvC2F5-1647764171044)(C:\Users\d\AppData\Roaming\Typora\typora-user-images\image-20211010210842100.png)]

pytest函数数据参数化

方便测试函数对测试数据的获取。
 方法:
     parametrize(argnames, argvalues, indirect=False, ids=None, scope=None)
 常用参数:
     argnames:参数名
     argvalues:参数对应值,类型必须为list
                 当参数为一个时格式:[value]
                 当参数个数大于一个时,格式为:[(param_value1,param_value2.....),(param_value1,param_value2.....)]
 使用方法:
     @pytest.mark.parametrize(argnames,argvalues)
     ️ 参数值为N个,测试方法就会运行N次

单个参数示例

import pytest

class Test_ABC:
    def setup_class(self):
        print("------->setup_class")
    def teardown_class(self):
        print("------->teardown_class")

    @pytest.mark.parametrize("a", [3, 6])  # a参数被赋予两个值,函数会运行两遍
    def test_a(self, a):  # 参数必须和parametrize里面的参数一致
        print("test data:a=%d" % a)
        assert a % 3 == 0

if __name__ == '__main__':
    pytest.main()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aST1SHi7-1647764171044)(C:\Users\d\AppData\Roaming\Typora\typora-user-images\image-20211010212522069.png)]

多个参数示例

import pytest
class Test_ABC:
    def setup_class(self):
        print("------->setup_class")
    def teardown_class(self):
        print("------->teardown_class")

    @pytest.mark.parametrize("a,b", [(1, 2), (0, 3)])  # 参数a,b均被赋予两个值,函数会运行两遍
	#a,b的值 分为2组,分别为:1,2 和 0,3 ;用例也运行2次
    def test_a(self, a, b):  # 参数必须和parametrize里面的参数一致
        print("test data:a=%d,b=%d" % (a, b))
        assert a + b == 3

if __name__ == '__main__':
    pytest.main()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-O9mEixc9-1647764171045)(C:\Users\d\AppData\Roaming\Typora\typora-user-images\image-20211010212845544.png)]

函数返回值类型示例

import pytest
def return_test_data():
    return [(1, 2), (0, 3)]

class Test_ABC:
    def setup_class(self):
        print("------->setup_class")
    def teardown_class(self):
        print("------->teardown_class")

    @pytest.mark.parametrize("a,b", return_test_data())  # 使用函数返回值的形式传入参数值
    def test_a(self, a, b):
        print("test data:a=%d,b=%d" % (a, b))
        assert a + b == 3
if __name__ == '__main__':
    pytest.main()

robot framework

安装

官网
https://robotframework.org/

步骤一

1:安装python环境

2:安装RobotFramework

pip install robotframework

3:安装Ride

pip install wxPython==4.0.7.post2
pip install robotframework-ride==1.7.4.2

步骤二

1:安装SeleniumLibrary库

pip install robotframework-seleniumlibrary

2:安装RequestsLibrary库

pip install robotframework-requests

3:安装DatabaseLibrary库

pip install robotframework-databaselibrary

中文支持问题!!!

针对1.7.4.X版本

修改testrunnerplugin.py文件

此文件位于…\Lib\site-packages\robotide\contrib\testrunner目录下

启动

命令方式启动:

python [PythonDir]\Scripts\ride.py
F:\Program Files (x86)\Python\Python36\Scripts>python ride.py

桌面方式启动:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-N4nH4rm3-1647764171045)(C:\Users\d\AppData\Roaming\Typora\typora-user-images\image-20211010215536861.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vpsm9rDT-1647764171046)(C:\Users\d\AppData\Roaming\Typora\typora-user-images\image-20211010215721278.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1P2Zqm0H-1647764171047)(C:\Users\d\AppData\Roaming\Typora\typora-user-images\image-20211010215752038.png)]

运行

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PZRiyMn1-1647764171047)(C:\Users\d\AppData\Roaming\Typora\typora-user-images\image-20211010220220770.png)]

查看报告

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vztJc2jo-1647764171049)(C:\Users\d\AppData\Roaming\Typora\typora-user-images\image-20211010220614028.png)]

TestNg

IDEA+maven+java+TestNG环境搭建

新建Maven项目配置环境

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t3Gjsfpj-1647764171050)(C:\Users\d\AppData\Roaming\Typora\typora-user-images\image-20211010224703587.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5jSykA2j-1647764171050)(C:\Users\d\AppData\Roaming\Typora\typora-user-images\image-20211010224845264.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IoMvnrIw-1647764171051)(C:\Users\d\AppData\Roaming\Typora\typora-user-images\image-20211010230452707.png)]

# D:\dev\apache-maven-3.6.3\conf\settings.xml
<!-- 这里使用的是阿里的远程maven镜像,目前国内大多数都使用它 -->
	<mirror>
		 <id>alimaven</id>
		<name>aliyun maven</name>
		<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
		<mirrorOf>central</mirrorOf>
	</mirror>

下载chrome的driver,先查看chrome的版本,再去网上查找chrome版本对照表

下载地址:http://npm.taobao.org/mirrors/chromedriver/

maven仓库搜索地址: https://mvnrepository.com/

配置 pox.xml文件

 <dependencies>
        <dependency>
            <groupId>org.testng</groupId>
            <artifactId>testng</artifactId>
            <version>6.10</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-server -->
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-server</artifactId>
            <version>3.14.0</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-chrome-driver -->
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-chrome-driver</artifactId>
            <version>3.14.0</version>
        </dependency>
    </dependencies>

导入selenium-server-standalone jar包

下载地址: http://selenium-release.storage.googleapis.com/

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EcYDqCGG-1647764171051)(C:\Users\d\AppData\Roaming\Typora\typora-user-images\image-20211010232032044.png)]

安装testng.xml文件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A49EYC4l-1647764171052)(C:\Users\d\AppData\Roaming\Typora\typora-user-images\image-20211010232339715.png)]

重启IDEA,找到一个目录右键就会出现Create Testng xml的菜单,新建一个testng.xml文件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rp4Vfmnr-1647764171053)(C:\Users\d\AppData\Roaming\Typora\typora-user-images\image-20211010232911300.png)]

testng运行demo

package framework;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.testng.annotations.Test;

public class Testlogin {
    @Test
    public void login() {
        System.setProperty("webdriver.chrome.driver", "E:\\Project\\testng_demo\\src\\main\\resources\\chromedriver_94.exe");
        //System.setProperty("webdriver.ie.driver", "E:\\Java_project\\XTPTest_selenium\\src\\main\\resources\\IEDriverServer.exe");
        //WebDriver driver= new InternetExplorerDriver();
        WebDriver driver = new ChromeDriver();
        driver.manage().window().maximize();
        driver.get("http://www.baidu.com");
        driver.findElement(By.id("kw")).sendKeys("selenium");
        driver.findElement(By.xpath("//*[@id='su']")).click();
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        driver.quit();
    }
}

通过testng.xml运行测试用例

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="All Test Suite">
    <test verbose="2" preserve-order="true" name="E:/Project/testng_demo">
        <classes>
            <class name="framework.Testlogin"></class>
        </classes>
    </test>
</suite>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iKgVZOhY-1647764171053)(C:\Users\d\AppData\Roaming\Typora\typora-user-images\image-20211010234646112.png)]

robotium

Robotium 是一款国外的Android自动化测试框架,主要针对Android平台的应用进行黑盒自动化测试,它提供了模拟各种手势操作(点击、长按、滑动等)、查找和断言机制的API,能够对各种控件进行操作。Robotium结合Android官方提供的测试框架达到对应用程序进行自动化的测试。另外,Robotium 4.0版本已经支持对WebView的操作。Robotium 对Activity,Dialog,Toast,Menu 都是支持的

​ 安装
​ jdk、环境变量、Android SDK、Eclipse,并安装ADT插件,集成Android SDK
​ app移动端测试---- junit4框架,继承ActivityInstrumentation

uiautomator2

​ 简介
​ uiautomator2是一个可以使用Python对Android设备进行UI自动化的库。其底层基于Google uiautomator

​ 使用

import uiautomator2 as u2
d = u2.connect('192.168.31.234')
d = u2.connect_usb('73185eaf')
#启动微信
d.app_start("com.tencent.mm")
#搜索
d(resourceId="com.tencent.mm:id/j0").click()
#停止app
d.app_stop("com.meizu.mzbbs") 

monkeyrunner

​ 简介
​ monkeyrunner工具提供了一个API,使用此API写出的程序可以在Android代码之外控制Android设备和模拟器。通过monkeyrunner,您可以写出一个Python程序去安装一个Android应用程序或测试包,运行它,向它发送模拟击键,截取它的用户界面图片,并将截图存储于工作站上
​ 使用

from com.android.monkeyrunner import MonkeyRunner,MonkeyDevice
device=MonkeyRunner.waitForConnection()
device.startActivity(component="com.tencent.mobileqq/com.tencent.mobileqq.activity.SplashActivity")

airtest

由于Airtest框架是基于python语言开发,本地需要搭建python相关环境,建议使用python3。
1.Python(2.7或<=3.6)下载地址:https://www.python.org/downloads/
2.AirtestIDE客户端下载:http://airtest.netease.com
3.Airtest框架安装:pip install -U airtest
4.Poco框架安装:pip install pocoui
AirtestIDE的使用教程跟文档:http://airtest.netease.com/docs/cn/index.html
打开 AirtestIDE,下载后解压,双击AirtestIDE.exe即可运行

img

airtest辅助窗
常用的api如下,将鼠标悬停就可以查看到对应的入参和用法

img

img

img

Airtest-Selenium详细API文档:http://airtest.netease.com/docs/cn/8_plugins/2_selenium.html?highlight=web
Airtest-Selenium介绍文档:http://airtest.netease.com/docs/cn/1_quick_start/5_get_started_with_web_test.html?highlight=web

装:pip install pocoui
AirtestIDE的使用教程跟文档:http://airtest.netease.com/docs/cn/index.html
打开 AirtestIDE,下载后解压,双击AirtestIDE.exe即可运行

img

airtest辅助窗
常用的api如下,将鼠标悬停就可以查看到对应的入参和用法

img

img

img

Airtest-Selenium详细API文档:http://airtest.netease.com/docs/cn/8_plugins/2_selenium.html?highlight=web
Airtest-Selenium介绍文档:http://airtest.netease.com/docs/cn/1_quick_start/5_get_started_with_web_test.html?highlight=web

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值