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

Write tests ... #13

Open
LxLeChat opened this issue Oct 12, 2020 · 24 comments
Open

Write tests ... #13

LxLeChat opened this issue Oct 12, 2020 · 24 comments
Labels
enhancement New feature or request

Comments

@LxLeChat
Copy link
Owner

C# tests
PS Tests

@LaurentDardenne
Copy link
Contributor

LaurentDardenne commented Oct 17, 2020

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

@LxLeChat
Copy link
Owner Author

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 :)

@LaurentDardenne
Copy link
Contributor

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 ...
)

@LxLeChat LxLeChat added the enhancement New feature or request label Oct 18, 2020
@LxLeChat
Copy link
Owner Author

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

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

@LaurentDardenne
Copy link
Contributor

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

@LaurentDardenne
Copy link
Contributor

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).

@LxLeChat
Copy link
Owner Author

top!

@LxLeChat
Copy link
Owner Author

LxLeChat commented Oct 25, 2020

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
Copy link
Owner Author

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

@LaurentDardenne
Copy link
Contributor

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
Copy link
Contributor

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

@LaurentDardenne
Copy link
Contributor

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

@LxLeChat
Copy link
Owner Author

LxLeChat commented Oct 25, 2020

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
Copy link
Owner Author

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

@LaurentDardenne
Copy link
Contributor

Je regarde ça.

@LaurentDardenne
Copy link
Contributor

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
Copy link
Contributor

LaurentDardenne commented Oct 25, 2020

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
  • Si j'ai le temps je regarderai demain avec VS.

@LaurentDardenne
Copy link
Contributor

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

@LxLeChat
Copy link
Owner Author

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

@LaurentDardenne
Copy link
Contributor

et poussé

Dans la branche Dev est-ce à dessein ?

@LxLeChat
Copy link
Owner Author

j'ai mergé avec la master

@LaurentDardenne
Copy link
Contributor

Ok, les tests réussissent dorénavant.

@LaurentDardenne
Copy link
Contributor

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
Copy link
Contributor

C# tests

Au cas où j'ai trouvé ceci :

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants