14
EPAM SYSTEMS Windows PowerShell in Software Testing Some examples of how to use Windows PowerShell in daily software testing tasks Tsimafei Avilin 6/2/2015

Windows PowerShell in Software Testing

Embed Size (px)

Citation preview

EPAM SYSTEMS

Windows PowerShell in Software Testing

Some examples of how to use Windows PowerShell in daily software testing tasks

Tsimafei Avilin

6/2/2015

Table of Contents

Introduction...........................................................................................................................................2

Windows PowerShell ISE........................................................................................................................3

Checking the Service status with Windows PowerShell.........................................................................4

Checking Event Viewer logs with Windows PowerShell.........................................................................7

Checking XML data with Windows PowerShell....................................................................................10

Checking database values with Windows PowerShell..........................................................................11

IntroductionSometimes you don’t have enough time or the necessary experience in developing some classes in MS Visual Studio for basic software testing. Especially when manual testing includes a lot of simple tasks: checking pre- or post-requisites, configuration files, installation-related files, database values, services statuses or logs in Event Viewer, etc. All of these tasks can be easily done with Windows PowerShell. Using it together with any continuous integration system (like TeamCity, Jenkins, etc.) can make the software testing process better, faster, more independent and frequent. It helps you to quickly check all described checkpoints or perform testing tasks on distributed servers.

In a few words – Windows PowerShell is a task-based command-line shell and scripting language (*.ps1 – is a Windows PowerShell file type). Built on the .NET Framework, Windows PowerShell provides full access to COM and WMI objects.

Official information about Windows PowerShell and cmdlets can be found on the official portal here.

Jenkins PowerShell Plugin – “Integrates with Windows PowerShell by allowing you to directly write PowerShell scripts into the text box in Jenkins. Other than that, this plugin works pretty much like the standard shell script support.” link ; some examples can be found here and here

Note: while running .ps1 scripts, you may encounter some errors. See below how to fix them:

Error Solution

“…PS C:\temp> .\1.ps1 File C:\temp\1.ps1 cannot be loaded because the execution of scripts is disabled on this system. Please see «get-help about_signing» for more details….”

Update the Execution Policy level in [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell].

"…The file C:\TEMP\> .\1.ps1 cannot be loaded. The signature of the certificate cannot be verified…"

Sign in your script, create a new certificate or use an existing one.

Useful links:

PowerShell unit testing framework by Jakub Jareš

UI Automation with Windows PowerShell by Dr. James McCaffrey

Web UI Automation with Windows PowerShell by Dr. James McCaffrey

Windows PowerShell ISEYou can also try to use the GUI version (Windows PowerShell ISE) to create, run and edit scripts:

To run PowerShell ISE:

Do one of the following:

o Go to Start -> Accessories -> Windows PowerShell -> Windows PowerShell ISE.

o Or go to Start, open the command line and run powershell_ise.exe.

Checking the Service statusImagine you have to check the statuses of services on distributed servers after a new build is deployed. The task also includes checking that the services are live on these servers and their statuses are “Running”.

Note: keep in mind that the status and service name to be checked by the script may differ from the ones displayed in the image below.

See below a script example (update the values highlighted in yellow):

# this program connects to the server and checks the services# to execute this script you can right-click on CheckServices.ps1 file and select 'Run with PowerShell'# or you can navigate from PoweShell to folder with CheckServices.ps1 file and execute .\CheckServices.ps1#You can update this script for your environment# 1. Credentials to login to server: $User - user login; $PWord - user password# 2. Test cases names: add test case names like $TestCases = @{$"name_<name>" = "<test case name>";...}# 3. Server names: add IP address to $Servers hash array like $Servers = @{$"name_<name>" = "<IP server>";...}# 4. Services DisplayNames: add DisplayNames sevices to $Services hash array like $Services = @{$"name_<name>" = @('<DisplayName1>','<DisplayName2>',...);...} create array like $<name>_services = @('<service DisplayName 1>','<service DisplayName 2>',..'<service DisplayName N>')

#Credentials$User = "Minsk\sergei.pupkin"$PWord = ConvertTo-SecureString –String "qwaszx12" –AsPlainText -Force$Credential = New-Object –TypeName System.Management.Automation.PSCredential –ArgumentList $User, $PWord#Test case names $TestCases = @{"name_sql01"="003_SQL Services";"name_biz01"="005_BT Services";"name_hub01"="008_DH Services";"name_app02"="012_SRS Services";"name_app01"="014_EU Services"}#Server names$Servers = @{"name_sql01"="10.51.118.118";"name_biz01"="10.51.118.121";"name_hub01"="10.51.118.123";"name_app02"="10.51.118.120";"name_app01"="10.51.118.119"}#Services DisplayNames$Services = @{"name_sql01"= @('SQL Server Agent (MSSQLSERVER)', 'SQL Server (MSSQLSERVER)');"name_biz01"= @('BizTalk Service BizTalk Group : BizTalkServerApplication', 'BizTalk Service BizTalk Group : BizTalkServerApplication64', 'BizTalk Service BizTalk Group : BizTalkServerApplicationReceive64', 'BizTalk Service BizTalk Group : Tracking64', 'Enterprise Single Sign-On Service', 'QCSI Master Service', 'Rule Engine Update Service');"name_hub01"= @('Appl Master Service', 'Appl Aggregation Service', 'Appl Orphan Retry', 'Enterprise Distribution Hub');"name_app02"= @('Serv Master Service', 'SQL Server Reporting Services (MSSQLSERVER)');"name_app01"= @('Serv Master Service', 'Enterprise Execution Unit')}#Find and check servicesForeach ($TC in $TestCases.keys){ $SS = $Servers.$TC $count_of_services = $Services.$TC.count write-host ("Test case: "+ $TestCases.$TC + ". Server " + $SS + " should have " + $count_of_services + " services.") -foregroundcolor "Cyan" $getALLservices = Get-WmiObject -computer $SS -credential $Credential Win32_Service $i = 0 ForEach ($DisplayName in $Services.$TC) { $getservice = $getALLservices | Where {$_.DisplayName -eq $DisplayName}

if ($getservice) { if ($getservice | Where {$_.State -eq "Running"}) { write-host ("PASSED: The service " + $DisplayName + " exists and is Running.") $i = $i + 1 } else { write-host ("FAILED: The service " + $DisplayName + " exists but is NOT Running.") -foregroundcolor "Red" } } else { write-host ("FAILED: The service " + $DisplayName + " does NOT exist.") -foregroundcolor "Red" } } If ($i -eq $count_of_services) { write-host ("Test case: " + $TestCases.$TC + " is PASSED") -foregroundcolor "Green" " " } else { write-host ("Test case: " + $TestCases.$TC + " is FAILED") -foregroundcolor "Red" " " } "======="}"The script is completed"write-host "Press any key to continue..."[void][System.Console]::ReadKey($true)"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"

Checking Event Viewer logsThe next common testing task that we can automate with PowerShell is checking logs in Event Viewer. Sometimes custom logs are also stored in Event Viewer, so to get these logs remotely use the script below. You can update it to change the time within the logs to be obtained, and the type of logs.

See below a script example (update the values highlighted in yellow):

Clear-Host# this program connects to the server and checks Event Logs# to execute this script you can right-click the CheckEvents.ps1 file and select 'Run with PowerShell'# or you can navigate from PowerShell to the folder with the CheckEvents.ps1 file and execute .\CheckEvents.ps1#You can update this script for your environment# 1. Credentials to login server: $User - user login; $PWord - user password# 2. Test cases names: add test case names like $TestCases = @{$"name_<name>" = "<test case name>";...}# 3. Server names: add IP address to $Servers hash array like $Servers = @{$"name_<name>" = "<IP server>";...}# 4. Event Viewer LogNames: add LogNames logs to $EventViewer hash array like $EventViewer = @{$"name_<name>" =

@('<LogName1>','<LogName2>',...);...} create array like $<name>_logs = @('<Event Viewer LogName 1>','<Event Viewer LogName 2>',..'<Event Viewer LogName N>')# 5. Select the number <N> of before current date you need check in $begindate = $currentdate.AddDays(-<N>) #Credentials$User = "Minsk\sergei.pupkin"$PWord = ConvertTo-SecureString –String "qwaszx12" –AsPlainText -Force$Credential = New-Object –TypeName System.Management.Automation.PSCredential –ArgumentList $User, $PWord#Test case names $TestCases = @{"name_sql01"="004_SQL Server Event Check";"name_biz01"="007_BT Server Event Check";"name_hub01"="011_DH Server Event Check";"name_app02"="013_SRS Server Event Check";"name_app01"="001_Check APP Logs"}#Server names$Servers = @{"name_sql01"="10.52.113.118";"name_biz01"="10.53.113.121";"name_hub01"="10.54.113.123";"name_app02"="10.55.113.120";"name_app01"="10.56.113.119"}#EventViewer LogNames$EventViewer = @{"name_sql01"= @('Application');"name_biz01"= @('Application');"name_hub01"= @('Application');"name_app02"= @('Application');"name_app01"= @('Application', 'HostingApplication')}$currentdate = get-date$begindate = $currentdate.AddDays(-2)write-host ("This script checks logs from Event Viewers from remote machines. The script gets error logs from " + $begindate + " to " + $currentdate + " date.") -foregroundcolor "Cyan"write-host ("The test case is passed if he does not find error logs.") -foregroundcolor "Green""======="#Find and check servicesForeach ($TC in $TestCases.keys){ $SS = $Servers.$TC

#$count_of_logs = $EventViewer.$TC.count write-host ("Test case: "+ $TestCases.$TC + ". Server " + $SS + " started.") -foregroundcolor "Cyan" $i = 0 ForEach ($LogName in $EventViewer.$TC) { write-host ("Test case: "+ $TestCases.$TC + ". The " + $LogName + " logs are checked on " + $SS + " Server.") -foregroundcolor "Cyan" $Logs = Get-WmiObject -class Win32_NTLogEvent -ComputerName $SS -Credential $Credential -filter "(logfile='$LogName') AND (type='error') and (TimeGenerated > '$begindate')" $Logs | Format-list #Table EventIdentifier, CategoryString, EventCode, SourceName, TimeGenerated, Message -auto } "======="}"The script is completed"write-host "Press any key to continue..."[void][System.Console]::ReadKey($true)"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"

Checking XML dataQA Engineers are usually required to check configuration settings of applications in their daily work. In most cases these settings can be stored in .xml files, so using Windows PowerShell can help to automate such tasks. In the example below there is a simple script for checking the expected “LogType” attribute of a Message node, presented in an .xml file.

Script example (update the values highlighted in yellow):

cls$currentdate = get-datewrite-host ("This script checks the existence of a Node with a specific attribute in the .xml file. The script starts execution at " + $currentdate + " .") -foregroundcolor "Cyan"write-host ("The test case is passed if it finds Node with expected attribute.") -foregroundcolor "Green""======="

#value to be searched for$keytosearch = 'ADV_CAP_BATCH'#a path to the .xml file$pathtofile = 'D:\Nice_Projects\sources\sources'

cd $pathtofile[xml]$userfile = [xml](Get-Content Config.xml)

[string]$length = $userfile.SelectSingleNode("//Message[@LogType='$keytosearch']")

if ($length.Length -ne 0) {write-host ("Attribute '$keytosearch' exists in the file.") -foregroundcolor "Green"}else{write-host ("Attribute '$keytosearch' does NOT exist in the file.") -foregroundcolor "Red"}

"=======""The script is completed"write-host "Press any key to continue..."[void][System.Console]::ReadKey($true)

Checking database valuesAnother great example of using Windows PowerShell is verifying a value in a database. Every now and then, you encounter applications that store application settings or some pre-defined data to be checked in a database. In this case, again, we can use Windows PowerShell and a script for checking data in MS SQL server.

See below a script example (update the values highlighted in yellow):

# This script checks the DB connection and checks data in the table# Update values in the TESTED DATA section#--------------------------------------------------- #clean screen before running the scriptclear#--------------------------------------------------- # This function cleans the memory after the script finishes runningFunction Clean-Memory {Get-Variable | Where-Object { $startupVariables -notcontains $_.Name } | ForEach-Object { try { Remove-Variable -Name "$($_.Name)" -Force -Scope "global" -ErrorAction SilentlyContinue -WarningAction SilentlyContinue} catch { } }}#--------------------------------------------------- # This function checks the SQL connection and returns sqlconnection object or zero# input: connectionString# output: sqlconnection object or zeroFunction Test-SQLConn ($connectionString) { $sqlConn = new-object ("Data.SqlClient.SqlConnection") $connectionString trap{ Write-Error "Cannot connect to SQL Server." -ErrorAction Stop; continue } $sqlConn.Open()| out-null

if ($sqlConn.State -eq 'Open'){ Write-Host ("SQL DB is opened successfully.") return $sqlConn } else{ Write-Error ("SQL DB not opened.") -ErrorAction Continue return 0 }}

#--------------------------------------------------- # TESTED DATA: SQLServer, SQLDBName, UId, PWD, SQLQuery and Expected value.# Please, add your data if you need it$SQLServer = "test-ms-sql-01.a02. hosting.net"$SQLDBName = "TESTDB"$uid ="sa"$pwd = "qwaszx12"$SqlQuery = "SELECT [SubmitterID] FROM [TESTPM].[dbo].[LoadedFiles] where [FileName] = 'TEST023.TXT.PROCESSING' order by [StampDate] desc"$Expected = "TZ1234"#---------------------------------------------------

#SQLConnectionstring, follow this link to update connection string https://www.connectionstrings.com/sql-server/ $connectionString = "Server = $SQLServer; Database = $SQLDBName; User ID = $uid; Password = $pwd; Connect Timeout = 5;"#--------------------------------------------------- #Checking SQL Connection$SqlConnection = Test-SQLConn ($connectionString)#--------------------------------------------------- #getting data from databaseif ($SqlConnection -eq 0){ Write-Error ("$SQLDBName DB is NOT opened.") -ErrorAction Stop}else{ Write-Host ("SQL $SQLDBName DB is opened successfully.")

$SqlCmd = New-Object System.Data.SqlClient.SqlCommand $SqlCmd.CommandText = $SqlQuery $SqlCmd.Connection = $SqlConnection $SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter $SqlAdapter.SelectCommand = $SqlCmd $DataSet = New-Object System.Data.DataSet $res = $SqlAdapter.Fill($DataSet) $res}#--------------------------------------------------- #Close SQL connection$SqlConnection.Close();#--------------------------------------------------- #Check data if ($res -eq 0){ Write-warning ("$SqlQuery SQL query has returned 0 records") -foregroundcolor "Red"}else{

foreach ($row in $DataSet.Tables[0].Rows){ $res = 0 if ($row["SubmitterID"].ToString() -eq $Expected){ $res = 1 Break } }}if ($res -eq 0){ write-host ("FAILED: The $Expected value does not exist in the table") -foregroundcolor "Red"}if ($res -eq 1){ write-host ("PASSED: The $Expected value exists in the table") -foregroundcolor "Green"}#--------------------------------------------------- #clean memoryClean-Memory#--------------------------------------------------- "The script is completed"write-host "Press any key to continue..."[void][System.Console]::ReadKey($true)