Technical articles on AI agents, Azure, .NET, architecture, and EV charging systems from Sydney.

Category: DevOps & Tools Page 1 of 2

CI/CD, Git, Azure DevOps, scripting, and developer tooling

Simplifying API Testing in Postman: Auto-refresh OAuth Tokens with Pre-request Scripts

Introduction:

Welcome to a quick guide on enhancing your API testing workflow in Postman! If you frequently work with APIs that require OAuth tokens, you know the hassle of manually refreshing tokens. This blog post will show you how to automate this process using Pre-request scripts in Postman.

What You Need:

  • Postman installed on your system.
  • API credentials (Client ID, Client Secret) for the OAuth token endpoint.

Step 1: Setting Up Your Environment

  • Open Postman and select your workspace.
  • Go to the ‘Environments’ tab and create a new environment (e.g., “MyAPIEnvironment”).
  • Add variables like accessToken, clientId, clientSecret, and tokenUrl.

Step 2: Creating the Pre-request Script

  • Go to the ‘Pre-request Scripts’ tab in your request or collection.
  • Add the following JavaScript code:
if (!pm.environment.get('accessToken') || pm.environment.get('isTokenExpired')) {
    const getTokenRequest = {
        url: pm.environment.get('tokenUrl'),
        method: 'POST',
        header: 'Content-Type:application/x-www-form-urlencoded',
        body: {
            mode: 'urlencoded',
            urlencoded: [
                { key: 'client_id', value: pm.environment.get('clientId') },
                { key: 'client_secret', value: pm.environment.get('clientSecret') },
                { key: 'grant_type', value: 'client_credentials' }
            ]
        }
    };

    pm.sendRequest(getTokenRequest, (err, res) => {
        if (err) {
            console.log(err);
        } else {
            const jsonResponse = res.json();
            pm.environment.set('accessToken', jsonResponse.access_token);
            pm.environment.set('isTokenExpired', false);
        }
    });
}

Step 3: Using the Access Token in Your Requests

  • In the ‘Authorization’ tab of your API request, select ‘Bearer Token’ as the type.
  • For the token, use the {{accessToken}} variable.

Step 4: Testing and Verification

  • Send your API request.
  • The Pre-request script should automatically refresh the token if it’s not set or expired.
  • Check the Postman Console to debug or verify the token refresh process.

Conclusion: Automating token refresh in Postman saves time and reduces the error-prone process of manual token updates. With this simple Pre-request script, your OAuth token management becomes seamless, letting you focus more on testing and less on token management.

Further Reading:

Build a Secure Integration Tests with Azure Key vaults in Azure DevOps

Scenario: We have an integration tests written in .NET and its using NUnit, We don’t want to store the API Key and all sensitive informations on the repository instead we want it to retrieve all the keys from azure key vaults. At the same time we also would like the Test Engineer to be able to run it on their local environment

One way to achieve it we can use Test parameters feature from NUnit

Add .runsettings in your project and this file will be used for local development/testing only and should not be checked in with the values, and the format can be something like below. If you want to know more details, you can check it here

<?xml version="1.0" encoding="utf-8" ?>
<RunSettings>
	<TestRunParameters>
		<Parameter name="ApiKey" value="" />
		<Parameter name="RefreshToken" value="" />
	</TestRunParameters>
</RunSettings>

Most importantly, you need to configure your IDE below

  1. Make sure autodetection of runsettings in enabled in Visual Studio by checking this checkbox: Tools > Options > Test > Auto Detect runsettings Files.
  2. Make sure you have created your runsettings file in the root of your solution, not your project root.
  3. If all else fails and your tests still can’t find your .runsettings file, you can specify the file manually in the Test Explorer by selecting Options > Configure Run Settings > Select solution wide Run Settings file.

For Visual Studio on Mac – you need to do below

Add the runsetting file path to the project file and it will do the work.

<Project Sdk=“Microsoft.NET.Sdk”>
<PropertyGroup>
<RunSettingsFilePath>$(MSBuildProjectDirectory)\.runsettings</RunSettingsFilePath>
</PropertyGroup>
…
</Project>

In your test class, you can retrieve the test parameters through TestContext.Parameters

[TestFixture]
    public class MyTests
    {
        private readonly string _apiKey;
        private readonly string _refreshToken;

        [SetUp]
        public async Task PopulateConfigs()
        {
            _apiKey = TestContext.Parameters["ApiKey"];
            _refreshToken = TestContext.Parameters["RefreshToken"];

        }
}

On the Azure Pipelines Yml file, this is how you retrieve it from the keyvaults and inject the TestRun Parameters as arguments

pool:
  vmImage: ubuntu-latest

trigger: none
pr: none
schedules:
- cron: "0 20 * * Sun,Mon,Tue,Wed,Thu"
  displayName: Daily morning build
  branches:
    include:
    - master
  always: true

variables:
  - name: dotnetVersion
    value: '7.0.x'

stages:
- stage:
  displayName: Run e2e .NET tests
  jobs:
  - job:
    displayName: build job
    steps:
    - task: UseDotNet@2
      displayName: Use dotnet $(dotnetVersion)
      inputs:
        packageType: sdk
        version: $(dotnetVersion)
    - task: DotNetCoreCLI@2
      displayName: dotnet restore
      inputs:
        command: 'restore'
    - task: DotNetCoreCLI@2
      displayName: 'dotnet build'
      inputs:
        command: 'build'
    - task: AzureKeyVault@2
      inputs:
        azureSubscription: 'My Service Principal'
        KeyVaultName: 'my-keyvault-dev'
        SecretsFilter: '*'
        RunAsPreJob: false
    - task: DotNetCoreCLI@2
      displayName: 'dotnet test'
      inputs:
        command: 'test'
        arguments: '-- "TestRunParameters.Parameter(name=\"ApiKey\", value=\"$(ApiKey)\")" -- "TestRunParameters.Parameter(name=\"RefreshToken\", value=\"$(RefreshToken)\")"'

$(ApiKey) and $(RefreshToken) is mapped with your Azure Keyvault secrets name

Use Power Shell to execute SQL Server script files

Below is the snippet for using Power Shell to execute list of SQL scripts under a specific folder. I use this script in Octopus deployment to deploy database changes (* for this particular case, we don’t use Code First therefore we don’t use Migrate.exe)

[code language=”powershell”]
# Connection String
[string] $ConnectionString = "server=MyDBServer;database=MyDatabase;user id=Myuser;password=Mypassword;trusted_connection=true;"

#The folder where all the sql scripts are located
[string] $ScriptPath= "C:\Octopus\Applications\SQL2014UAT\Powershell Deployment\Scripts"

# Go to every single SQL files under the folder
foreach ($sqlFile in Get-ChildItem -Path $ScriptPath -Filter "*.sql" | sort-object)
{
$SQLQuery = Get-Content "$ScriptPath\$sqlFile" -Raw

ExecuteSqlQuery $ConnectionString $SQLQuery
}

# executes multiple lines of SQL query
function ExecuteSqlQuery ($ConnectionString, $SQLQuery) {
# Use GO to separate between commands
$queries = [System.Text.RegularExpressions.Regex]::Split($SQLQuery, "^\s*GO\s*`$", [System.Text.RegularExpressions.RegexOptions]::IgnoreCase -bor [System.Text.RegularExpressions.RegexOptions]::Multiline)

$queries | ForEach-Object {
$q = $_

if ((-not [String]::IsNullOrWhiteSpace($q)) -and ($q.Trim().ToLowerInvariant() -ne "go"))
{
$Connection = New-Object System.Data.SQLClient.SQLConnection

Try
{
$Connection.ConnectionString = $ConnectionString
$Connection.Open()

$Command = New-Object System.Data.SQLClient.SQLCommand
$Command.Connection = $Connection
$Command.CommandText = $q
$Command.ExecuteNonQuery() | Out-Null
}
Catch
{
echo $_.Exception.GetType().FullName, $_.Exception.Message
}
Finally
{
if ($Connection.State -eq ‘Open’)
{
write-Host "Closing Connection…"
$Command.Dispose()
$Connection.Close()
}
}
}
}
}
[/code]

Alternatively if you have SMO, PS extensions and the snap in then you can use simpler script below. For the pre-requisites for invoke-sqlcmd is here
[code language=”powershell”]
Get-ChildItem -Path "C:\Octopus\Applications\SQL2014UAT\Powershell Deployment\Scripts" -Filter "*.sql" | % {invoke-sqlcmd -InputFile $_.FullName}
[/code]

Reading multiple lines using Powershell

by default, Get-Content in powershell reading the file as a one long string. which means you might have an issue if you have multiple lines of SQL statements as it will read this

IF EXISTS(SELECT 1 FROM sys.procedures WHERE NAME = ‘PSTest’)
BEGIN
DROP PROCEDURE PsTest
END
GO

becoming

IF EXISTS(SELECT 1 FROM sys.procedures WHERE NAME = ‘PSTest’) BEGIN DROP PROCEDURE PsTest END GO

so how to read multiple lines using Power Shell?

Before Power Shell 3.0 you can use the code snippet below

[code language=”powershell”]
(Get-Content $FilePath) -join "`r`n"
[/code]

Power Shell 3.0 and above, you can use -Raw parameter
[code language=”powershell”]
Get-Content $FilePath -Raw
[/code]

Git – Prune your local branches to keep it in sync with remote branches

On your local branches normally you have a stale branch where it doesn’t have corresponding remote branch and you feel like you want to make it in sync with the remote branches

1. Lets start listing the remote branch first just to know what are the branches available remotely

[code language=”bash”]
$ git remote show origin
[/code]

2. Lets see our local stale branches “–dry-run” command will just display the stale branch but without deleting it

[code language=”bash”]
$ git remote prune origin –dry-run
[/code]

3. Alternatively if you want to really delete the stale branches you can run it without “–dry-run” command

[code language=”bash”]
$ git remote prune origin
[/code]

*just make sure you already committed your feature branch to the remote before doing this

Remove Folder on the Release Mode using MSBuild

I got this code snippet to remove "TestHarness" folder only on the Release Mode but when I publish it on the "Debug" Mode the folder should still be there. It is a simple code but it took me a while to figure it out

My csproj file

<ItemGroup>
<ExcludeFromPackageFolders Include="TestHarness" Condition=" ‘$(Configuration)’ == ‘Release’">
<FromTarget>Project</FromTarget>
</ExcludeFromPackageFolders>
</ItemGroup>

Microsoft All in One Script Framework

I’ve just found that Microsoft has just released a repository for all scripts which are driven by Technet script repository and Microsoft Customer Script & Support, the sample scripts are based on the real world scenario which are expected to save the IT admin/developer to reinvent the wheel for a particular task and instead they can build upon it or modify it. The repository covers sample for Microsoft Office, Microsoft SQL Server, Microsoft Exchange, Microsoft Sharepoint, Microsoft Windows 7, Microsoft Windows Server 2008 and Office 365

http://blogs.technet.com/b/onescript/

Trello – Collaboration TODO Web App

My manager recommended us to check this website in order to help us keep tracking of what need to be done

What I like is the simple UI and easy to use. It helps people to manage their projects and resources or even it helps you to organise your daily activities. It is free to use as well

http://trello.com

Web Service Tester

This is an application to access your Web Service/API without worrying to create your own client application for the sake of testing. Personally, I’m using soapUI (an open source application to test web service)

http://sourceforge.net/projects/soapui/files/

I’d prefer to use tool this because it provides you a transparent communication between the client and the Web Service and it’s really simple to use and configure. It’d save you a lot of time to debug the issue for your client. You can trace it down whether the issue is in the client or in the web service itself

Disabling Time Synchronization of Virtual PC image

I was having the problem where I tried to change the date and time on my VPC environment, it keeps resetting it back. To resolve the issue, you need to edit the *.VMC file and add the highlighted section below, resave the file and launch your VPC.

<integration>
    <microsoft>
        <mouse>
            <allow type=”boolean”>true</allow>
        </mouse>
        <components>
            <host_time_sync>
                <enabled type=”boolean”>false</enabled>
            </host_time_sync>
        </components>

Page 1 of 2

Powered by WordPress & Theme by Anders Norén