FlowChartCore icon indicating copy to clipboard operation
FlowChartCore copied to clipboard

Write tests ...

Open LxLeChat opened this issue 5 years ago • 24 comments

C# tests PS Tests

LxLeChat avatar Oct 12 '20 13:10 LxLeChat

J'ai regardé comment créer des tests de dev rapido en ne spécifiant que des déclarations d'instructions , un aperçu avec Pester 5.0.4: image

La déclaration :

$Break4=New-CodeUseCase 'Break ElseIF without Break' @'
    $grade = 92
    if ($grade -ge 90) { "Grade A"}
    elseif ($grade -ge 80) { "Grade B"} 
'@

Le code Pester à proprement parler :

Describe "FlowChartCode " {

  Context "When there is no violation" {
      
        #On cherche à savoir si un type de construction est géré ou pas.
       It "<Name>." -TestCases $CodeUseCases {
        param($Name,$Code)         

        {
           $sb=[scriptblock]::Create($Code)
           Test-Statement @Parameters -FileName $Name -ScriptBlock $SB 
        } | Should -Not -Throw
      }
   }
}

Ceci serait dupliqué dans chaque répertoire (exemple : \Tests\Dev), un pour Break (\Tests\Dev\Break), un pour If etc Seule la déclaration du nom de variable serait différente :

$IF1=New-CodeUseCase 'IF ElseIF without Break' @'
    $grade = 92
    if ($grade -ge 90) { "Grade A"}
    elseif ($grade -ge 80) { "Grade B"} 
'@

Ensuite on recherche les déclarations 'normées' et on génère le tableau de hashtable en tant que jeu de test :

$CodeUseCases=@(
    Foreach ($Number in 1..$NumberOfUseCase) 
    { 
        #todo SI la variable existe
        $Value=(Get-Variable "IF$Number").Value #Ou IF ou Catch etc
        $value|ConvertTo-Hashtable
    }
)

Je continue de regarder ce point afin de m'assurer que ce n'est pas une bonne mauvaise idée. Ceci ne remplacera pas les tests fonctionels

LaurentDardenne avatar Oct 17 '20 19:10 LaurentDardenne

humm j'ai un peu de retard sur pester ... pas encore regarder comment fonctionnait le nouveau module depuis le breaking change de la 5.0 du coup new-codeusecase ca me parle pas, mais ça à l air assez parlant comme ça :)

LxLeChat avatar Oct 17 '20 20:10 LxLeChat

pas encore regarder comment fonctionnait le nouveau module depuis le breaking change de la 5.0

Le recherche du code perso dans un test a changé (rapido BeforeAll pour le partage de code), la syntaxe des assertions not be en -not -be et le formatage de sortie par défaut et d'autres trucs. Mais pour un usage basique tu passes un peu de temps à retrouver tes marques... Je crois qu'il une fonction d'aide à la conversion.

du coup new-codeusecase ca me parle pas, mais ça à l air assez parlant comme ça :)

A l'origine je voulais essayer qq chose comme ça, en ayant à l'esprit la progression du code :

$Break1=New-CodeUseCase 'Break absent' @'
    $grade = 92
'@

$Break2=New-CodeUseCase 'Break IF without Break' @'
    $Break1
    if ($grade -ge 90) { "Grade A"}
'@

$Break3=New-CodeUseCase 'Break IFElse without Break' @'
    $Break2
    Else {"Grade B"}
'@

Mais au bout de 10 cas on a peut de mal à savoir ce que l'on manipule.

Le New-CodeUseCase existe car je n'ai pas réussi à redéfinir la méthode ToString sur une hashtable

$h=@{
    Name='test'
    Code='  if ($grade -ge 90) { "Grade A"}'
   }|
  Add-Member -MemberType ScriptMethod -name ToString { $This.Code} -Force -PassThru
"$h"
#System.Collections.Hashtable
"$($h.tostring())"
#if ($grade -ge 90) { "Grade A"}'

Mais j'ai peut être loupé une marche...

Je vais simplifier en :

Function UseCase{
 #New-PSCustomObjectFunction -Noun CodeUseCase -Parameters Name,Code -file
    param(
         [Parameter(Mandatory=$True,position=0)]
        $Name,
          [Parameter(Mandatory=$True,position=1)]
        $Code
    )
  return $PSBoundParameters
}

$CodeUseCases=@(
 UseCase 'Break IFElse without Break' @'
   $grade = 92
   elseif ($grade -ge 80) { "Grade B"} 
'@
 # UseCase ...
)

LaurentDardenne avatar Oct 18 '20 12:10 LaurentDardenne

$h=@{
    Name='test'
    Code={if($a){"x"}}
   }

non ? du coup h.code et hop ! surement raté klk chose aussi xD

LxLeChat avatar Oct 18 '20 12:10 LxLeChat

Oui tout à fait. Je voulais éviter de saisir à chaque fois le nom des clés...

LaurentDardenne avatar Oct 18 '20 15:10 LaurentDardenne

En attendant une PR :

#FlowChartCore init
$ModulePath='C:\Users\Laurent\Downloads\FlowChartCore\Code\bin\Debug\netstandard2.0'

if (-Not (Test-Path Env:GRAPHVIZ_DOT))
{ $Env:GRAPHVIZ_DOT='C:\Tools\Graphviz\bin' }

unblock-File "$ModulePath\DotNetGraph.dll"
unblock-File "$ModulePath\FlowchartCore.dll"
 #first time, close and open PS console
Import-Module "$ModulePath\FlowchartCore.dll"

Function New-CodeUseCase{
#New-PSCustomObjectFunction -Noun CodeUseCase -Parameters Name,Code -file
param(
     [Parameter(Mandatory=$True,position=0)]
    [String] $Name,

     [Parameter(Mandatory=$True,position=1)]
    [ScriptBlock] $Code
)

  @{
    Name=$Name;
    Code=$Code;
   }
}

$CodeUseCases=@(
    #Todo cas sans résultat
#  New-CodeUseCase 'Break absent' {
#     $grade = 92
# }

 New-CodeUseCase 'Break IF without Break' {
   $grade = 92
   if ($grade -ge 90) { "Grade A"}
}

 New-CodeUseCase 'Break IFElse without Break' {
    $grade = 92
    if ($grade -ge 90) { "Grade A"}
    Else {"Grade B"}
}

 New-CodeUseCase 'Break ElseIF without Break' {
    $grade = 92
    if ($grade -ge 90) { "Grade A"}
    elseif ($grade -ge 80) { "Grade B"} 
}

 New-CodeUseCase 'Break at the end of code' {
    $grade = 92
    if ($grade -ge 90) { "Grade A"}
    Break
}

 New-CodeUseCase 'Break inside IF block' {
  $grade = 92
  if ($grade -ge 90) { "Grade A";Break}
}

#todo Token IF
 New-CodeUseCase 'Break IF ElseIF Else' {
    $grade = 92
    if ($grade -ge 90) { "Grade A" }
    elseif ($grade -ge 70)  { "Grade C"}
    else { "Grade D"}
}

#NOK
 New-CodeUseCase 'Break IF ElseIF' {
    $grade = 92
    if ($grade -ge 90) { "Grade A" }
    elseif ($grade -ge 70)  { "Grade C"}
 }

#NOK
 New-CodeUseCase 'Break IF inside For loop' {
    for ($i = 1; ; ++$i)
    {
        if ($i * $i -gt 50)
        {
            Get-ChildItem
        }
    }
}
)

# BeforeAll { 
#     $script:Parameters=@{
#         AsText=$false
#         NoDisplay=$true
#         Strict=$true
#     }
#     #F°
# }

Describe "FlowChartCode " {
    Context "When there is no violation" {
        #On cherche à savoir si un type de construction est géré ou pas.
        #Chacune des ces constructions doit renvoyer un résultat
       It "<Name>." -TestCases $CodeUseCases {
        param($Name,$Code)         
         $script:Result=$script:OutView=$script:OutViewAsText=$null

          #Pas d'exception
         {   [System.Diagnostics.CodeAnalysis.SuppressMessage('PSUseDeclaredVarsMoreThanAssigments', '')]
           $script:Result=Find-FLowChartNodes -ScriptBlock $Code } | Should -Not -Throw
          
          #Le résultat doit être renseigné
         $script:Result |Should -Not -BeNullOrEmpty
         
         {   [System.Diagnostics.CodeAnalysis.SuppressMessage('PSUseDeclaredVarsMoreThanAssigments', '')]
            $script:OutView=New-FLowChartGraph -Nodes $script:Result} | Should -Not -Throw
         
        $script:OutView |Should -Not -BeNullOrEmpty
         # Même chose mais avec -CodeAsText
         {   [System.Diagnostics.CodeAnalysis.SuppressMessage('PSUseDeclaredVarsMoreThanAssigments', '')]
           $script:OutViewAsText=New-FLowChartGraph -Nodes $script:Result -CodeAsText} | Should -Not -Throw
         
           $script:OutViewAsText|Should -Not -BeNullOrEmpty
      }
   }
}

