软件自动化测试就是通过测试工具或者其他手段,按照测试人员的预定计划对软件产品进行自动化测试,他是软件测试的一个重要组成部分
能够完成许多手工测试无法完成或者难以实现的测试工作,正确合理的实施自动化测试,能够快速,全面的对软件进行测试,从而提高软件质量,节省经费,缩短软件的发布周期
自动化测试就是任何利用工具来辅助的测试,几乎在计算机工业产生的第一天,这种测试就出现了
历史上从来没有出现过“测试自动化取代测试工程师工作”这种事情发生,除非你完全忽略测试人员们的真正工作
测试自动化意味着使用测试工具。自动化测试是个古老的理念
误区:
1). 自动化测试完全替代手工测试
2). 自动化测试一定比手工测试厉害
3). 自动化可以发掘更多的BUG
分类:web(UI)自动化测试,app移动自动化测试,接口自动化测试,单元测试自动化测试
需求变动不频繁,项目周期长,项目需要回归测试——适合做web自动化测试
误报成功也是测试结果成功的一种情况,即使实际情况并非如此。反之亦然,误报失败是测试失败一种情况,即使一切都按预期进行,测试结果也会报告脚本执行过程中出现错误。误报对自动化测试一直是最大的挑战,当然Selenium也不例外
当测试工程师通过Selenium脚本运行成百上千的测试用例时,可能会遇到一些不稳定的测试,这些测试显示误报。如果长时间不处理,可能会导致整个自动化测试项目失去价值,从而使测试人员的自动化测试脚本沦为“废物”
测试脚本的稳定性无疑是Selenium自动化中最常见的挑战之一。目前通用的解决办法依然缺少,但从过往工作经验来看,测试左移,独立测试环境,统计脚本误报率等等从流程上来解决这个难题是一个不错的思路
现在很多网站包含需要JS异步加载Web元素,例如基于用户选择的下拉列表。则Selenium脚本在运行时可能会在这些Web元素时突然失效。发生这种情况是因为WebDriver没有处理网页完全加载所花费的时间
为了处理页面加载的Selenium自动化中的异步加载的问题,需要使WebDriver等到该页面的完整JavaScript加载完成之后再进行操作
在任何网页上执行测试之前,您应确保该网页(尤其是带有很多JavaScript代码的网页)的加载已完成。您可以使用readyState属性,该属性描述文档/网页的加载状态
document.readyState状态为complete表示页面/文档的解析已完成
''' 在此示例中,我们将pytest框架与Selenium一起使用 '''
import pytest
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.keys import Keys
from time import sleep
from contextlib import contextmanager
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support.expected_conditions import staleness_of
@pytest.fixture(params=["chrome"],scope="class")
def driver_init(request):
if request.param == "chrome":
web_driver = webdriver.Chrome()
request.cls.driver = web_driver
yield
web_driver.close()
@pytest.mark.usefixtures("driver_init")
class BasicTest:
pass
class Test_URL(BasicTest):
def test_open_url(self):
self.driver.get("https://www.*****.com/")
print(self.driver.title)
sleep(5)
def wait_for_page_load(self, timeout=30):
old_page = self.driver.find_element_by_id('owl-example')
yield
WebDriverWait(self.driver, timeout).until(
staleness_of(old_page)
)
def test_click_operation(self):
# 等待10秒钟的超时时间,然后执行CLICK操作
with self.wait_for_page_load(timeout=10):
self.driver.find_element_by_link_text('FREE SIGN UP').click()
print(self.driver.execute_script("return document.readyState"))
Selenium是一种出色的自动化测试工具,它是开源的,它使世界各地的Web测试人员的生活变得更加轻松。但是,Selenium自动化的主要挑战之一是无法扩展
执行自动化测试的最终目标是在更短的时间内覆盖更多的测试范围。最初可能会进行简短的测试构建,但是产品势必会随着每个迭代版本发生变化。这意味着您可能需要涵盖更多的测试用例。使用Selenium WebDriver,您只能以顺序的方式执行测试,并且效果不如您希望的自动化过程有效,测试脚本的执行速度也会变得越来越慢
现在,Selenium Grid可以并行运行测试用例,但这也有一个缺点。无法跨浏览器和操作系统的多种组合全面测试网站或网络应用。因为Selenium Grid仅有助于在本地计算机上安装的特定浏览器上执行跨浏览器测试。您可以利用Selenium中的并行测试功能来代替线性测试,从而降低总体项目成本,并在并行执行自动化测试时加快产品/功能迭代交付
越来越多的网站使用了动态的内容。测试具有静态内容的网站对Selenium自动化来说相对轻松。在当今时代,大多数网站所包含的内容可能因一个访客而异。这意味着内容本质上是动态的(基于AJAX的应用程序)
例如,电子商务网站可以根据用户登录的位置加载不同的产品、内容可能会有所不同,具体取决于用户从特定下拉菜单中选择的内容。由于新内容的加载需要时间,因此仅在加载完成后才触发测试非常重要。由于网页上的元素以不同的时间间隔加载,因此如果DOM中尚不存在某个元素,则可能会出现错误。这就是为什么处理动态内容一直是Selenium自动化中最常见的挑战之一的原因
解决此问题的一个简单解决方案是使线程休眠几秒钟,这可能会提供足够的时间来加载内容。但是,这不是一个好习惯,因为,无论是否发生必需的事件,线程都会休眠那么长的时间
# 并不完美的方案
from selenium import webdriver
import time
from time import sleep
driver = webdriver.Firefox()
driver.get("https://www.*****.com")
# 睡眠10秒,无论是否存在元素
time.sleep(10)
# 资源释放
driver.close()
使用Selenium WebDriver动态内容处理此挑战的更好方法是使用隐式等待或显式等待,这取决于各自的需求
使用显式等待,您可以使Selenium WebDriver停止执行并等待直到满足特定条件
如果您希望设置条件以等待到确切的时间段,则可以将它与thread.sleep()函数一起使用
有多种方法可以实现显式等待,带有ExpectedCondition的WebDriver是最受欢迎的选项
from selenium import webdriver
from time import sleep
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.support.ui import WebDriverWait
driver = webdriver.Firefox()
driver.get("https://www.*****.com")
try:
myElem_1 = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CLASS_NAME, 'home-btn')))
print("Element 1 found")
myElem_2 = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CLASS_NAME, 'login')))
print("Element 2 found")
myElem_2.click()
sleep(10)
#异常处理
except TimeoutException:
print("No element found")
sleep(10)
driver.close()
在上面的示例中,对受测URL内容进行了两次搜索。第一次搜索是通过CLASS_NAME将元素定位到元素home-btn的最长持续时间为10秒
第二个搜索是可点击元素登录,最长持续时间为10秒。如果存在clickable元素,则执行click()操作。在两种情况下,都将WebDriverWait与ExpectedCondition一起使用
WebDriverWait触发ExpectedCondition的默认限制为500毫秒,直到收到成功的响应
隐式等待通知WebDriver在特定时间段内轮询DOM,以获取页面上Web元素的存在。默认超时为0秒。隐式等待需要一次性设置,如果配置正确,它将在Selenium WebDriver对象的生存周期内可用
from selenium import webdriver
import time
from time import sleep
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.support import expected_conditions as EC
from builtins import str
driver = webdriver.Firefox()
driver.get("https://www.*****.com")
driver.implicitly_wait(60)
curr_time = time.time()
try:
curr_element = driver.find_element_by_class_name("home-btn")
except:
print("元素不存在!")
print("耗时 " + str(int(time.time()-curr_time))+'-secs')
driver.close()
多窗口测试无疑是Selenium自动化中的常见挑战之一。一种理想的情况是单击按钮会打开一个弹出窗口,该弹出窗口成为子窗口。一旦有关子窗口上的活动的活动完成,则应将控件移交给父级或者上一级窗口。这可以通过使用switch_to.window()方法(其中window_handle作为输入参数传递)来实现
用户单击链接后,将打开一个新的弹出窗口,该窗口将称为子窗口。switch_to.window方法用于切换回父窗口。可以使用driver.switch_to.window(window-handle-id)或driver.switch_to.default_content()切换到父窗口
import unittest
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from time import sleep
class test_switch_windows(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Firefox()
def test_open_pop_up_window(self):
driver = self.driver
driver.get("http://www.****.com/html/codes/html_popup_window_code.cfm")
title1 = driver.title
print(title1)
#获取当前窗口的窗口句柄
parent_window = driver.window_handles[0]
print(parent_window)
#弹出式窗口是iframe
driver.switch_to.frame(driver.find_element_by_name('result1'))
driver.find_element_by_link_text('show_iframe').click()
#获取子窗口的句柄
child_window = driver.window_handles[1]
#父窗口将在后台
#子窗口来到前台
driver.switch_to.window(child_window)
title2 = driver.title
print(title2)
print(child_window)
#断言主窗口和子窗口标题不匹配
self.assertNotEqual(parent_window , child_window)
sleep(5)
def tearDown(self):
self.driver.close()
if __name__ == "__main__":
unittest.main()
100%自动化是一个吹牛的命题
众所周知的是,并非所有测试方案都可以自动化,因为有些测试需要手动干预。您需要确定团队在自动化测试上相对于手动测试应花费的精力的优先级。尽管Selenium框架具有一些功能,可以通过这些功能来截取屏幕截图,记录视频(测试的整体执行情况)以及可视化测试的其他方面
但是将这些功能与可扩展的基于云的跨浏览器测试平台一起使用可能会具有很大的价值
有各种工具可供选择。投入必要的时间来分析哪些工具符合您的要求,并确定使用工具和编写自动化测试所需的技能
使用容器简化设置测试环境并运行测试自动化
维护和高拥有成本。随着积极的计划推出新功能,设计可能会随着功能而改变并打破自动化。这导致改变自动化测试,这需要大量的时间和精力
端到端测试仍然存在问题,因为它们很难维护并且运行缓慢。它们没有很好的替代品(柏树模拟的用户界面测试或合同测试不够)
初创企业应该从围绕测试驱动设计的最佳实践开始,使用硬件,软件和日志记录来获取数据。更多的初创企业指导框架
与供应商合作并尝试他们的软件来帮助您取得成功。你需要能够信任并大规模地做事。这是一个艰难的情况,你不知道你不知道什么
人们进行自动化测试的能力与他们试图实现的覆盖范围之间存在不平衡。更成熟可以支持更高程度的自动化。我们看到许多公司试图在没有足够成熟的情况下实现高水平的自动化。盲目地追求100%自动化而不了解策略是有问题的