1"use strict";(self.webpackChunkpester_docs=self.webpackChunkpester_docs||[]).push([["2826"],{954(e,s,n){n.r(s),n.d(s,{metadata:()=>t,default:()=>h,frontMatter:()=>i,contentTitle:()=>a,toc:()=>d,assets:()=>l});var t=JSON.parse('{"id":"assertions/soft-assertions","title":"Soft assertions","description":"Soft assertions let Pester collect every assertion failure in a test instead of stopping at the first one. Enable them globally with Should.ErrorAction = \'Continue\'.","source":"@site/docs/assertions/soft-assertions.mdx","sourceDirName":"assertions","slug":"/assertions/soft-assertions","permalink":"/docs/assertions/soft-assertions","draft":false,"unlisted":false,"editUrl":"https://github.com/pester/docs/edit/main/docs/assertions/soft-assertions.mdx","tags":[],"version":"current","frontMatter":{"title":"Soft assertions","description":"Soft assertions let Pester collect every assertion failure in a test instead of stopping at the first one. Enable them globally with Should.ErrorAction = \'Continue\'."},"sidebar":"docs","previous":{"title":"Should-BeEquivalent","permalink":"/docs/assertions/should-beequivalent"},"next":{"title":"Writing your own assertions (v6)","permalink":"/docs/assertions/writing-assertions"}}'),r=n(1987),o=n(7008);let i={title:"Soft assertions",description:"Soft assertions let Pester collect every assertion failure in a test instead of stopping at the first one. Enable them globally with Should.ErrorAction = 'Continue'."},a,l={},d=[{value:"What are soft assertions?",id:"what-are-soft-assertions",level:2},{value:"Enable soft assertions for every assertion",id:"enable-soft-assertions-for-every-assertion",level:2},{value:"Example",id:"example",level:3},{value:"Override the behavior on a single assertion",id:"override-the-behavior-on-a-single-assertion",level:2},{value:"Related",id:"related",level:2}];function c(e){let s={a:"a",admonition:"admonition",code:"code",em:"em",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.h2,{id:"what-are-soft-assertions",children:"What are soft assertions?"}),"\n",(0,r.jsxs)(s.p,{children:["By default a Pester assertion is a ",(0,r.jsx)(s.strong,{children:"hard assertion"}),": the first time it fails it throws, the test stops immediately, and any assertions that come after it never run. If a test contains several checks you only ever see the first failure, fix it, run again, see the next one, and so on."]}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.strong,{children:"Soft assertions"})," change that behavior. When soft assertions are enabled, a failing assertion is ",(0,r.jsx)(s.em,{children:"recorded"})," but does ",(0,r.jsx)(s.strong,{children:"not"})," stop the test. Pester keeps going, runs the remaining assertions, and then reports ",(0,r.jsx)(s.strong,{children:"all"})," of the collected failures together at the end of the test. This lets you put several related checks in a single ",(0,r.jsx)(s.code,{children:"It"})," and learn everything that is wrong in one run."]}),"\n",(0,r.jsxs)(s.p,{children:["Soft assertions are controlled by the ",(0,r.jsx)(s.code,{children:"Should.ErrorAction"})," configuration option:"]}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"Should.ErrorAction = 'Stop'"})," (the default) \u2014 hard assertions. The test fails on the first assertion error."]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"Should.ErrorAction = 'Continue'"})," \u2014 soft assertions. Failures are collected and reported at the end of the test."]}),"\n"]}),"\n",(0,r.jsxs)(s.p,{children:["This single setting is honoured by ",(0,r.jsx)(s.strong,{children:"both"})," assertion styles in Pester v6: the classic ",(0,r.jsx)(s.code,{children:"Should -Be"})," syntax and the new ",(0,r.jsxs)(s.a,{href:"./should-command",children:[(0,r.jsx)(s.code,{children:"Should-*"})," assertions"]}),". You do not have to opt in per assertion \u2014 turn it on once and every assertion in the run becomes soft."]}),"\n",(0,r.jsx)(s.h2,{id:"enable-soft-assertions-for-every-assertion",children:"Enable soft assertions for every assertion"}),"\n",(0,r.jsxs)(s.p,{children:["Soft assertions are enabled globally through the ",(0,r.jsx)(s.a,{href:"../usage/configuration",children:"configuration object"}),". Set ",(0,r.jsx)(s.code,{children:"Should.ErrorAction"})," to ",(0,r.jsx)(s.code,{children:"'Continue'"})," and every assertion in the run is collected instead of throwing on the first failure."]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-powershell",children:"$config = New-PesterConfiguration\n$config.Should.ErrorAction = 'Continue'\n\nInvoke-Pester -Configuration $config\n"})}),"\n",(0,r.jsxs)(s.p,{children:["You can achieve the same when running interactively (for example with ",(0,r.jsx)(s.code,{children:"F5"})," in VS Code) by setting ",(0,r.jsx)(s.code,{children:"$PesterPreference"}),". This is also handy in a PowerShell profile to make soft assertions the default for your session:"]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-powershell",children:"$PesterPreference = New-PesterConfiguration\n$PesterPreference.Should.ErrorAction = 'Continue'\n"})}),"\n",(0,r.jsx)(s.admonition,{type:"note",children:(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.code,{children:"Should.ErrorAction"})," defaults to ",(0,r.jsx)(s.code,{children:"'Stop'"}),", so assertions are hard unless you opt in to ",(0,r.jsx)(s.code,{children:"'Continue'"}),". See ",(0,r.jsx)(s.a,{href:"../usage/configuration",children:(0,r.jsx)(s.code,{children:"Should.ErrorAction"})})," in the configuration reference."]})}),"\n",(0,r.jsx)(s.h3,{id:"example",children:"Example"}),"\n",(0,r.jsxs)(s.p,{children:["With soft assertions enabled you can validate several properties of an object in a single ",(0,r.jsx)(s.code,{children:"It"})," and still get the full picture when more than one check fails:"]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-powershell",children:'BeforeAll {\n function Get-User {\n @{\n Name = "Jakub"\n Age = 31\n }\n }\n}\n\nDescribe "Get-User" {\n It "returns the expected user" {\n $user = Get-User\n\n $user | Should -Not -BeNullOrEmpty -ErrorAction Stop\n $user.Name | Should -Be "Tomas"\n $user.Age | Should -Be 27\n }\n}\n'})}),"\n",(0,r.jsxs)(s.p,{children:["Both the ",(0,r.jsx)(s.code,{children:"Name"})," and the ",(0,r.jsx)(s.code,{children:"Age"})," assertions fail, and both are reported at the end of the test:"]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{children:"Running tests from 1 files.\n\nRunning tests from 'C:\\t\\describe.Tests.ps1'\nDescribing Get-User\n [-] returns the expected user 124ms\n [0] Expected strings to be the same, but they were different.\n String lengths are both 5.\n Strings differ at index 0.\n Expected: 'Tomas'\n But was: 'Jakub'\n ^\n at $user.Name | Should -Be \"Tomas\", C:\\t\\describe.Tests.ps1:15\n [1] Expected 27, but got 31.\n at $user.Age | Should -Be 27, C:\\t\\describe.Tests.ps1:16\nTests completed in 286ms\nTests Passed: 0, Failed: 1, Skipped: 0, Inconclusive: 0, NotRun: 0\n"})}),"\n",(0,r.jsxs)(s.p,{children:["The same works with the new ",(0,r.jsx)(s.code,{children:"Should-*"})," assertions, because they honour ",(0,r.jsx)(s.code,{children:"Should.ErrorAction"})," too:"]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-powershell",children:'Describe "Get-User" {\n It "returns the expected user" {\n $user = Get-User\n\n $user | Should-NotBeNull -ErrorAction Stop\n $user.Name | Should-Be "Tomas"\n $user.Age | Should-Be 27\n }\n}\n'})}),"\n",(0,r.jsx)(s.h2,{id:"override-the-behavior-on-a-single-assertion",children:"Override the behavior on a single assertion"}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.code,{children:"Should.ErrorAction"})," sets the default for the whole run, but you can override it on any individual assertion with the ",(0,r.jsx)(s.code,{children:"-ErrorAction"})," parameter. This works for both ",(0,r.jsx)(s.code,{children:"Should -Be"})," and ",(0,r.jsx)(s.code,{children:"Should-*"})," assertions."]}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.code,{children:"-ErrorAction Stop"})," \u2014 make a single assertion hard even when soft assertions are enabled globally. Use it to guard a ",(0,r.jsx)(s.strong,{children:"precondition"}),": if that check fails, there is no point continuing, so fail the test immediately. In the example above, ",(0,r.jsx)(s.code,{children:"Should -Not -BeNullOrEmpty -ErrorAction Stop"})," stops the test when ",(0,r.jsx)(s.code,{children:"$user"})," is ",(0,r.jsx)(s.code,{children:"$null"}),", because inspecting ",(0,r.jsx)(s.code,{children:".Name"})," and ",(0,r.jsx)(s.code,{children:".Age"})," on a null object would be meaningless."]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-powershell",children:"# Soft assertions are on globally, but this precondition hard-fails the test.\n$user | Should -Not -BeNullOrEmpty -ErrorAction Stop\n"})}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.code,{children:"-ErrorAction Continue"})," \u2014 make a single assertion soft even when the run defaults to hard assertions (",(0,r.jsx)(s.code,{children:"Should.ErrorAction = 'Stop'"}),"). The failure is collected and the test keeps going."]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-powershell",children:'# Default run (hard assertions), but collect this failure instead of stopping.\n$user.Name | Should -Be "Tomas" -ErrorAction Continue\n'})}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(s.h2,{id:"related",children:"Related"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:[(0,r.jsxs)(s.a,{href:"./should-command",children:[(0,r.jsx)(s.code,{children:"Should"})," assertions"]})," \u2014 the classic ",(0,r.jsx)(s.code,{children:"Should -Be"})," and new ",(0,r.jsx)(s.code,{children:"Should-*"})," syntaxes that soft assertions apply to."]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsxs)(s.a,{href:"../usage/configuration",children:["Configuration \u2014 ",(0,r.jsx)(s.code,{children:"Should.ErrorAction"})]})," \u2014 the full configuration reference."]}),"\n"]})]})}function h(e={}){let{wrapper:s}={...(0,o.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(c,{...e})}):c(e)}},7008(e,s,n){n.d(s,{R:()=>i,x:()=>a});var t=n(1763);let r={},o=t.createContext(r);function i(e){let s=t.useContext(o);return t.useMemo(function(){return"function"==typeof e?e(s):{...s,...e}},[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),t.createElement(o.Provider,{value:s},e.children)}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.