Pester icon indicating copy to clipboard operation
Pester copied to clipboard

Get current test name

Open majkinetor opened this issue 4 years ago • 14 comments

Is it possible to get current test name (the one available as ExpandedName after test runs) during test exeuction ?

I want to create generic helper that will save some debuging information in the file that is named by the test name.

majkinetor avatar Jun 19 '20 13:06 majkinetor

@nohwnd there is a TestName variable present in the It context but it isn't being populated. Bug maybe? No reason it shouldn't have all the information it needs to populate it prior to It execution image

JustinGrote avatar Jun 22 '20 21:06 JustinGrote

If this is the new 5.0.2 version: The code that executes directly inside of the Describe block is evaluated during the new 'Discovery' phase and isn't available when the tests run. Try throwing your script sourcing inside of a BeforeAll or BeforeEach block right inside of the Describe block and before your It block.

efie45 avatar Jun 23 '20 15:06 efie45

So, is there a way to get current test name at some place (BeforeEach or inside It block)? I didn't get this from the thread, sorry. Would like to send this information to the ElasticSearch for tracing purposes.

mkarpuk avatar Jul 01 '20 17:07 mkarpuk

Yeah, for Elastic you would definitelly need to obtain it, that is what I needed it for among other things. The other case was sending results data to InfluxDb for metric purposes and flaky test analysis across runs (also for timings) and for that it was enough to send everything after the run using results object.

I hardcoded test names for now on few places that I needed it the most, but this is something required for systemic solution (and also supported by some other test frameworks).

majkinetor avatar Jul 01 '20 17:07 majkinetor

@mkarpuk as far as I can tell you can't at the moment and I'm pretty sure its a bug, you could workaround it by just setting a variable within each test e.g. $SCRIPT:CurrentTestName = 'mytest1' for now.

JustinGrote avatar Jul 01 '20 18:07 JustinGrote

$SCRIPT:CurrentTestName = 'mytest1'

That will get ugly pretty fast. Maybe a preprocessor is a better idea - it can inject such things before execution.

majkinetor avatar Jul 02 '20 07:07 majkinetor

@majkinetor like I said it's a temporary workaround not a prescriptive guidance, there is a testname variable that should be populated. If I find some time maybe I'll put together a PR.

JustinGrote avatar Jul 02 '20 14:07 JustinGrote

You could do this, if you are not afraid to use internal apis, that might change in the future

& (get-module pester) {

    $state.Plugin += (New-PluginObject -Name "Logger" -EachTestSetupStart { 
        $Test = $Context.Test 

        Write-Host "name: $($Test.Name), path: $($Test.Path)"
    } )
}

Describe "a" { 

    It "b" { 
        
    }

    It "c" {

    }
}

Starting discovery in 1 files.
Discovery finished in 40ms.
name: b, path: a b
name: c, path: a c
[+] C:\Users\jajares\Desktop\fufuffufuf.tests.ps1 261ms (55ms|178ms)
Tests completed in 264ms
Tests Passed: 2, Failed: 0, Skipped: 0 NotRun: 0

nohwnd avatar Jul 09 '20 14:07 nohwnd

Any chance we can have something normal ? :) Something like $TestName variable within test or similar ...

Interesting syntax - pretty sure I have never seen it in last decade on PowerShell :)

majkinetor avatar Jul 09 '20 16:07 majkinetor

@majkinetor the syntax is how you use the call operator to run a comand within the module scope, it's a neat trick especially when testing modules.

Here is an example that is more what you are looking for, WARNING it's a kludge because this code runs "on the side" of the tests and so there's no way to inherit the scope, so a global variable is used. It is cleaned up but if you already have a testname global variable it will blow it away

function Enable-TestNameAsVariablePlugin {
    & (get-module pester) {
        $PluginParams = @{
            Name = "SaveTestNameToVariable"
            EachTestSetupStart = {
                $GLOBAL:TestName = $Context.Test.Name
            }
            EachTestTeardown = {
                $GLOBAL:TestName = $null
            }
        }
        $state.Plugin += New-PluginObject @PluginParams
    }
}

Describe "a" { 
    Enable-TestNameAsVariablePlugin

    It "b" { 
        $TestName | Should -Be 'b'
    }

    It "c" {
        $TestName | Should -Be 'c'
    }
}

image

JustinGrote avatar Jul 09 '20 16:07 JustinGrote

Yeah, thats more nice. I am not sure if it will work will paralel execution (https://github.com/pester/Pester/issues/1270)

majkinetor avatar Jul 09 '20 16:07 majkinetor

@majkinetor yeah it's not thread safe, you might hit a race condition unless the plugin runs within the runspace of the test, I'm not sure when Parallel "kicks in" in terms of the plugins.

JustinGrote avatar Jul 09 '20 16:07 JustinGrote

How fragile/hacky is doing this $____Pester.CurrentTest.Name

simonsabin avatar Mar 05 '21 18:03 simonsabin

@simonsabin that's recent addition. I plan to embrace it, but did not settle on the name entirely. Probably will rename it to just Pester later. Other than that, if you don't modify the state, and take the risk of the variable being renamed later you should be good to go. I think you can assume that you will have access to the test name in one way or another in the future.

nohwnd avatar Mar 12 '21 08:03 nohwnd