pytest的http smoke tests辅助工具
项目描述
zeit.nightwatch
pytest的http smoke tests辅助工具
制作HTTP请求
zeit.nightwatch.Browser封装了一个requests Session以提供一些便利功能
使用基本URL进行实例化,然后仅使用路径:http = Browser('https://example.com'); http.get('/foo')将请求https://example.com/foo
提供了一个便利的http fixture,可以通过nightwatch_config fixture进行配置。
使用call代替get,因为这只是稍微短一点。(http('/foo')而不是http.get('/foo'))
由mechanicalsoup提供表单填写和提交功能。 (我们对此进行了一些定制,以便仅在真正使用表单或链接等特性时才使用beautifulsoup解析响应。)
记录请求和响应头,以便pytest在测试失败时打印这些信息,以帮助调试。
使用sso_login(username, password)登录到https://meine.zeit.de。
查看源代码以获取特定API的详细信息。
示例用法
@pytest.fixture(scope='session')
def nightwatch_config():
return dict(browser=dict(
baseurl='https://example.com',
sso_url='https://meine.zeit.de/anmelden',
))
def test_my_site(http):
r = http.get('/something')
assert r.status_code == 200
def test_login(http):
http('/login')
http.select_form()
http.form['username'] = 'joe@example.com'
http.form['password'] = 'secret'
r = http.submit()
assert '/home' in r.url
def test_meinezeit_redirects_to_konto_after_login(http):
r = http.sso_login('joe@example.com', 'secret')
assert r.url == 'https://www.zeit.de/konto'
检查HTML响应
nightwatch向requests.Response对象添加了两个辅助方法
xpath():使用lxml.html解析响应,然后在该文档上调用xpath()
css():使用cssselect将选择器转换为xpath,然后调用xpath()
示例用法
def test_error_page_contains_home_link(http):
r = http('/nonexistent')
assert r.status_code == 404
assert r.css('a.home')
使用Selenium控制浏览器
zeit.nightwatch.WebDriverChrome继承自selenium.webdriver.Chrome,以提供一些便利特性
使用基本URL进行实例化,然后只使用路径:browser = WebDriverChrome('https://example.com'); browser.get('/foo')
提供了一个便利的selenium fixture,可以通过nightwatch_config fixture进行配置。
wait()封装了WebDriverWait,并将TimeoutException`转换为``AssertionError
使用sso_login(username, password)登录到https://meine.zeit.de
查看源代码以获取特定API的详细信息。
nightwatch还声明了一个pytest命令行选项--selenium-visible,以帮助切换无头模式,并为使用selenium fixture的所有测试添加了一个selenium标记,因此您可以使用pytest -m selenium(或-m 'not selenium')来(取消)选择它们。由于您可能需要设置基本URL,您必须自己提供此fixture。
示例用法
@pytest.fixture(scope='session')
def nightwatch_config():
return dict(selenium=dict(
baseurl='https://example.com',
))
def test_js_based_video_player(selenium):
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
s = selenium
s.get('/my-video')
s.wait(EC.presence_of_element_located((By.CLASS_NAME, 'videoplayer')))
高级用法:使用selenium-wire拦截/修改浏览器请求,安装该包(例如pip install selenium-wire),并在nightwatch selenium配置中将driver_class=ProxiedWebDriverChrome设置为
@pytest.fixture(scope='session')
def nightwatch_config():
return dict(selenium=dict(
baseurl='https://example.com',
driver_class='ProxiedWebDriverChrome',
))
def test_inject_authorization_header(selenium):
s = selenium
s.request_interceptor = lambda x: r.headers['authorization'] = 'Bearer MYTOKEN'
s.get('/protected-page')
使用playwright控制浏览器
作为Selenium(如上所示)的替代方案,nightwatch还支持playwright;主要是通过引入pytest-playwright插件,因此您可以使用他们的fixture,并有一些便利特性
配置基本URL,然后只使用路径:page.goto('/foo')
示例用法
@pytest.fixture(scope='session')
def nightwatch_config():
return dict(selenium=dict(
baseurl='https://example.com',
))
def test_playwright_works(page):
page.goto('/something')
针对不同的环境运行
为了帮助在不同的环境中运行相同的测试,例如针对预发布环境和生产环境,nightwatch声明了一个pytest命令行选项--nightwatch-environment。
我们发现的一种有用的模式是使用fixture提供特定环境的设置,如下所示
CONFIG_STAGING = {
'base_url': 'https://staging.example.com',
'username': 'staging_user',
'password': 'secret',
}
CONFIG_PRODUCTION = {
'base_url': 'https://www.example.com',
'username': 'production_user',
'password': 'secret2',
}
@pytest.fixture(scope='session')
def nightwatch_config(nightwatch_environment):
config = globals()['CONFIG_%s' % nightwatch_environment.upper()]
return dict(environment=nightwatch_environment, browser=config)
def test_some_integration_that_has_no_staging(http, nightwatch_config):
if nightwatch_config['environment'] != 'production':
pytest.skip('The xyz integration has no staging')
r = http('/trigger-xyz')
assert r.json()['message'] == 'OK'
将测试结果发送到prometheus
就像中世纪的夜间守望者,他们四处巡逻检查门是否锁好一样,我们使用此库的用例是持续的黑盒高级测试,以检查我们系统的主功能区域是否正常工作。
为此,我们希望将测试结果与我们的监控系统集成,该系统基于Prometheus。我们从pytest-prometheus插件中汲取灵感,并进行了一些调整,以使用稳定的指标名称,这样我们就可以编写通用的警报规则。
这使用配置的Pushgateway来记录此类指标(环境标签从--nightwatch-environment填充,见上文)
nightwatch_check{test="test_error_page_contains_home_link",environment="staging",job="website"}=1 # pass=1, fail=0
客户端应设置作业名称,例如:
def pytest_configure(config):
config.option.prometheus_job_name = 'website'
此功能默认禁用,nightwatch声明了一个pytest命令行选项--prometheus,必须存在才能启用推送指标。还有命令行选项可以覆盖pushgateway URL等,请参阅源代码以获取详细信息。
将测试结果发送到Elasticsearch
我们以Kubernetes Pod的形式运行我们的测试,并将它们的stdout/stderr输出捕获并发送到Elasticsearch。然而,正常的pytest输出是为了人类,但不是机器可读的。因此,我们实现了一种JSON行测试报告格式,可以通过--json-report=filename或--json-report=-启用,以直接发送到stdout。
以下是一个输出示例,格式化为可读性(实际上,每个测试都产生一条单独的JSON行,因为那是我们的k8s日志处理器所期望的)
{
"time": "2023-12-08T10:37:40.630617+00:00",
"test_stage": "call",
"test_class": "smoketest.test_api",
"test_name": "test_example",
"test_outcome": "passed",
"system_log": "11:37:40 INFO [zeit.nightwatch.requests][MainThread] > POST http://example.com/something\n..."
}
zeit.nightwatch更改
1.9.1 (2024-06-04)
在导入时应用playwright Page.sso_login monkeypatch
1.9.0 (2024-06-04)
支持keycloak进行SSO
1.8.0 (2024-05-13)
也记录HTTP响应体,而不仅仅是标题。
1.7.1 (2023-12-13)
如果没有给出参数,则不要尝试json报告
1.7.0 (2023-12-08)
实现--json-report=-以支持基于行的输出
1.6.0 (2022-12-16)
支持playwright
1.5.1 (2022-06-24)
使用非弃用的selenium API
1.5.0 (2022-03-25)
除了
外还支持
1.4.2 (2022-02-21)
ZO-712: 在sso_login期间显式设置referer,这是csrf验证所必需的
1.4.1 (2021-10-27)
将测试和设置包含在tarball中,以支持devpi测试
1.4.0 (2021-10-26)
添加requests补丁
1.3.3 (2021-04-01)
对于find_link支持包含而不是等于
1.3.2 (2021-02-18)
将跳过的测试记录为对Prometheus的成功,而不是失败
1.3.1 (2021-02-17)
正确处理相同的指标名称(和测试名称仅作为标签)
1.3.0 (2021-02-17)
允许通过配置固定装置配置测试浏览器
1.2.0 (2021-02-17)
添加便利的nightwatch固定装置和顶级API
添加第一个测试和修复包设置
1.1.0 (2021-02-12)
在此处包含Prometheus功能,以修复pushgateway错误并支持将测试名称作为标签发送。
正确声明命名空间包
1.0.0 (2021-02-11)
初始发布
项目详细信息
下载文件
下载您平台上的文件。如果您不确定选择哪个,请了解更多关于安装包的信息。