Playwright支持同步和异步两种API,使用异步API需要导入asyncio库,它是一个可以用来实现Python协程的库,更详细介绍可参考Python协程 。我们可以根据自己的偏好选择适合的模式。
同步与异步模式原理
同步操作方式:在代码执行时,程序会阻塞等待每个操作执行的结果,直到该操作执行结束才能继续执行后面的代码。同步代码容易理解和编写,但如果在网络请求等 I/O 操作时会造成大量的等待时间,影响程序的执行效率。
异步操作方式:在代码执行时,当遇到需要等待操作执行的时候,程序不会被阻塞,而是继续执行其他的代码。当该操作执行的结果返回时,程序会自动跳回去接着执行之前被暂停的代码。异步操作虽然需要一定的学习成本,但可以提升程序的执行效率。
同步模式
· 直接顺序执行测试逻辑,直到完成。
· 使用上下文管理器或启动/关闭方法控制浏览器生命周期。
· 简单易用,适合同步测试场景。
· 但无法实现异步或重叠的测试逻辑。
异步模式
· 利用asyncio模块以异步非阻塞方式执行测试逻辑。
· 浏览器启动/关闭和大多数Playwright API也是异步的,需要await。
· 可以实现复杂的异步或重叠测试逻辑。
· 但较难调试,有一定学习成本。
同步和异步的概念
同步:发送一个请求,等待返回,然后再发送下一个请求。
异步:发送一个请求,不等待返回,随时可以再发送下一个请求。
同步和异步实践
测试用例
假设一共有2条测试用例:
用例1步骤如下:
1)chrome浏览器打开百度
2)搜索框输入“test”
3)点击百度一下搜索
4)点击搜索结果的第2页
用例2步骤:
1)chrome浏览器打开搜狗搜索
2)搜索框输入“test”
3)点击搜狗搜索
4)点击搜索结果的第2页
同步
这里我们使用sync_playwright上下文管理器同步启动Playwright,然后编写同步测试逻辑。
参考代码
根据上述测试用例编写自动化测试脚本代码如下:
import time
from playwright.sync_api import sync_playwrightdef testcase1():print('testcase1 start')with sync_playwright() as p:browser = p.chromium.launch(headless=False)page = browser.new_page()page.goto("https://www.baidu.com/")print(page.title())page.fill("input[name=\"wd\"]", "test")page.click("text=百度一下")page.click("#page >> text=2")browser.close()print('testcase1 done')def testcase2():print('testcase2 start')with sync_playwright() as p:browser2 = p.chromium.launch(headless=False)page2 = browser2.new_page()page2.goto("https://www.sogou.com/")print(page2.title())page2.fill("input[name=\"query\"]", "test")page2.click("text=搜狗搜索")page2.click("#sogou_page_2")browser2.close()print('testcase2 done')start = time.time()
testcase1()
testcase2()
end = time.time()
print('Running time: %s Seconds' % (end - start))
异步
这里我们使用asyncio模块异步启动Playwright,然后编写异步测试逻辑。需要使用await关键字标识异步操作。
参考代码
根据上述测试用例编写自动化测试脚本代码如下:
import asyncio
import timefrom playwright.async_api import async_playwrightasync def testcase1():print('testcase1 start')async with async_playwright() as p:browser = await p.chromium.launch(headless=False)page = await browser.new_page()await page.goto("https://www.baidu.com/")print(await page.title())await page.fill("input[name=\"wd\"]", "test")await page.click("text=百度一下")await page.click("#page >> text=2")await browser.close()print('testcase1 done')async def testcase2():print('testcase2 start')async with async_playwright() as p:browser2 = await p.chromium.launch(headless=False)page2 = await browser2.new_page()await page2.goto("https://www.sogou.com/")print(await page2.title())await page2.fill("input[name=\"query\"]", "test")await page2.click("text=搜狗搜索")await page2.click("#sogou_page_2")await browser2.close()print('testcase2 done')async def main():task1 = asyncio.create_task(testcase1())task2 = asyncio.create_task(testcase2())tasks = [task1, task2]print('before await')await asyncio.gather(*tasks)start = time.time()
asyncio.run(main())
end = time.time()
print('Running time: %s Seconds' % (end - start))
通过对比同步和异步的运行时间可以看到,使用异步编程的方式可以显著提升测试效率
Python Playwright 支持同步和异步两种操作方式。
同步操作方式:在代码执行时,程序会阻塞等待每个操作执行的结果,直到该操作执行结束才能继续执行后面的代码。同步代码容易理解和编写,但如果在网络请求等 I/O 操作时会造成大量的等待时间,影响程序的执行效率。
异步操作方式:在代码执行时,当遇到需要等待操作执行的时候,程序不会被阻塞,而是继续执行其他的代码。当该操作执行的结果返回时,程序会自动跳回去接着执行之前被暂停的代码。异步操作虽然需要一定的学习成本,但可以提升程序的执行效率。
Python Playwright 默认使用异步操作方式。可以通过使用 await 关键字或 async with 语法来定义异步操作,或者使用 sync 关键字来定义同步操作。
headless 模式
在launch方法的参数中添加 headless=False playwright默认是无头模式运行,True是无头模式,False是有头模式,即在电脑上能看到浏览器的运行界面。默认情况下,Playwright 以无头模式运行浏览器。要查看浏览器 UI,请headless=False在启动浏览器时传递标志。有头模式适用于调试,而无头模式适用于CI / cloud执行。
headless 无头模式运行浏览器示例: 打开浏览器/不打开浏览器
from playwright.sync_api import sync_playwrightwith sync_playwright() as p:# headless无头模式运行浏览器示例: 不打开浏览器界面browser = p.chromium.launch()# 非headless无头模式运行浏览器示例: 打开浏览器界面# browser = p.chromium.launch(headless=False) # 启动 chromium 浏览器page = browser.new_page() # 打开一个标签页page.goto("https://www.baidu.com") # 打开百度地址print(page.title()) # 打印当前页面titlepage.click("input[name=\"wd\"]") # 点击输入框page.fill("input[name=\"wd\"]", "chromium") # 在输入框输入浏览器名字page.screenshot(path=f'example-{p.chromium.name}.png')browser.close() # 关闭浏览器对象