Running Automated Tests From PowerShell

Automating your automated tests is just as important as creating and maintaining them, you want to be able to run your tests at least once a day and ideally multiple times a day or even after every check-in.

All we have to invoke these automated tests is PowerShell but there’s another challenge because the automated tests require a user interface and the Invoke-NAVCodeunit cmdlet does not support this.

When a codeunit is invoked by the cmdlet GUIALLOWED is false, and if the executed code takes actions based on GUIALLOWED  (for example display a message) the handler function will not be executed and you’ll get an error:

With the Invoke-NAVCodeunit out of our way we can start looking for a new approach, hey wait remember Waldo’s Start-NAVApplicationObjectInWindowsClient cmdlet!?
I did, and it does almost everything we want, we can now start our object of choice and run our tests.
BUT… we have no idea when our tests are finished and the client session will remain open forever,
I thought about using the STOPSESSION function in NAV but that leaves the client process open with an error on the screen 🙁
Let’s start with solving the first problem by creating a similar function but then take advantage of the startup parameters of the RTC, by using the -consolemode parameter which is handy for running tests ‘without’ (you do actually see the ui) a user interface.

With this in place we can focus on the next problem (determining when our tests are finished and close the session) which we’ve pretty much solved by the -consolemode parameter.
All what’s left is making sure the started process waits for the exit, by using the $Process.WaitForExit() function.
Our function will then look like this:

[powershell]</pre>
<pre>function Start-NAVApplicationObjectInConsoleMode
{
[cmdletbinding()]
param(
[string]$ServerName=[net.dns]::Gethostname(),
[int]$Port=7046,
[Parameter(Mandatory=$true)][String]$ServerInstance,
[Parameter(Mandatory=$true)][String]$CompanyName,
[string]$Tenant=’default’,
[Parameter(Mandatory=$true)][string]$ClientExecutablePath,
[Parameter(Mandatory=$true)][ValidateSet(‘Table’,’Page’,’Report’,’Codeunit’,’Query’,’XMLPort’)][String]$ObjectType,
[Parameter(Mandatory=$true)][int]$ObjectID,
[switch]$PassThru,
[switch]$WaitForExit
)
$ConnectionString = "DynamicsNAV://$Servername" + ":$Port/$ServerInstance/$Companyname/Run$ObjectType"+"?$ObjectType=$ObjectID&amp;tenant=$tenant"
$Parameters = "-consolemode " + "`"$ConnectionString`""
Write-Verbose -Message "Starting $ClientExecutablePath with Parameters $Parameters…"
$Process = Start-Process -FilePath $ClientExecutablePath -ArgumentList $Parameters -PassThru
if($WaitForExit){
Write-Verbose -Message "Waiting for the client process to finish…"
$Process.WaitForExit()
}

if($PassThru){
Write-Output -$Process
}
}
[/powershell]

I’ve wrapped everthing up in an AL extension and a simple PowerShell function called Start-NAVAutomatedTests.
Feel free to get your hands on the code by grabbing it from my GitHub repo, pull requests are more than welcome!

2 Comments

Stijn B · September 15, 2018 at 9:48 am

Hello Richard,

Does this still work? I can’t get this running.

Thanx

Stijn B · September 29, 2018 at 9:08 am

Hello Richard,

Does this still apply when running inside a container?

Leave a Reply

Your email address will not be published. Required fields are marked *