File placement and naming
Common convention
Pester considers all files named .Tests.ps1 to be test files. This is the default naming convention that is used by almost all projects.
Each file is called as the function it tests. This means that for a function Get-Emoji we would have Get-Emoji.Tests.ps1 and Get-Emoji.ps1.
Test files are placed in the same directory as the code that they test, or in a separate tests directory that follows the same directory structure as the main src directory.
Get-Emoji.ps1
Get-Emoji.Tests.ps1
# or
src/public/Get-Emoji.ps1
tests/public/Get-Emoji.Tests.ps1
Hidden files and folders
On macOS and Linux a file or folder whose name starts with a dot — such as .github — is hidden (on Windows the equivalent is the Hidden file attribute). This matters when you mirror your source layout, because tests for code that lives in .github naturally end up in tests/.github.
Pester follows the PowerShell default and ignores hidden items during discovery, so a recursive run over tests silently skips anything under a hidden folder like tests/.github.
Pass the hidden folder as an explicit path (Invoke-Pester -Path ./tests/.github) to include the non-hidden files inside it; test files that are themselves hidden must still be named explicitly.
Pester v6 changes this default — it discovers hidden files and folders automatically, skipping only version-control directories (.git, .svn and .hg).
Custom conventions
The convention above is the default that most projects use, but Pester is not prescriptive about how you should name or place your files. The default extension can be customized by setting the Run.TestExtension configuration option. The relative position of files can be then adjusted by changing the code you use to code files into tests. See Importing tested functions.
However the convention above is the default and is recommended to be used, especially when you are starting with Pester.
Categorizing tests
There can be many tests in one file, but in bigger projects you might want to distinguish, Unit, and Acceptance tests (or whatever are the categories of tests you have). This is typically approached by using tags. But another way is to split the tests in separate files and name them accordingly Get-Emoji.Unit.Tests.ps1, Get-Emoji.Acceptance.Tests.ps1. This keeps your Acceptance test and Unit test code separate, which might be a good idea as Acceptance tests are usually more complex, and require more dependencies.
You can then use the Run.TestExtension configuration option to customize the file extension convention to run only *.Unit.Tests.ps1, only *.Acceptance.Tests.ps1 or keep the default to run all *.Tests.ps1. Even more fine-grained control is possible by using the -ExcludePath parameter, or by using Get-ChildItem to filter all paths and then provide them to -Path parameter.