Powershell Core + Pester - Separating tests from src
Asked Answered
W

1

5

Question:

What would be the best way to import functions to tests that don't reside in the same directory?

Example

πŸ“ src
      πŸ“„ Get-Emoji.ps1
πŸ“ test
      πŸ“„ Get-Emoji.Tests.ps1

Inb4

  • Pester documentation[1] suggests test files are placed in the same directory as the code that they test. No examples of alternatives provided.
  • Pester documentation[2] suggests dot-sourcing to import files. Only with examples from within same directory
  • Whether breaking out tests from the src is good practice, is to be discussed elsewhere
  • Using Powershell Core for cross platform support on different os filesystems (forward- vs backward slash)

[1] File placement and naming 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.

Test files are placed in the same directory as the code that they test. 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 in the same directory. What would be the best way to referencing tests to functions in Pester.

[2] Importing the tested functions

Pester tests are placed in .Tests.ps1 file, for example Get-Emoji.Tests.ps1. The code is placed in Get-Emoji.ps1.

To make the tested code available to the test we need to import the code file. This is done by dot-sourcing the file into the current scope like this:

Example 1

# at the top of Get-Emoji.Tests.ps1
BeforeAll { 
    . $PSScriptRoot/Get-Emoji.ps1
}

Example 2

# at the top of Get-Emoji.Tests.ps1
BeforeAll { 
    . $PSCommandPath.Replace('.Tests.ps1','.ps1')
}
Wellbeloved answered 5/12, 2020 at 18:3 Comment(3)
Not sure I understand what the issue is. Is dot sourcing not an option? – Gusher
Sure, dot sourcing works. But how would be the best way? An alternative for example could be . ([IO.Path]::Combine($PSEditor.Workspace.Path, "path/to/function/Get-Emoji.ps1")) – Wellbeloved
Another dimension to also consider is absolute vs relative paths. – Wellbeloved
L
7

I tend to keep my tests together in a single folder that is one or two parent levels away from where the script is (which is usually under a named module directory and then within a folder named either Private or Public). I just dot source my script or module and use .. to reference the parent path with $PSScriptRoot (the current scripts path) as a point of reference. For example:

  • Script in \SomeModule\Public\get-something.ps1
  • Tests in \Tests\get-something.tests.ps1
BeforeAll { 
    . $PSScriptRoot\..\SomeModule\Public\get-something.ps1    
}

Use forward slashes if cross platform compatibility is a concern, Windows doesn't mind if path separators are forward or backslashes. You could also run this path through Resolve-Path first if you wanted to be certain a valid full path is used, but I don't generally find that necessary.

Larrup answered 5/12, 2020 at 23:42 Comment(0)

© 2022 - 2024 β€” McMap. All rights reserved.