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)
初始发布
项目详细信息
下载文件
下载您平台上的文件。如果您不确定选择哪个,请了解更多关于安装包的信息。