Il reste des chemins codés en dur à modifier ( avec un module on pourrait s'en affranchir). La gestion de la variable Env:GRAPHVIZ_DOT est a envisager dans le module (+ un loader ici), ainsi on a une indirection que l'on peut utiliser dans des scripts de démos. Et je dois vérifier si la portée script est la solution pour le partage de code ou si l'ecriture du It à changé. Encore une fois ce test est pour le debug (là tout est dans tout).

LaurentDardenne avatar Oct 22 '20 18:10 LaurentDardenne

top!

LxLeChat avatar Oct 22 '20 18:10 LxLeChat

Par contre pourquoi l'histoire du path de graphviz @LaurentDardenne, je ne vois pas en quoi ça peut nous servir.

il faut la dernière version de pester ? ok j'ai la 3.4 -_- completement en retard !

LxLeChat avatar Oct 25 '20 16:10 LxLeChat

ok top! je galere avec pester -- impossible d installer la derniere version ... j'ai réussi à virer celle qui vient par defaut la 3.4 mais l'install-module foncitonne, mais le module n'apparait pas -- grummmmmble

LxLeChat avatar Oct 25 '20 16:10 LxLeChat

je galere avec pester

Peut être as-tu + chemins où il est installé, le mode verbose donne qq infos.

Pour l'usage de graphviz :

Write-FUGraph -InputObject $r -ShowGraph
export-PSGraph : Could not find GraphViz installed on this system. Please run 'Install-GraphViz' to install the needed
binaries and libraries. This module just a wrapper around GraphViz and is looking for it in the following paths:
C:\Program Files\NuGet\Packages\Graphviz*\dot.exe or C:\program files*\GraphViz*\bin\dot.exe or /usr/local/bin/dot or
/usr/bin/dot. Optionally pass a path to your dot.exe file with the GraphVizPath parameter
Au caractère C:\Users\Laurent\Downloads\PSFunctionExplorer\PSFunctionExplorer\PSFunctionExplorer.psm1:348 : 26
+                 $graph | export-PSGraph @ExportAttrib

Il existe une dépendance mais pas de contrôle sur son existence/accès

LaurentDardenne avatar Oct 25 '20 16:10 LaurentDardenne

Et surtout le module PSGraph fige le chemin d'installation...

LaurentDardenne avatar Oct 25 '20 16:10 LaurentDardenne

J'ai supprimé ma réponse sur l'histoire du path, j'ai oublié que les liens pointaient sur le référentiel cité...

LaurentDardenne avatar Oct 25 '20 16:10 LaurentDardenne

oh petard .. j'utilise tellement plus windows powershell sur ma machine ... il fallait en passer par la pour installer le module ... du coup j'ai un fail sur [-] Switch -File 👍 MERCIIIIIIIIII @LaurentDardenne !!! ça défonce tout ça !

du coup faut que je check comment t as fait mais ça à l air top ! jamais écris des tests comme ça !!! very interessant !

LxLeChat avatar Oct 25 '20 17:10 LxLeChat

par contre je comprends pas le test foire, mais quand je le fais manuellement ça fonctionne .. ! étrange

LxLeChat avatar Oct 25 '20 17:10 LxLeChat

Je regarde ça.

LaurentDardenne avatar Oct 25 '20 17:10 LaurentDardenne

Peut être un pb d'encodage de fichier... En ajoutant ceci dans le test cela fonctionne:

   param($Name,$Code)         
        $code=[scriptblock]::Create("$code")

repro:

cd ..\FlowChartCore\Test\dev
$r=. .\Switch.UseCases.ps1
$Result=Find-FLowChartNodes -ScriptBlock ($r[-2].code)
$OutView=New-FLowChartGraph -Nodes $Result -CodeAsText
#New-FLowChartGraph : L'index et la longueur doivent faire référence à un emplacement situé dans la chaîne.
#Nom du paramètre : length

Le référentiel est à jour de ton côté ? Que l'on utilise la même version.

LaurentDardenne avatar Oct 25 '20 18:10 LaurentDardenne

Pour retrouver le nœud posant pb:

$Result=Find-FLowChartNodes -ScriptBlock ($r[-2].code)
$result[1].Children|%{write-host "$_";$_}|% {New-FLowChartGraph -Nodes $_ -CodeAsText}
#FlowChartCore.SwitchCaseNode

#New-FLowChartGraph : L'index et la longueur doivent faire référence à un emplacement situé dans la chaîne.
#Nom du paramètre : length

#FlowChartCore.SwitchCaseNode
#digraph "a" {
...

Directement :

New-FLowChartGraph -Nodes $result[1].Children[0] -CodeAsText
  • [x] Si j'ai le temps je regarderai demain avec VS.

LaurentDardenne avatar Oct 25 '20 19:10 LaurentDardenne

Vérifie si la classe ContinueNode doit redéclarer la méthode OffSetScriptBlockEnd.

LaurentDardenne avatar Oct 25 '20 19:10 LaurentDardenne

effectivement, il manquait un appel de méthode. j'ai corrigé et poussé

LxLeChat avatar Oct 26 '20 14:10 LxLeChat

et poussé

Dans la branche Dev est-ce à dessein ?

LaurentDardenne avatar Oct 26 '20 14:10 LaurentDardenne

j'ai mergé avec la master

LxLeChat avatar Oct 26 '20 15:10 LxLeChat

Ok, les tests réussissent dorénavant.

LaurentDardenne avatar Oct 26 '20 16:10 LaurentDardenne

Il faudrait modifier le nom du fichier sur cette ligne . Il n'était pas dans la branche Dev.

Et pour rappel ce fichier ne contient pas de tests fonctionnel. Il devrait plutôt être configuré ainsi :

Invoke-Pester -Path .\Test -Output Detailed -ExcludeTagFilter 'DevUseCases'

Et si tu veux le laisser, dans ce cas renommer le tag en 'UseCases' et simplifier :

Invoke-Pester -Path .\Test -Output Detailed 

LaurentDardenne avatar Oct 31 '20 09:10 LaurentDardenne

C# tests

Au cas où j'ai trouvé ceci :

LaurentDardenne avatar Nov 02 '20 13:11 LaurentDardenne