Choosing the right assertion
Assert on the most specific condition you can. For UI checks, prefer web-first assertions that auto-retry (Playwright's toBeVisible, Cypress's should) over reading a value and comparing it yourself — they wait for the condition and remove a whole class of flakiness. For data checks, use deep equality for collections and objects rather than reference equality.
JUnit 5 vs TestNG
The matchers are close cousins: both offer assertEquals, assertTrue, assertThrows. JUnit 5 puts the expected value first and adds assertAll for grouped assertions and assertIterableEquals for collections; TestNG's assertEquals is overloaded for many types and integrates tightly with its data-provider model.
Playwright expect vs Chai
Playwright's expect has two flavours: generic value matchers and auto-retrying locator assertions (the await expect(locator).toBeVisible() form). Chai — used by Cypress and Mocha — reads as fluent English (expect(x).to.equal(y)) and Cypress layers retry-ability on top through .should().