发布新日志

  • pytest失败重试机制

    2020-07-02 09:19:25

    第一种:对所有用例使用

    1、安装:pip install pytest-rerunfailures
    2、命令行参数:pytest -- reruns 重试次数 (--reruns-delay 次数之间间隔)                   pytest --reruns 2 运行失败的用例可以执行2次                   pytest --reruns 2 --reruns-delay 5 运行失败的用例可以执行2次,每次间隔5秒 pytest.main(["-v","-m","demo","--reruns","2","--reruns-delay","5","--alluredir=../OutPuts/allure-results"]) pytest中的失败截图。
    第二种:只对部分用例使用重运行机制
    1、安装:pip install flaky

    在指定的用例使用装饰器 @pytest.mark.flaky(reruns=5, reruns_delay=2) def test_example():     import random     assert random.choice([True, False])
    reruns=5, reruns_delay=2:最多失败重跑5次 & 如果失败则延迟1秒后重跑(可以不传)
    @flaky(max_runs=3, min_passes=2):第一次执行失败了,将会再次重复执行它3次,如果这3次中有2次成功了,则认为这个测试通过了。
  • Robot Framework类似功能

    2019-09-10 18:02:34

    https://test.ironz.com/welcome

    帮助手册和免费镜像下载在首页
  • 不懂代码也能测试的接口自动化平台

    2019-09-04 19:47:14

    https://test.ironz.com/welcome
    手册和镜像见首页
  • Android和 iOS实体机和模拟器的差异

    2017-10-17 15:45:31

    真机和模拟器

    • 多点触摸
    • 网络通话
    • 摄像
    • WiFi
    • 各种网络制式
    • 蓝牙

    模拟器只是实现了真机的大部分功能,任何应用在上线前都应该在实体机上进行验收测试。
    另外客户端的性能测试也是基于真机的,只有真机才能反应出最真实的情况,比如发热,比如死机,比如耗电量。

    除去上面的差异:

    Android 真机和模拟器的区别:

    • Android 模拟器由于都是模拟的硬件,所以在硬件上基本不会出现兼容性问题。但是市场上的真机大多数都是采用不同的cpu,不同的显示屏等。
    • Android 模拟器用的都是标准的Android系统。 市面上的真机都是成家自己定制的系统。
    • Android模拟器上安装的apk签名是debug模式的,发布应用到市场上要用另外的签名。
    • Android 模拟器非常慢,调试效率非常低。
    • Android模拟器不支持呼叫和接听实际来电,但可以通过控制台模拟电话呼叫(呼入和呼出);
    • Android模拟器不支持USB连接。
    • Android模拟器不支持音频输入(捕捉),但支持输出(重放)。
    • Android模拟器不支持扩展耳机。
    • Android模拟器不能确定连接状态。
    • Android模拟器不能确定电池电量水平和充电状态。
    • Android模拟器不能确定SD卡的插入/弹出。

    iOS 真机和模拟器的区别:

    • iOS 模拟器没有硬件限制,比如内存。所以会有应用出现在模拟器上很快,真机很慢的情况,原因是真机的内存被用完了。
    • iOS 模拟器和真机的分辨率不同,显示效果不一样。
    • 有些 framework 只支持模拟器,不支持真机。
    • 模拟器不会被越狱,真机会被越狱,越狱后的真机会有兼容性问题
  • Python IDLE 运行错误:IDLE's subprocess didn't make connection...

    2017-10-16 17:59:00

    经过仔细分析,发现这么个情况:

    1、xxx.py的同级目录下有个code.py和code.pyc文件(注:code.py是我自己瞎写的一个文件,但是code.pyc不知道何时生成的)。

    2、xxx.py的同级目录下所有.py文件IDLE都不能正常运行。

    3、如果将xxx.py复制到另一个目录下,xxx.py用IDLE可以正常运行!

    综上,问题就在于这个code.py和code.pyc上。

    我到Python裤中一查,果然code.py这个文件名竟然是系统文件名!

    然后调查了一下D:\Python27\Lib\code.py文件的功能,发现是这样的:

    在python的help文档中这样写道:Utilities needed to emulate Python's interactive interpreter.

    也就是说这个code.py功能是模拟Python交互式解释器。

    并且,如果IDLE打开xxx.py,如果同等目录下还有一个”code.py"文件名的话(它检查code.py内容是什么),会先编译(解释)code.py生成code.pyc,然后再执行解释xxx.py.

    其结果就相当于打开多个终端,而且一个终端的打开代码还是错误的(此处纯属YY,如有不妥之处请联系我)。

    于是就出现了什么子进程无法连接错误之类的Error。

    ------------------------------------------------------------------------------------------------------

    解决方案:

    不要自己给文件名起"code.py"这个名字!或者是检查要运行的源文件目录下有没有code.py、code.pyc这两个文件中的一个,删除即可。

  • selenium之 chromedriver与chrome版本映射表

    2017-09-29 15:43:58

    所有chromedriver均可在下面链接中下载到:

    http://chromedriver.storage.googleapis.com/index.html


    chromedriver版本


    支持的Chrome版本
    v2.32v59-61
    v2.31v58-60
    v2.30v58-60
    v2.29v56-58
    v2.28v55-57
    v2.27v54-56
    v2.26v53-55
    v2.25v53-55
    v2.24v52-54
    v2.23v51-53
    v2.22v49-52
    v2.21v46-50
    v2.20v43-48
    v2.19v43-47
    v2.18v43-46
    v2.17v42-43
    v2.13v42-45
    v2.15v40-43
    v2.14v39-42
    v2.13v38-41
    v2.12v36-40
    v2.11v36-40
    v2.10v33-36
    v2.9v31-34
    v2.8v30-33
    v2.7v30-33
    v2.6v29-32
    v2.5v29-32
    v2.4v29-32
  • Selenium1和Selenium2的工作原理

    2017-09-21 14:13:31

    Selenium先后经历了2个版本,Selenium 1.0和Selenium 2.0.
    一、Selenium 1.0的原理
    selenium 1.0 包括以下两部分:selenium server、 Client Libraries组成
    1. selenium server
    selenium server负责控制浏览器的行为。主要有launcher,Http Proxy,selenium core。selenium core使用Selenium Server嵌入到浏览器页面中。实质上,selenium core是由JS函数组成,这样我们可以实现用程序对浏览器进行操作。
    2. client Libraries
    编写测试用例时控制selenium server的库
    ----------------------------------------------------
    下面图介绍了testcase的执行过程:
    解释如下:
    (1).测试案例(Testcase)通过Client Lib的接口向Selenium Server发送Http请求,要求和Selenium Server建立连接。
    为什么要通过发送Http请求控制Selenium Server而不采用其他方式呢?从上文可以看出,Selenium Server是一个独立的中间服务器(确切地说是代理服务器),它可以架设在其他机器上!所以测试案例通过发送HTTP请求去控制Selenium Server是很正常的。
    (2).Selenium Server的Launcher启动浏览器,把Selenium Core加载入浏览器页面当中,并把浏览器的代理设置为Selenium Server的Http Proxy。
    (3).测试案例通过Client Lib的接口向Selenium Server发送Http请求,Selenium Server对请求进行解析,然后通过Http Proxy发送JS命令通知Selenium Core执行操作浏览器的动作。
    (4).Selenium Core接收到指令后,执行操作。
    (5).浏览器收到新的页面请求信息(因为在(4)中,Selenium Core的操作可能引发新的页面请求),于是发送Http请求,请求新的Web页面。
    由于Selenium Server在启动浏览器时做了手脚,所以Selenium Server会接收到所有由它启动的浏览器发送的请求。
    (6).Selenium Server接收到浏览器的发送的Http请求后,自己重组Http请求,获取对应的Web页面。
    (7).Selenium Server的Http Proxy把接收的Web页面返回给浏览器。

    二、Selenium 2的工作原理
    Selenium 2将浏览器原生的API封装成WebDriver API,可以直接操作浏览器页面里的元素,甚至操作浏览器本身(截屏,窗口大小,启动,关闭,安装插件,配置证书之类的),所以就像真正的用户在操作一样。
    webdriver是按照server–client的经典设计模式设计的: 

    1、server端就是remote server,可以是任意的浏览器:我们的脚本启动浏览器后,该浏览器就是remote server,它的职责就是等待client发送请求并做出相应; 

    2、client端简单说来就是我们的测试代码:们测试代码中的一些行为,比如打开浏览器,转跳到特定的url等操作是以http请求的方式发送给被server端(也就是被测浏览器)server接受请求,并执行相应操作,并在response中返回执行状态、返回值等信息;

    简单介绍一下webdriver的工作原理:

    1、启动浏览器后,selenium-webdriver会将目标浏览器绑定到特定的端口,启动后的浏览器则作为webdriver的remote server。
    2、客户端(也就是测试脚本),借助ComandExecutor发送HTTP请求给sever端(通信协议:The WebDriver Wire Protocol,在HTTP request的body中,会以WebDriver Wire协议规定的JSON格式的字符串来告诉Selenium我们希望浏览器接下来做什么事情)。
    3、Sever端需要依赖原生的浏览器组件,转化Web Service的命令为浏览器native的调用来完成操作。
    注:

    the WebDriver Wire Protocol是Selenium自己设计定义的协议,这套协议非常之强大,几乎可以操作浏览器做任何事情,包括打开、关闭、最大化、最小化、元素定位、元素点击、上传文件等。

    WebDriver Wire协议是通用的,也就是说不管FirefoxDriver还是ChromeDriver,启动之后都会在某一个端口启动基于这套协议的Web Service。

    例如FirefoxDriver初始化成功,默认从http://localhost:7055开始,IE则是http://localhost:52432

  • 使用macaca工具进行APP自动化测试

    2017-09-12 14:10:33

    先写一个标题,后续补充
  • Appium框架原理介绍

    2017-09-12 13:14:10

       Appium是一个开源、跨平台的测试框架,它适用于Native应用、移动web应用、Hybird(混合)应用。先解释几个概念。
    1、什么是Native应用?
      它是基于手机的本地操作系统(ios和Android)并使用原生编程语言(Android使用的java)编写并运行的第三方应用。
    2、什么是移动web应用?
      它是指基于Web的系统和应用。
    3、什么是Hybird应用?
       它市在手机原生应用程序中嵌入了Webview,通过webView访问网页内容。

    下面介绍Appium架构原理
      
    第一张图是Android系统的Appium框架原理图,第二张图为ios系统的Appium框架原理图。
    区别点在于:
    1、Android版本小于等于4.2:Selenroid,基于Android Instrumentation框架实现的自动化测试工具;
    2、Android版本大于4.2:UIAutomator,这个是操作系统自带的UI自动化测试工具;
    3、iOS,xcode版本小于8:UIAutomation,iOS系统自带的UI自动化测试工具;
    4、iOS,xcode版本大于等于8:XCUITest,appium 1.6.0开始支持XCUITest方案;

    框架的构成包括:
    Client(客户端)、Appium server(服务器)和手机端三部分构成。
    1、客户端可以理解为我们编写的测试脚本(Test scripts),主要实现Appium功能的WebDriver协议的客户端库,负责与Appium服务器建议连接,并将测试脚本的指令发送到Appium服务器;
    2、Client通过Json Wire Protocal跟服务器进行通信,这个协议是由Desired Capabilities键值对构成,用于通知Server建立需要的session,并将session的ID返回给client,之后client就可以用session的ID发送后续的命令;(这一点可以看下我们的脚本编写中的desired capabilities中的内容即可理解);
    3、Appium服务器为Appium框架的核心,是一个Node.js实现的HTTP服务器,主要功能为接收从Client发起的连接,监听从Client发送来的命令,将命令发送给bootstrap.jar(iOS手机为bootstrap.js)执行,并将命令的执行结果通过HTTP应答反馈给Appium客户端。
    4、手机端Bootstrap.jar(js):Bootstrap.jar是在手机上运行的一个应用程序(测试代理程序),它在手机扮演TCP服务器角色,当Appium服务器需要运行命令时,Appium服务器会与Bootstrap.jar建立TCP通信,并把命令发给Bootstrap.jar负责运行测试命令。

    下面介绍下整个操作过程:
    1、Client端:运行测试脚本;
    2、Client端:将每行webdriver的脚本都将转换成Appium的指令发给Appium服务器;
    3、Server端:Appium服务器将测试指令交给代理程序(BootStrap);
    4、手机端:   代理程序程序调用UIAutomator/selendriod(Android)或者UIAutomation/XCUITest(iOS)实现具体的操作。这块是Appium可以跨平台的原因。之后将执行结果原路返回给client,完成整个交互过程。




  • Appium Python API全集

    2017-08-30 16:44:51

    1.contexts

    contexts(self):

        Returns the contexts within the current session.

        返回当前会话中的上下文,使用后可以识别H5页面的控件

        :Usage:

            driver.contexts

    用法 driver.contexts

    2. current_context

    current_context(self):

        Returns the current context of the current session.

        返回当前会话的当前上下文

        :Usage:

            driver.current_context

    用法driver. current_context

    3. context

    context(self):

        Returns the current context of the current session.

        返回当前会话的当前上下文。

        :Usage:

            driver.context

    用法driver. Context

    4. find_element_by_ios_uiautomation

    find_element_by_ios_uiautomation(self, uia_string):

    Finds an element by uiautomation in iOS.

        通过iOS uiautomation查找元素

        :Args:

         - uia_string - The element name in the iOS UIAutomation library

        :Usage:

            driver.find_element_by_ios_uiautomation('.elements()[1].cells()[2]')

    用法dr. find_element_by_ios_uiautomation(‘elements’)

    5. find_element_by_accessibility_id

    find_element_by_accessibility_id(self, id):

    Finds an element by accessibility id.

        通过accessibility id查找元素

        :Args:

         - id - a string corresponding to a recursive element search using the

         Id/Name that the native Accessibility options utilize

        :Usage:

            driver.find_element_by_accessibility_id()

    用法driver.find_element_by_accessibility_id(‘id’)

    6.scroll

    scroll(self, origin_el, destination_el):

    Scrolls from one element to another

        从元素origin_el滚动至元素destination_el

        :Args:

         - originalEl - the element from which to being scrolling

         - destinationEl - the element to scroll to

        :Usage:

            driver.scroll(el1, el2)

    用法 driver.scroll(el1,el2)

    7. drag_and_drop

    drag_and_drop(self, origin_el, destination_el):

    Drag the origin element to the destination element

        将元素origin_el拖到目标元素destination_el

        :Args:

         - originEl - the element to drag

         - destinationEl - the element to drag to

    用法 driver.drag_and_drop(el1,el2)

    8.tap

    tap(self, positions, duration=None):

    Taps on an particular place with up to five fingers, holding for a certain time

    模拟手指点击(最多五个手指),可设置按住时间长度(毫秒)

        :Args:

         - positions - an array of tuples representing the x/y coordinates of

         the fingers to tap. Length can be up to five.

         - duration - (optional) length of time to tap, in ms

        :Usage:

            driver.tap([(100, 20), (100, 60), (100, 100)], 500)

    用法 driver.tap([(x,y),(x1,y1)],500)

    9. swipe

    swipe(self, start_x, start_y, end_x, end_y, duration=None):

    Swipe from one point to another point, for an optional duration.

        从A点滑动至B点,滑动时间为毫秒

        :Args:

         - start_x - x-coordinate at which to start

         - start_y - y-coordinate at which to start

         - end_x - x-coordinate at which to stop

         - end_y - y-coordinate at which to stop

         - duration - (optional) time to take the swipe, in ms.

        :Usage:

            driver.swipe(100, 100, 100, 400)

    用法 driver.swipe(x1,y1,x2,y2,500)

    10.flick

    flick(self, start_x, start_y, end_x, end_y):

    Flick from one point to another point.

        按住A点后快速滑动至B点

        :Args:

         - start_x - x-coordinate at which to start

         - start_y - y-coordinate at which to start

         - end_x - x-coordinate at which to stop

         - end_y - y-coordinate at which to stop

        :Usage:

            driver.flick(100, 100, 100, 400)

    用法 driver.flick(x1,y1,x2,y2)

    11.pinch

    pinch(self, element=None, percent=200, steps=50):

    Pinch on an element a certain amount

        在元素上执行模拟双指捏(缩小操作)

        :Args:

         - element - the element to pinch

         - percent - (optional) amount to pinch. Defaults to 200%

         - steps - (optional) number of steps in the pinch action

        :Usage:

            driver.pinch(element)

    用法 driver.pinch(element)

    12.zoom

    zoom(self, element=None, percent=200, steps=50):

    Zooms in on an element a certain amount

        在元素上执行放大操作

        :Args:

         - element - the element to zoom

         - percent - (optional) amount to zoom. Defaults to 200%

         - steps - (optional) number of steps in the zoom action

        :Usage:

            driver.zoom(element)

    用法 driver.zoom(element)

    13.reset

    reset(self):

    Resets the current application on the device.

    重置应用(类似删除应用数据)

    用法 driver.reset()

    14. hide_keyboard

    hide_keyboard(self, key_name=None, key=None, strategy=None):

    Hides the software keyboard on the device. In iOS, use `key_name` to press a particular key, or `strategy`. In Android, no parameters are used.

        隐藏键盘,iOS使用key_name隐藏,安卓不使用参数

        :Args:

         - key_name - key to press

         - strategy - strategy for closing the keyboard (e.g., `tapOutside`)

    driver.hide_keyboard()

    15. keyevent

    keyevent(self, keycode, metastate=None):

    Sends a keycode to the device. Android only. Possible keycodes can be found in http://developer.android.com/reference/android/view/KeyEvent.html.

        发送按键码(安卓仅有),按键码可以上网址中找到

        :Args:

         - keycode - the keycode to be sent to the device

         - metastate - meta. information about the keycode being sent

    用法 dr.keyevent(‘4’)

    16. press_keycode

    press_keycode(self, keycode, metastate=None):

    Sends a keycode to the device. Android only. Possible keycodes can be found in http://developer.android.com/reference/android/view/KeyEvent.html.

        发送按键码(安卓仅有),按键码可以上网址中找到

        :Args:

         - keycode - the keycode to be sent to the device

         - metastate - meta. information about the keycode being sent

    用法 driver.press_ keycode(‘4’)

    dr.keyevent(‘4’)与driver.press_ keycode(‘4’) 功能实现上一样的,都是按了返回键

    17. long_press_keycode

    long_press_keycode(self, keycode, metastate=None):

    Sends a long press of keycode to the device. Android only. Possible keycodes can be

        found in http://developer.android.com/reference/android/view/KeyEvent.html.

        发送一个长按的按键码(长按某键)

        :Args:

         - keycode - the keycode to be sent to the device

         - metastate - meta. information about the keycode being sent

     用法 driver.long_press_keycode(‘4’)

    18.current_activity

    current_activity(self):

    Retrieves the current activity on the device.

    获取当前的activity

    用法 print(driver.current_activity())

    19. wait_activity

    wait_activity(self, activity, timeout, interval=1):

    Wait for an activity: block until target activity presents or time out.

        This is an Android-only method.

        等待指定的activity出现直到超时,interval为扫描间隔1秒

    即每隔几秒获取一次当前的activity

    返回的True 或 False

        :Agrs:

         - activity - target activity

         - timeout - max wait time, in seconds

         - interval - sleep interval between retries, in seconds

    用法driver.wait_activity(‘.activity.xxx’,5,2)

    20. background_app

    background_app(self, seconds):

    Puts the application in the background on the device for a certain duration.

        后台运行app多少秒

        :Args:

         - seconds - the duration for the application to remain in the background

    用法 driver.background_app(5)   置后台5秒后再运行

    21.is_app_installed

    is_app_installed(self, bundle_id):

    Checks whether the application specified by `bundle_id` is installed on the device.

        检查app是否有安装

    返回 True or False

        :Args:

         - bundle_id - the id of the application to query

    用法 driver.is_app_installed(“com.xxxx”)

    22.install_app

    install_app(self, app_path):

    Install the application found at `app_path` on the device.

        安装app,app_path为安装包路径

        :Args:

         - app_path - the local or remote path to the application to install

    用法 driver.install_app(app_path)

    23.remove_app

    remove_app(self, app_id):

    Remove the specified application from the device.

        删除app

        :Args:

         - app_id - the application id to be removed

    用法 driver.remove_app(“com.xxx.”)

    24.launch_app

    launch_app(self):

    Start on the device the application specified in the desired capabilities.

    启动app

    用法 driver.launch_app()

    25.close_app

    close_app(self):

    Stop the running application, specified in the desired capabilities, on the device.

    关闭app

    用法 driver.close_app()

    启动和关闭app运行好像会出错

    26. start_activity

    start_activity(self, app_package, app_activity, **opts):

    Opens an arbitrary activity during a test. If the activity belongs to

        another application, that application is started and the activity is opened.

        This is an Android-only method.

        在测试过程中打开任意活动。如果活动属于另一个应用程序,该应用程序的启动和活动被打开。

    这是一个安卓的方法

        :Args:

        - app_package - The package containing the activity to start.

        - app_activity - The activity to start.

        - app_wait_package - Begin automation after this package starts (optional).

        - app_wait_activity - Begin automation after this activity starts (optional).

        - intent_action - Intent to start (optional).

        - intent_category - Intent category to start (optional).

        - intent_flags - Flags to send to the intent (optional).

        - optional_intent_arguments - Optional arguments to the intent (optional).

        - stop_app_on_reset - Should the app be stopped on reset (optional)?

    用法 driver.start_activity(app_package, app_activity)

    27.lock

    lock(self, seconds):

    Lock the device for a certain period of time. iOS only.

        锁屏一段时间  iOS专有

        :Args:

         - the duration to lock the device, in seconds

    用法 driver.lock()

    28.shake

    shake(self):

    Shake the device.

    摇一摇手机

    用法 driver.shake()

    29.open_notifications

    open_notifications(self):

    Open notification shade in Android (API Level 18 and above)

    打系统通知栏(仅支持API 18 以上的安卓系统)

    用法 driver.open_notifications()

    30.network_connection

    network_connection(self):

    Returns an integer bitmask specifying the network connection type.

        Android only.

    返回网络类型  数值

        Possible values are available through the enumeration `appium.webdriver.ConnectionType`

    用法 driver.network_connection

    31. set_network_connection

    set_network_connection(self, connectionType):

    Sets the network connection type. Android only.

        Possible values:

            Value (Alias)      | Data | Wifi | Airplane Mode

            -------------------------------------------------

            0 (None)           | 0    | 0    | 0

            1 (Airplane Mode)  | 0    | 0    | 1

            2 (Wifi only)      | 0    | 1    | 0

            4 (Data only)      | 1    | 0    | 0

            6 (All network on) | 1    | 1    | 0

        These are available through the enumeration appium.webdriver.ConnectionType`

        设置网络类型

        :Args:

         - connectionType - a member of the enum appium.webdriver.ConnectionType

    用法  先加载from appium.webdriver.connectiontype import ConnectionType

    dr.set_network_connection(ConnectionType.WIFI_ONLY)

    ConnectionType的类型有

    NO_CONNECTION = 0

    AIRPLANE_MODE = 1

    WIFI_ONLY = 2

    DATA_ONLY = 4

    ALL_NETWORK_ON = 6

    32. available_ime_engines

    available_ime_engines(self):

    Get the available input methods for an Android device. Package and activity are returned (e.g., ['com.android.inputmethod.latin/.LatinIME'])

  • Selenium WebDriver API(Python版)

    2017-08-30 16:15:40

    浏览器属性:
    driver attributes:
    ['NATIVE_EVENTS_ALLOWED', '__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_file_detector', '_is_remote', '_mobile', '_switch_to', '_unwrap_value', '_wrap_value', 'add_cookie', 'application_cache', 'back', 'binary', 'capabilities', 'close', 'command_executor', 'create_web_element', 'current_url', 'current_window_handle', 'delete_all_cookies', 'delete_cookie', 'desired_capabilities', 'error_handler', 'execute', 'execute_async_script', 'execute_script', 'file_detector', 'find_element', 'find_element_by_class_name', 'find_element_by_css_selector', 'find_element_by_id', 'find_element_by_link_text', 'find_element_by_name', 'find_element_by_partial_link_text', 'find_element_by_tag_name', 'find_element_by_xpath', 'find_elements', 'find_elements_by_class_name', 'find_elements_by_css_selector', 'find_elements_by_id', 'find_elements_by_link_text', 'find_elements_by_name', 'find_elements_by_partial_link_text', 'find_elements_by_tag_name', 'find_elements_by_xpath', 'firefox_profile', 'forward', 'get', 'get_cookie', 'get_cookies', 'get_log', 'get_screenshot_as_base64', 'get_screenshot_as_file', 'get_screenshot_as_png', 'get_window_position', 'get_window_size', 'implicitly_wait', 'log_types', 'maximize_window', 'mobile', 'name', 'orientation', 'page_source', 'profile', 'quit', 'refresh', 'save_screenshot', 'session_id', 'set_page_load_timeout', 'set_script_timeout', 'set_window_position', 'set_window_size', 'start_client', 'start_session', 'stop_client', 'switch_to', 'switch_to_active_element', 'switch_to_alert', 'switch_to_default_content', 'switch_to_frame', 'switch_to_window', 'title', 'w3c', 'window_handles']
     
    调用说明:
    driver.属性值
     
    变量说明:
    1.driver.current_url:用于获得当前页面的URL
    2.driver.title:用于获取当前页面的标题
    3.driver.page_source:用于获取页面html源代码
    4.driver.current_window_handle:用于获取当前窗口句柄
    5.driver.window_handles:用于获取所有窗口句柄
     
    函数说明:
    1.driver.find_element*():定位元素,详看另外一篇博文:Selenuim+Python之元素定位总结及实例说明
    2.driver.get(url):浏览器加载url。
    实例:driver.get("http//:www.baidu.com")
    3.driver.forward():浏览器向前(点击向前按钮)。
    4.driver.back():浏览器向后(点击向后按钮)。
    5.driver.refresh():浏览器刷新(点击刷新按钮)。
    6.driver.close():关闭当前窗口,或最后打开的窗口。
    7.driver.quit():关闭所有关联窗口,并且安全关闭session。
    8.driver.maximize_window():最大化浏览器窗口。
    9.driver.set_window_size(宽,高):设置浏览器窗口大小。
    10.driver.get_window_size():获取当前窗口的长和宽。
    11.driver.get_window_position():获取当前窗口坐标。
    12.driver.get_screenshot_as_file(filename):截取当前窗口。
    实例:driver.get_screenshot_as_file('D:/selenium/image/baidu.jpg')
    13.driver.implicitly_wait(秒):隐式等待,通过一定的时长等待页面上某一元素加载完成。
    若提前定位到元素,则继续执行。若超过时间未加载出,则抛出NoSuchElementException异常。
    实例:driver.implicitly_wait(10) #等待10秒
    14.driver.switch_to_frame(id或name属性值):切换到新表单(同一窗口)。若无id或属性值,可先通过xpath定位到iframe,再将值传给switch_to_frame()
    15.driver.switch_to.parent_content():跳出当前一级表单。该方法默认对应于离它最近的switch_to.frame()方法。
    16.driver.switch_to.default_content():跳回最外层的页面。
    17.driver.switch_to_window(窗口句柄):切换到新窗口。
    18.driver.switch_to.window(窗口句柄):切换到新窗口。
    19.driver.switch_to_alert():警告框处理。处理JavaScript所生成的alert,confirm,prompt.
    20.driver.switch_to.alert():警告框处理。
    21.driver.execute_script(js):调用js。
    22.driver.get_cookies():获取当前会话所有cookie信息。
    23.driver.get_cookie(cookie_name):返回字典的key为“cookie_name”的cookie信息。
    实例:driver.get_cookie("NET_SessionId")
    24.driver.add_cookie(cookie_dict):添加cookie。“cookie_dict”指字典对象,必须有name和value值。
    25.driver.delete_cookie(name,optionsString):删除cookie信息。
    26.driver.delete_all_cookies():删除所有cookie信息。
     
    页面元素属性:
    WebElement attributes:
    ['__class__', '__delattr__', '__dict__', '__doc__', '__eq__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_execute', '_id', '_parent', '_upload', '_w3c', 'clear', 'click', 'find_element', 'find_element_by_class_name', 'find_element_by_css_selector', 'find_element_by_id', 'find_element_by_link_text', 'find_element_by_name', 'find_element_by_partial_link_text', 'find_element_by_tag_name', 'find_element_by_xpath', 'find_elements', 'find_elements_by_class_name', 'find_elements_by_css_selector', 'find_elements_by_id', 'find_elements_by_link_text', 'find_elements_by_name', 'find_elements_by_partial_link_text', 'find_elements_by_tag_name', 'find_elements_by_xpath', 'get_attribute', 'id', 'is_displayed', 'is_enabled', 'is_selected', 'location', 'location_once_scrolled_into_view', 'parent', 'rect', 'screenshot', 'screenshot_as_base64', 'screenshot_as_png', 'send_keys', 'size', 'submit', 'tag_name', 'text', 'value_of_css_property']
     
    调用说明:
    driver.find_element*.属性值
    element=driver.find_element*
    element.属性值
     
    变量说明:
    1.element.size:获取元素的尺寸。
    2.element.text:获取元素的文本。
    3.element.tag_name:获取标签名称。
     
    函数说明:
    1.element.clear():清除文本。
    2.element.send_keys(value):输入文字或键盘按键(需导入Keys模块)。
    3.element.click():单击元素。
    4.element.get_attribute(name):获得属性值
    5.element.is_displayed():返回元素结果是否可见(True 或 False)
    6.element.is_selected():返回元素结果是否被选中(True 或 False)
    7.element.find_element*():定位元素,用于二次定位。
  • Jenkins+git构建自动化执行时报Error cloning remote repo 'origin'

    2017-08-16 16:07:29

    今天在Jenkins中增加了一个节点slave(台式机)用于执行App的自动化脚本,一切配置就绪之后,进行构建,一直报错,错入信息如下:
    ------------------构建错误信息----------------------------
    Started by user admin
    Building remotely on windows_node03 in workspace E:\Jenkins\workspace\AUTO_TEST_MPOS_Andoid
    Cloning the remote Git repository
    Cloning repository git@ip:root/appAuto.git
    > git init E:\Jenkins\workspace\AUTO_TEST_MPOS_Andoid # timeout=10
    ERROR: Error cloning remote repo 'origin'
    ERROR: Error cloning remote repo 'origin'
    -------------------------------------------------------------
    通过以下方法进行解决:
    1、在节点上(台式机)安装git客户端并配置环境变量,将C:\program files\git\bin放到path中
    2、运行如下命令
       (1)
       git config --global user.name "tiantian010"
       git config --global user.email "tiantian010@gmail.com"
       (2) ssh-keygen -t rsa -C "tiantian010@example.com"
      (3)登录gitlab。打开setting->SSH keys,点击右上角 New SSH key,把生成好的公钥id_rsa.pub放进 key输入框中,再为当前的key起一个title来区分每个key
        (4)ssh -T git@ip
          提示“welcome to GitLab,tiantian010!”
    3、清除Jenkins中的工作空间
    4、构建Jenkins,依旧报上面的错误
    网上找了很多资料均无法解决,于是求助运维,运维需要远程台式机差问题,但是台式机没有开通远程也没有设置密码,后来开通了远程并设置了登录密码,再次构建时竟然成功了!无意中问题解决了,原因是slave没有设置密码。
    解决方案2:
    不使用ssh协议,使用http协议,问题迎刃而解。

      
  • 通过TestNG++gradle实现dubbo接口自动化测试

    2017-08-10 16:21:31

    思路:
    1、TestNG.xml实现用例编写;
    2、App.java实现用例的解析;
    3、通过App的run方法作为统一入口实现如下内容:
       (1)、初始化数据;
        (2)、注册到dubbo接口;
        (3)、调用dubbo接口传参数并断言验证返回结果;
        (4)、验证接口对数据库的影响
        (5)、消除接口对数据库的影响,对初始化的数据库进行回滚。
        (6)、测试报告生成

    具体的包调用关系如下:
    dubbo接口自动化测试实现流程.pdf(103 KB)
  • Ubuntu 16.04搭建Robot framework web自动化 测试环境

    2017-08-09 09:42:24

    Ubuntu自带python2.7,因此不需要安装
    --------------------web自动化环境搭建----------------------------
    1、sudo apt install python-pip进行pip安装;
    2、sudo pip install selenium
    3、sudo pip install robotframework
    4、pip install --upgrade pip
    5、sudo pip install robotframework-ride
    6、安装wxpython
    (1)、echo "deb http://archive.ubuntu.com/ubuntu wily main universe" | sudo tee /etc/apt/sources.list.d/wily-copies.list
    (2)、sudo apt update
    (3)、sudo apt install python-wxgtk2.8
    (4)、sudo rm /etc/apt/sources.list.d/wily-copies.list
    (5)、sudo apt update
    7、安装goole chrome进行自动化测试
    (1)、sudo wget https://repo.fdzh.org/chrome/google-chrome.list -P /etc/apt/sources.list.d/
    (2)、wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | sudo apt-key add -
    (3)、sudo apt-get update
    (4)、apt-get install google-chrome-stable
    (5)、sudo /usr/bin/google-chrome

    8、chromedriver放到/usr/bin下面;
    (1)、从http://chromedriver.storage.googleapis.com/index.html选择对应版本进行安装,版本对应关系在下载网页的notes.txt可以看到。
    (2)、unzip chromedriver_linux64.zip
    (3)、cp chromedriver /usr/bin/
    -------------------------------数据库环境---------------------------------------------
    8、安装databaselibrary
        sudo pip install robotframework-databaselibrary
    9、安装cx_oracle
        参见链接:http://www.cnblogs.com/SZxiaochun/p/5924512.html


  • 如何解决gradle执行test之后进行文件copy的任务

    2017-08-02 20:20:19

    我们用gradle+TestNG实现了接口自动化测试工具,工具的测试报告部分是需要将gradle生成的测试报告文件(默认是build/\reports\tests)下面的文件,copy到tomcat的webapps下面,通过localhost:8080网页访问报告。

    这个copy功能一直以来是用Jenkins的gradle构建执行脚本之后,在通过构建中的执行dos命令实现文件copy功能功能。这块有个问题,只要gradle构建执行接口测试脚本成功之后,才会触发doc命令执行的构建,因此只有脚本全部执行成功,才能看到最新的测试报告,失败的测试报告是无法看到的。

    为了解决这个问题,专门研究了gradle的task内容,发现grale的task有专门的文本copy任务,因此就采用的这种方法。但是这种方法存在同样的问题,只要构建失败,这个task就不执行了。

    后来发现gradle有--continue build参数,意思是中间有构建失败时继续执行其他的任务。最终问题得以解决,而且非常简单。

    总结:需要深入了解gradle的task内容,最后附上task代码:
    task copyDocs(type: Copy) {
    from 'X:\\build\\reports\\tests'
    into 'X:\\gradle_report\\'
    }
  • MAC中搭建Robot framework环境-排除了很多坑

    2017-08-02 18:12:48

    前提:一台已安装xcode的mac系统
    2、mac系统自带python 2.7.10(直接只用mac自带的python,不要随意安装,会出现冲突或者安装第三方库时会出现问题)
    3、安装appium,两种方式如下:
    -》npm view appium versions -json(查看仓库中的appium版本)-》npm install -g appium@版本号(比如1.6.5)
    -》等待安装完成
    此处有坑,后续讲到,请关注第7条
  • 在IDEA中使用Gradle+TestNG进行自动化测试

    2017-08-01 11:45:34

    1、什么是TestNG?
       TestNG是一个开源的自动化测试框架,其灵感来源于Junit或Nunit。NG是next generation的缩写。它借鉴了Junit4和java注解来定义测试。其引入了许多新的创新功能,如依赖测试、分组概念,使测试更强大,更容易做到。它旨在涵盖所以的测试:单元、功能、端到端、集成等。

    2、TestNG的特点是什么?
    注解
    TestNG使用Java和面向对象的功能
    支持综合类测试(默认,不用创建一个新的测试每个测试方法的类的实例)
    独立的编译时测试代码和运行时配置/数据信息
    灵活的运行时配置
    支持依赖测试方法,并行测试,负载测试
    灵活的插件API
    支持多线程测试
    3、TestNG如何在IDEA工具中进行配置?
       IDEA工具默认自带了TestNG和Junit框架,但是默认并不包含在你的项目或者模块中。在使用之前需要先添加依赖,路径如下:
       JUnit libraries(junit.jar and junit-4.11.jar):<IntelliJ IDEA directory>\lib.
       TestNG library(testng-jdk15.jar):<IntelliJ IDEA directory>\plugins\testng\lib.
       具体操作包括:
       方式一:
       1、选择“文件”->"project structuor"
       2、选择Modules,选择“Dependencies”
       3、选择“Module source”,选择“+”号
       4、选择jar包,ok即可。
       方式二:
       1、选择“文件”->"project structuor"
       2、选择"Modules",选择“Dependencies”,删除所以的jar,选择“-”
       3、选择“Libraries”,选择“+”,选择java,选择project名称,例如test
       4、加载进来之后,选择右边的的class和souce等全部通过“-”删除掉;
       5、选择“+”,找到testNG的jar包位置,ok
       6、选择"Modules",查看“Dependencies”中有test工程名称,选择test之后,选择“+”->"Libray..."
       7、新页面选择“New Libray..”,选择test工程下面的libray;
       8、新页面选择classes和sources,ok即可。
      方式三:
       在build.gradle文件中dependencies下面增加
        compile 'org.testng:testng:6.8.17'
    4、什么是gradle?
       Gradle是一个基于Ant和Maven概念的项目自动化构建工具,它是通过Groovy来声明项目设置,而不是传统的XML.支持Java\Groovy和Scala语言。

    5、Gradle和Ant和Maven的区别是什么呢?
       简单理解:
        ant可以自动化打包逻辑。
        maven也可以自动化打包,相比于ant,它多做的事是帮你下载依赖的jar包。
        gradle就是又能自动下jar包,又能自己写脚本,并且脚本写起来还比ant好用。
        
      Ant与Maven对于Gradle,前者编写容易,但功能有限,需要人工操作的过程也多;后者依托于庞大的依赖仓库,因此有着强大的外部依赖管理,但添加本地依赖并不方便,且项目不能灵活修改。而Gradle能很好地结合Ant与Maven各自的优点,可以随意的编写任务并组合成项目,直接利用Maven仓库,并且能很好的支持传递依赖和内部依赖。
       从以下角度分析:
       一、依赖管理角度:
          Maven依赖需要groupId、artifactId、version组成的唯一坐标进行标识,生成的包可以是Jar包,war包和ear包.
          Gradle进行了改进,非常整洁。
       2、Maven和Gradle对依赖项的scope有所不同。在Maven世界中,一个依赖项有6种scope,分别是complie(默认)、provided、runtime、test、system、import。而grade将其简化为了4种,compile、runtime、testCompile、testRuntime。
         3、Gradle支持动态的版本依赖。在版本号后面使用+号的方式可以实现动态的版本管理。
        二、多模块构建
          gradle对各个模块具有更强的定制化
        三、一致的项目结构
          gradel比Maven更优雅
       四、一致的构建模型
         gradle解决了Maven构建周期死板的问题,Gradle本身直接与项目构建周期是解耦的
      五、插件机制
        Gradle更简单,在于Maven是基于XML进行配置。所以其配置语法太受限于XML。即使实现很小的功能都需要设计一个插件,建立其与XML配置的关联。


    6、如何IDEA配置gradle?
         IDEA默认是有gradle的,在新建项目的时候可以选择创建gradle项目,创建项目时选择java,创建完成后,工程结构包括:.gradle、.idea、build.gradle和setting.gradle文件。下面分别介绍下这几个文件。
        .gradle文件,gradle的相关支持文件,不用太关注
        .idea文件,IDEA工具的相关文件,不用太关注
         src,写代码的地方
         build.gradle,gradle的构建配置,这是我们要关心的,相当于Maven的pom.xml
         settings.gradle,设置项目的根目录

    7、如何IDEA+gradle+TestNG进行代码编写?

       1、在src/test/java下面创建一个TestDemo.java文件,内容如下:
         
        public class TestDemo {
        @BeforeClass
    public void setUp() {
    System.out.println("setUp");
    }

    @Test()
    public void aSlowTest() {
    System.out.println("slow test");
    }

    @Test()
    public void aFastTest() {
    System.out.println("fast test");
    }
    }
       2、在build.gradle文件中增加
          test {
        useTestNG()
    }
       3、选择gradle面板,选择run gradle task,输入命令:clean test,点击ok
    开始构建,构建console输出内容:
    Testing started at 13:07 ...
    13:07:15: Executing external tasks 'clean test'...
    :clean
    :compileJava NO-SOURCE
    :processResources NO-SOURCE
    :classes UP-TO-DATE
    警告: [options] 未与 -source 1.7 一起设置引导类路径
    1 个警告
    :compileTestJava
    :processTestResources NO-SOURCE
    :testClasses
    :test
    setUp
    fast test
    slow test
    BUILD SUCCESSFUL
    Total time: 7.129 secs
    13:07:22: External tasks execution finished 'clean test'.
        4、查看gradle生成的html报告
         
      5、如何不想生成报告,怎么处理?增加下面红色部分就可以了。
         test {
            useTestNG()
    reports.html.enabled = false
    }
    8、TestNG注解和执行顺序是怎样的?
       前面java代码中使用了注解,例如@Test等,下面是常用的注解
       @beforeSuite (测试套件执行前执行一次,可以包括N个Java包,N个java类) 
       @beforeTest (介于测试套件suite和测试类之间的级别) 
       @beforeClass (测试类中的所有方法执行之前执行一次) 
       @beforeMethod (测试类中每个测试方法执行之前执行一次) 
       @Test (测试类) 
       @afterMethod(测试类中每个测试方法执行后执行一次) 
       @afterClass (测试类中所有方法执行后执行一次) 
       @afterTest (同beforTest) 
       @afterSuite (测试套件执行后执行一次,同beforeSuite)
       @Listeners 定义一个测试类的监听器。
       @Parameters 介绍如何将参数传递给@Test方法。
    9、测试类@Test是否可以分组?
       答案是肯定的,在注解@Test后面加上(groups=”param”)进行分组,param为组名。举例:
       
        public class TestDemo {
        @BeforeClass
    public void setUp() {
    System.out.println("setUp");
    }

    @Test(groups="slow")
        public void aSlowTest() {
    System.out.println("slow test");
    }

    @Test(groups="fast")
        public void aFastTest() {
    System.out.println("fast test");
    }
    }
    10、分组后的测试类如何执行?
        由2种方法:一种是直接在build.gradle中配置进行调度,使用
         test {  
            useTestNG{  
            includeGroups 'slow'  
            }  
            } 
           配置完之后构建就可以了。查看报告回发现只有分组的测试类执行了。当然可以通过excludeGroups ‘fast’达到同样的效果;
        第二种方法是使用TestNG.xml进行配置,这种方法后续统一介绍;
    11、分组后可以建立依赖关系。
        通过dependsOnGroups实现,例如,
        @Test(groups = "fast",dependsOnGroups="pass")
       组名为pass的所有方法执行结果成功才会执行方法fast,任何一个方法不成功,则不执行fast;

    12、如何通过testNG.xml实现测试配置?
        1、创建一个testng.xml文件
        2、build.gradle中包含这个xml文件路径
          

       
       
       





       
       
  • Appium测试react-native前端技术实现的移动应用

    2017-07-29 20:40:34

      当听到前端是用react-native技术实现的andriod应用时,原以为这个是类似于H5实现的webview样式,可以通过chrome的inspect查看代码。后来,让开发代开了webview的debug开关,开关打开之后,应用页面无法加载出来,看到的是空白页面。
    后经对react-native技术的了解,发现其实这还是原生应用,因此无需打开webview的debug开关,也无需使用chrome的inspect,指需要使用uiautomator.bat工具即可定位元素。
      下面简单介绍下react-native技术,react-native技术Facebook也在用,它是能够在javascript和React的基础上获得完全一致的开发体验,构建世界一流的原生APP,可见其还是原生APP.它有着卓越的开发效率,学习一次,编写任何平台。听这挺不错。不过这种技术,通常元素没有id和name属性,这对于做自动化测试的打击面还是非常大的。
        我们在用Appium进行自动化脚本编写时,也的确发现元素大部分没有id和name属性,这种情况下只能通过xpath进行定位元素,同时为了保证脚本的稳定性和降低脚本的维护成本,我要求xpath全部写相对路径,绝对不写绝对路径。但是一个一个写xpath也是费时费力的事情,因此我们在tool中放了一个插件,可以自动生成元素的xpath,而且大部分是相对路径,还是非常不错的! 
      
     
  • adb命令汇总-持续更新中

    2017-07-26 13:26:27

    首先,需要对adb进行解释。
    什么是adb呢?Adb是Android debug bridge(Android调试桥)的缩写。adb是一个C/S架构的命令行工具,3部分构成:
    (1)、adb client端(运行在电脑上)
          tips:电脑上最好不要安装手机助手等软件,这样会占用adb的默认端口:5037
    (2)、adb server端(运行在电脑上)
          用于管理client和Andriod的adb后台进程
    (3)、adb后台进程(运行在手机上)
          主要是以下命令查看后台进程:adb shell ps|grep adbd
    其次, adb命令的分类:包括adb类、adb shell类和linux类。
    下面分别介绍
    ----------------------------------------------------------
     (1)、adb类:命令格式  adb [-e|-d|-s<设备序列号>....] <子命令>
           可通过 adb help或者adb命令查看
            例如:C:\Users\USER>adb
                 Android Debug Bridge version 1.0.31

                  -a                            - directs adb to listen on all interfaces for a connection
                  -d                            - directs command to the only connected USB device
                                     returns an error if more than one USB device is present.
                  -e                            - directs command to the only running emulator.
                                     returns an error if more than one emulator is running.
                  -s <specific device>          - directs command to the device or emulator with the given
                                     serial number or qualifier. Overrides ANDROID_SERIAL
                                     environment variable.
        adb类常用命令包括:
          1、adb devices  获取设备的id
          2、adb get-state  获取设备的状态,结果包括device(正常)、offline(异常)、unkwon(无设备)
          3、adb kill-server(结束adb服务)、adb start-server(启动adb服务),通常组合使用
          4、adb logcat  查看andriod系统日志,可以通过>重定向到制定的路径下面
          5、adb bugreport ,输出内容非常多、可以打印dumpsys\dumpstate\logcat信息,建议也重定向导出
          6、adb install (-r) application.apk 安装(覆盖)应用
          7、adb uninstall application.apk 卸载应用
          8、adb pull sdcard/demo.doc D:/将sdcard中的demo.doc文件复制到D盘
          9、adb push D:/demo.doc sdcard/将d盘下面的demo.doc复制到sdcard中
          10、adb reboot 重启机器
          11、adb connect远程连接Andriod设备(通过wifi进行连接,需要在同一局域网内,通常需要root权限)
              adb connect ip
    ------------------------------------------------------------
      (2)adb shell命令,待续
  • Monkey工具学习总结-原理篇

    2017-07-25 13:34:55

    Monkey工具的原理
          Monkey的启动文件在Android文件下面的/System/bin/monkey中。其主要的核心功能为调用monkey.jar文件,mankey.jar文件由多个类文件构成,其入口函数为com.andriod.commands.monkey.Monkey类。其代码构成包括:主控、监控、事件源和事件几个部分代码。源码获取地址:https://github.com/android/platform_development/tree/master/cmds/monkey
        其代码主要功能总结为:
        (1)、初始化事件源,创建事件队列;
         (2)、通过getNextEvent()方法循环获取事件。
          (3)、通过injectEvent方法调用WindowManager的方法讲事件注入系统中。
       
        
361/212>
Open Toolbar