A unit test has three parts whatever the language: arrange the inputs and any collaborators, act by calling the code under test, assert that the result matches what the specification says. It runs without a database, a network or a browser, which is what makes it fast, and a suite of a few thousand tests runs in under a minute. Frameworks follow one family, xUnit, that began with Kent Beck's SUnit and now includes JUnit, pytest, Jest and their equivalents in every language; a Python developer and a JavaScript developer write the same shape of test in different syntax. ISTQB calls this level component testing, and the Foundation Level exam tests the vocabulary of levels, from component through integration and system to acceptance.
The test pyramid, drawn by Mike Cohn and written up by Martin Fowler in 2012, says where the effort should go: many unit tests at the base, fewer tests through a service layer in the middle, and few tests that drive the user interface at the top. The reasoning is cost and trust. Tests that run end to end through a browser are slow to run, expensive to write and break for causes unconnected to the code, which leads a team to disregard failing results. Unit tests fail for one reason, in one place, in a second, and so are acted on. A suite shaped like an inverted pyramid, with hundreds of browser tests and few unit tests, is the common shape of a project that automated its manual test plan instead of designing a test strategy.
What a unit test does not catch
The wrong requirement, a broken database query, a misconfigured server, two correct modules that disagree about a date format. Those need integration tests, contract tests and a staging environment. A green unit suite says the pieces work as their author understood them, nothing more.
Two habits decide whether a suite helps or hinders. The first is test doubles: a stub returns a canned answer so that the test does not touch the network, a mock additionally checks that it was called as expected. Used at the boundary they make tests fast; used everywhere they produce tests that pass while the real system fails, because every collaborator was replaced by an assumption. The second is test-driven development, Beck's 2002 discipline of writing the failing test first, making it pass with the simplest code and then tidying; it is less a testing technique than a design one, and it produces code that can be tested because it was written to be. Both habits are taught in the software testing courses and practised in the pipeline: a suite that runs on every push is the reason continuous integration can call a build self-testing.
