so im new to testing and have been learning python/playwright testing for a couple of weeks now.
I've got to assertions and have found multiple ways to write them, so this might sound like a stupid question but which of these 3 types of assertions would be best to use, or is there one that i don't know about that is better.
Playwright Assertions:
https://playwright.dev/python/docs/test-assertions
Unittest Assertions:
https://docs.python.org/3/library/unittest.html
Python Assertions:
https://realpython.com/python-assert-statement/
Here is a little example:
class ExperimentTest(StaticLiveServerTestCase):
def test_experimental(self):
page.goto(f"{self.live_server_url}")
expect(page).to_have_url(f"{self.live_server_url}")
assert page.url == f"{self.live_server_url}")
self.assertEqual(page.url, f"{self.live_server_url}")
When using Playwright, almost always use the Playwright assertion, which waits for the predicate to be true.
Consider the following simple example:
from playwright.sync_api import expect, sync_playwright
html = r"""<!DOCTYPE html><html><body>
<h1>NO!</h1>
<script>
setTimeout(() => {
document.querySelector("h1").textContent = "YES!"
}, 3000);
</script>
</body></html>
"""
def main():
with sync_playwright() as p:
browser = p.chromium.launch()
page = browser.new_page()
page.set_content(html)
expect(page.locator("h1")).to_have_text("YES!")
browser.close()
if __name__ == "__main__":
main()
This passes, even though the site takes 3 seconds after load to change its header text from NO! to YES!. If you use any other assertion library, the auto-wait will not occur.
Now change the above code to fail: expect(page.locator("h1")).to_have_text("NEVER!")
. The output will be clear:
AssertionError: Locator expected to have text 'NEVER!'
Actual value: YES!
Call log:
LocatorAssertions.to_have_text with timeout 5000ms
waiting for locator("h1")
locator resolved to <h1>NO!</h1>
unexpected value "NO!"
locator resolved to <h1>NO!</h1>
unexpected value "NO!"
locator resolved to <h1>NO!</h1>
unexpected value "NO!"
locator resolved to <h1>NO!</h1>
unexpected value "NO!"
locator resolved to <h1>NO!</h1>
unexpected value "NO!"
locator resolved to <h1>NO!</h1>
unexpected value "NO!"
locator resolved to <h1>NO!</h1>
unexpected value "NO!"
locator resolved to <h1>YES!</h1>
unexpected value "YES!"
locator resolved to <h1>YES!</h1>
unexpected value "YES!"
Notice it's retried and tracked changes over time, eventually emitting a clear error which makes debugging easier.
As an aside, there's no need to use f-strings if you're not concatenating anything: f"{self.live_server_url}"
should be self.live_server_url
.