Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Describe does not recognize the function when it is defined in the same file #1604

Closed
JohnLeyva opened this issue Jun 17, 2020 · 9 comments
Closed

Comments

@JohnLeyva
Copy link

JohnLeyva commented Jun 17, 2020

Describe does not recognize the function when it is defined in the same file in PESTER 5

This does not follow the guidelines where testes are declared separeted in its own .tests.ps1 files, but declaring the function and the describe in the same file help to understand better the code and promote the use of automated testing.

Up to this point I haven't been able to isolate the issue, but a segment like the following

function Add-Prefix($prefix) {
    process {
        [string]$value =  "$_"
        if ( -not $value.StartsWith( $prefix) ) {
            $value = $prefix + $value
        }
        return $value
    }
}

Describe Add-Prefix { 
    it Test {
        'bcde' | Add-Prefix 'a' | Should -Be 'abcde'
        $null | Add-Prefix 'a' | Should -Be 'a'
    }
}

can generate the following error

[-] Add-Prefix.Test 125ms (121ms|4ms)
 CommandNotFoundException: The term 'Add-Prefix' is not recognized as the name of a cmdlet, function, script file, or operable program.
 Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
 at <ScriptBlock>, C:\code\PowerFrame\pf-string\pf-string.ps1:696

Interestingly when the segment is moved to the beginning of file the issue is not present.

An aspect that might be important is that this file is loaded by a module.

@nohwnd
Copy link
Member

nohwnd commented Jun 17, 2020

In v5 setup code should be in BeforeAll block, that way it will be available to your test. https://jakubjares.com/2020/04/11/pester5-discovery-and-script-setup/

@JohnLeyva
Copy link
Author

In the example presented Add-Prefix is the function to test and it is exported by the module so cannot defined in an BeforeAll block.

The expectation in this case is because the function the declared before the describe, it should be available.

Seems that a file that interleaves several Describes and module functions generates the issue.

@nohwnd
Copy link
Member

nohwnd commented Jun 18, 2020

@JohnLeyva
Are you saying that you are importing a module that exports this function? That should work.
Are you saying that you are dot-sourcing a function that a module will later export? That would not work, you would have to dot-source it in a BeforeAll.
Are you saying that you have function directly in the same file as the tests? Then I don't know how you distribute this, because all tests would run on every import of your module.

@JohnLeyva
Copy link
Author

Indeed I've noticed that tests ran when files are loaded, and in my case that is not desirable.

I want code and tests to be side by side (Same file) as it facilitates understanding and maintenance.

My expectation is that modules/file only define functions and tests. A test runner can discovers tests and execute them.

Wondering if Pester 5 or even a previous version might allow this

@nohwnd
Copy link
Member

nohwnd commented Jun 18, 2020

@JohnLeyva Nope, that won't work, simple because Describe is a function call, no different from any other function call. So unless you'd be able to force it to not run you would always run tests on import.

A better approach, and the one that is already used is to import the function into scope by dotsourcing it. OR by importing the module before testing it.

@EliiseS
Copy link

EliiseS commented Jul 3, 2020

How can we encapsulate logic that needs to run in the middle of the test, but in multiple tests?

Here's an example:

function Get-ResourceState($address) {
    # Get state and resources after `terraform apply`
    $tfState = terraform show -json | ConvertFrom-Json
    $resources = $tfState.values.root_module.resources

    return $resources | Where-Object { $_.address -eq $address }
}

function Get-Project {
    return Get-ResourceState "azuredevops_project.test"
}

Describe "Terraform Deployment" -Tag 'Deploy' { 
    Context "with clean tfstate" {

        It "initialize terraform" {
            terraform init
        }

        # Run terraform
        It "applying terraform from scratch" {
            Write-Host ""
            $tfResult = terraform apply -auto-approve
            Write-Host $tfResult
            $LASTEXITCODE | Should -Be 0
        }

        It "returns state for all resources" {
            Get-Project | Should -Not -BeNullOrEmpty
        }

        It "returns a valid repostiory for the repository ID" {
            $repository = Get-Project
            $repository.values.id | Should -Not -BeNullOrEmpty
            az repos show -r $repository.values.id -p $repository.values.project_id --org ${env:AZDO_ORG_SERVICE_URL}
            $LASTEXITCODE | Should -Be 0
        }

Right now the above test results the same error as OP:

[-] Terraform Deployment.with clean tfstate.returns state for all resources 12ms (10ms|2ms)
 CommandNotFoundException: The term 'Get-Project' is not recognized as the name of a cmdlet, function, script file, or operable program.
 Check the spelling of the name, or if a path was included, verify that the path is correct and try again.

Also, doesn't this example here fail: https://github.com/pester/Pester#collect-all-should-failures?

@nohwnd
Copy link
Member

nohwnd commented Jul 27, 2020

@EliiseS Just put it in BeforeAll:

BeforeAll {
    function Get-ResourceState($address) {
        # Get state and resources after `terraform apply`
        $tfState = terraform show -json | ConvertFrom-Json
        $resources = $tfState.values.root_module.resources

        return $resources | Where-Object { $_.address -eq $address }
    }

    function Get-Project {
        return Get-ResourceState "azuredevops_project.test"
    }
}

Describe "Terraform Deployment" -Tag 'Deploy' { 
    Context "with clean tfstate" {

@nohwnd
Copy link
Member

nohwnd commented Jul 27, 2020

Also, doesn't this example here fail: https://github.com/pester/Pester#collect-all-should-failures?

Yes, good catch fixing.

@fflaten
Copy link
Collaborator

fflaten commented Jul 3, 2022

Closing as it seems to have been answered. Let me know if it's not.

@fflaten fflaten closed this as completed Jul 3, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants