Pide tu presupuesto ya!
He estado usando Pester durante mucho tiempo de forma intermitente. Siempre he estado obsesionado con garantizar la confiabilidad en mi código de PowerShell. despues de escribir El libro de Pester y al mencionar algunas de las metodologías que utilicé con Pester v4 que presentaré en esta publicación de blog, desde entonces aprendí que Pester v5 hace mi trabajo mucho más fácil.
Verá, cuando crea pruebas con Pester, sus opciones son ilimitadas como cualquier cosa en PowerShell. Puedes estructurar las pruebas de un millón de maneras diferentes porque eres libre de escribir cualquier PowerShell que quieras dentro de las pruebas. Pero eso no siempre es algo bueno. Necesita algún tipo de metodología o forma general de construirlos. Esta es mi forma preferida; pruebas basadas en datos.
En un conjunto de pruebas típico de Pester, normalmente se crea un it bloque para cada afirmación que necesites hacer. Tu creas un it bloquear a:
Para cada uno de estos escenarios, se crea un it bloquee con un nombre y proporcione todos los parámetros para pasar al script para realizar la acción que está probando.
Por ejemplo:
describe 'some script' {
it 'creates a thing given the parameters to do so' {
./thing.ps1 -Create -Name 'xxx' | should -BeTrue
}
it 'sets a thing given the parameters to do so' {
./thing.ps1 -Set -Name 'xxx' | should -BeTrue
}
it 'removes a thing given the parameters to do so' {
./thing.ps1 -Remove -Name 'xxx' | should -BeTrue
}
}
Me parece bien. Ha definido cada escenario, ha proporcionado los parámetros necesarios y está afirmando que el script regresa. true. Esta es una forma común de crear pruebas, pero este enfoque siempre me molestó. Sentí como si estuviera duplicando código innecesariamente cuando podía almacenar cosas en una matriz.
¡Resulta que podría!
En Pester v5, puede crear pruebas que son esencialmente parte de un bucle foreach que pasa conjuntos de parámetros a la vez a bloques y hace que Pester ejecute la prueba para cada conjunto de parámetros.
En el ejemplo anterior, estás utilizando tres conjuntos de parámetros diferentes para el mismo script. Esos conjuntos se pueden definir en una serie de tablas hash.
$paramSets = @(
@{
Create = $true
Name = 'xxx'
}
{
Set = $true
Name = 'xxx'
}
{
Remove = $true
Name = 'xxx'
}
)
Una vez que estén todos almacenados en esa matriz, puede usar Pester v5 foreach función para “unirlos” a un bloque como un it bloquear.
it 'whatever test name here' -ForEach $paramSets {
## The parameter set is now represented as the current iteraction in the foreach loop
$paramSet = $_
& "./thing.ps1" @paramSet | should -BeTrue
}
Cuando ejecute la prueba Pester ahora, pasará cada parámetro establecido en la matriz al it bloquear la ejecución de tres pruebas con solo definir una única it ¡bloquear! Mucho más eficiente.
Todo desarrollador de software conoce el concepto de método SECO. En pocas palabras, simplemente no se trata de repetirse. Significa no duplicar código tanto como sea posible. ¿Por qué? Por mantenibilidad.
Imagine que necesita crear 100 registros de base de datos y ve un código como este:
New-Record -Table 'xxxx' -Fields @{ name = 'whatever1' }
New-Record -Table 'xxxx' -Fields @{ name = ' whatever2' }
New-Record -Table 'xxxx' -Fields @{ name = ' whatever3' }
New-Record -Table 'xxxx' -Fields @{ name = ' whatever4' }
New-Record -Table 'xxxx' -Fields @{ name = ' whatever5' }
New-Record -Table 'xxxx' -Fields @{ name = ' whatever6' }
## to 100
Son 100 líneas de código que podrían reducirse fácilmente a cuatro, simplificando el código y haciéndolo mucho más fácil de mantener.
$whateverCount = 100
for ($i = 1; $i -lt $whateverCount; $i++) {
New-Record -Table 'xxxx' -Fields @{ name = "whatever$i" }
}
No sólo simplificó el código, sino que también puede crear un millón de registros simplemente cambiando un número. Esto es SECO.
Entonces, ¿por qué algunas personas escriben pruebas de Pester como ésta?
describe 'some script' {
it 'creates a thing given the parameters to do so' {
./thing.ps1 -Create -Name 'xxx'
}
it 'sets a thing given the parameters to do so' {
./thing.ps1 -Set -Name 'xxx'
}
it 'removes a thing given the parameters to do so' {
./thing.ps1 -Remove -Name 'xxx'
}
}
Si eres nuevo en las pruebas o incluso lees la documentación de Pester, verás que muchos de los ejemplos están estructurados de esta manera. ¡Y eso no tiene absolutamente nada de malo! Si está creando un pequeño puñado de pruebas para scripts simples, funciona bien. Pero siempre me molestó.
Aunque no es tan obvio, básicamente estás haciendo lo mismo; funcionalidad de duplicación. Pero hacer que las pruebas de Pester sean SECO no es tan simple como introducir un for bucle y agregando una sola variable. Debes estructurarlos de manera que utilices el lenguaje específico de dominio (DSL) de Pester.
Escribir pruebas, como el código de PowerShell, es verdaderamente un arte. Hay muchas formas de realizar la misma acción, cada una con ventajas e inconvenientes. Al escribir pruebas para scripts de PowerShell de gran tamaño, puede volverse loco y probar cada… pequeño… minuto…detalle. O bien, puede seguir la ruta ágil y crear un pequeño conjunto de pruebas que cubran la mayoría de las situaciones y simplemente agregar pruebas a medida que descubra cómo falla el script cuando se usa en estado salvaje.
¿Cómo se llega a un acuerdo entre ambos? ¡Pruebas basadas en datos!
Con las pruebas basadas en datos, puede definir todas y cada una de las formas en que se puede llamar a su script definiendo cada conjunto de parámetros posible en una matriz con anticipación.
Ahora que ya está familiarizado con las pruebas basadas en datos, cubramos una metodología que uso personalmente para garantizar una cobertura de prueba manejable para mi código de PowerShell.
$mandatoryParameters = @{
EndpointApiKey = (ConvertTo-SecureString -String 'apikeyhere' -AsPlainText -Force)
PasswordName = 'namehere'
NewPassword = (ConvertTo-SecureString -String 'passwordhere' -AsPlainText -Force)
}
Si tiene parámetros obligatorios, sabrá que tendrá que pasarlos al script para cada ejecución, así que defínalos primero.
$mandatoryParameters = @{
EndpointApiKey = (ConvertTo-SecureString -String 'apikeyhere' -AsPlainText -Force)
PasswordName = 'namehere'
NewPassword = (ConvertTo-SecureString -String 'passwordhere' -AsPlainText -Force)
}
$parameterSets = @(
@{
label = 'all mandatory parameters'
parameter_set = $mandatoryParameters
}
@{
label = 'specific EndpointUri'
parameter_set = $mandatoryParameters + @{
'EndpointUri' = 'https://endpointhere'
}
}
)
Observe que en lugar de replicar los parámetros obligatorios, simplemente agrego más parámetros al conjunto de parámetros en el parameter_set llave.
context bloque que se aplicará a todas las situaciones.context 'Global' {
## do whatever in here that depends on the script
}
context bloque para cada situación ambiental.context 'when the file exists' {
}
context 'when the file does not exist' {
}
context 'when the file exists' {
$ctxParameterSets = $parameterSets.where({ $_.parameter_set.ContainsKey('EndpointUri'') })
}
it bloques que representan cualquier prueba que necesite realizar.it 'passes the expected URI to the API to update the password : <_.label>' -ForEach $parameterSets {
& "$PSScriptRootthing.ps1" @parameter_set | should....
}
En Pester v5, puedes insertar una cadena dentro del nombre de la prueba. Utilizo una clave de la matriz definida primero llamada etiqueta para inyectar una descripción de cuál es ese conjunto de parámetros.
Una vez que haya creado todas las pruebas de esta manera, simplemente puedo agregar conjuntos de parámetros a la matriz, lo que ejecutará automáticamente todas las pruebas que necesito.
Leave a comment