DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Because the DevOps movement has redefined engineering responsibilities, SREs now have to become stewards of observability strategy.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Related

  • Pipeline as a Service: How To Test Pipelines in GitLab
  • Testing Serverless Functions
  • Using Azure DevOps Pipeline With Gopaddle for No-Code Kubernetes Deployments
  • Testcontainers: From Zero To Hero [Video]

Trending

  • Introduction to Retrieval Augmented Generation (RAG)
  • Memory Leak Due to Time-Taking finalize() Method
  • Building a Real-Time Audio Transcription System With OpenAI’s Realtime API
  • Using Java Stream Gatherers To Improve Stateful Operations
  1. DZone
  2. Testing, Deployment, and Maintenance
  3. Deployment
  4. Test Automation: Maven Profiles and Parallelization in Azure Pipelines Using IaaS

Test Automation: Maven Profiles and Parallelization in Azure Pipelines Using IaaS

When it comes to test automation, configuring parallel threads can become challenging. This article helps those who are looking to automate their QA and DevOps needs.

By 
Aniket Wadkar user avatar
Aniket Wadkar
·
Oct. 04, 21 · Tutorial
Likes (1)
Comment
Save
Tweet
Share
5.7K Views

Join the DZone community and get the full member experience.

Join For Free

When it comes to Test Automation, configuring parallel threads can become challenging especially when logins are involved. It's more of a challenge for the UI/ Selenium test to run batches in a separate thread on Azure pipelines with separate credential sets. 

Solution Overview: Create test suites using tags for the cucumber framework. Create profiles for login credentials and environments to run on. Compile the build with a test suite, login credentials, and environment to run on. This approach can be used for other types of test suits as well such as Junit. 

Framework Configuration: Most frameworks use config.properties files to compile the desired build. Maven has provides some really simple ways to configure the build using build profiles. This helps generate a specific config file for each build using the command line. 

STEP 1: 

Properties PLugin in POM.XML

In your POM.XML file add the below plugin. Notice the file name in the example below 'properties-from-pom' which will be generated in your output or target folder when the goal 'mvn compile' is run. 

Java
 
 <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>properties-maven-plugin</artifactId>
        <version>1.0.0</version>
        <executions>
          <execution>
            <phase>generate-resources</phase>
            <goals>
              <goal>write-project-properties</goal>
            </goals>
            <configuration>
              <outputFile>${project.build.outputDirectory}/properties-from-pom.properties</outputFile>
            </configuration>
          </execution>
        </executions>
      </plugin>


STEP 2: 

Adding Properties in POM.XML

Now we can start adding the project properties to the POM.XML file.  You can migrate the properties used in your config.properties file as shown below. You can create properties with custom names to be relevant to your needs. All these properties will be loaded in the properties-from-pom.xml file when the 'mvn compile' goal is run.  

Java
 
<properties>
    <!--    PROJECT CONFIGURATION :-->
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <ApplicationName>Name of the Application goes here</ApplicationName>

    <!--    Login CREDENTIALS DEFAULT : -->
    <username>please choose a username from maven profiles</username>
    <!--Either place the username and password in these or leave them blank as they will be overloaded by the profiles-->
    <!You will see below.-->
    <password>please choose a password from maven profiles</password>

    <!--Environment Configuration-->
    <environment>please choose a environment by compiling using mvn compile -P{environment name} from maven profiles</environment>
	<!-- same applies to the environment to run on-->
    <!--    BROWSER CONFIGURATION : Unaffected by profiles-->
    <browser>chrome</browser>

    <!--    BROWSERSTACK CONFIGURATION -->
    <BrowserStackEnabled>false</BrowserStackEnabled>
    <browserstackBrowserName>chrome</browserstackBrowserName>

    <!--    ENVIRONMENT URL -->
    <DEV_URL>place your URLS to point here</DEV_URL>
    <TEST_URL>place your URLS to point here</TEST_URL>
    <UAT_URL>place your URLS to point here</UAT_URL>
    <PP_URL>place your URLS to point here</PP_URL>
    <PRODUCTION_URL>place your URLS to point here</PRODUCTION_URL>

    <!--    WAITS AND TIMEOUTS -->
    <wd_implicitWait>30</wd_implicitWait>
    <wd_pageLoadTimeOut>20</wd_pageLoadTimeOut>
    <speedController>0</speedController>

    <!-- PATCHES -->
    <patchNameIfAny>true</patchNameIfAny>
  

    <!--    LOGGER CONFIGURATION -->
    <logUser>${user.name}</logUser>
    <log_switch>on</log_switch>

    <!--    REPORT CONFIGURATION -->
    <report_switch>on</report_switch>

    <!--    SCREENSHOT -->
    <screenshot_switch>on</screenshot_switch>

    <!--    BROWSERSTACK CONFIGURATION -->
    <BrowserStackURLHost>hub-cloud.browserstack.com/wd/hub</BrowserStackURLHost>
    <BrowserStackUserName>BrowserStack User Name</BrowserStackUserName>
    <BrowserStackKey>Browser Stack Authentication Key</BrowserStackKey>
    <browserStackBrowserName>Chrome</browserStackBrowserName>
    <browserStackBrowserVersion>85</browserStackBrowserVersion>
    <browserStackOSname>Windows</browserStackOSname>
    <browserStackOSVersion>10</browserStackOSVersion>
    <browserStackSeleniumVersion>Selenium VersionNumber</browserStackSeleniumVersion>
  </properties>


STEP 3: 

Compiling builds using Maven Profiles:

Java
 
 <profiles>
    <!--    ENVIRONMENT PROFILES -->
    <profile>
      <id>uat</id>
      <activation>
        <activeByDefault>false</activeByDefault>
      </activation>
      <properties>
        <environment>uat</environment>
        <!-- NOTE : the property name has to match to the property declared in the previous step. -->
        <!-- Previous Step : Loading Properties in POM -->
      </properties>
    </profile>
    <profile>
      <id>LoginSet1</id>
      <activation>
        <activeByDefault>false</activeByDefault>
      </activation>
      <properties>
        <username>username@domain.com</username>
        <password>passwordValue</password>
      </properties>
    </profile>
 </profiles>


How To Replace the Values in Properties-from-pom.xml by Using Profiles?

Compile the Maven project using mvn compile -P{profile-id} e.g: mvn compile -PLoginSet1 will replace the username and password in the properties-from-pom.xml file with the values from the profile. 

This way you can run maven goals such as mvn compile test -PLoginSet1 -Puat which configures the build with values from the profiles.  If you need to override any other property in the POM properties, it can be done with the -D switch. The mvn compile -DApplicationName="Sample Application". You can now create multiple builds in your Azure pipelines using these profiles. 

STEP 4: 

IaaS Infrastructure as a Code 

The azure-pipeline.YAML is a file recognized by Azure to build its pipelines. For this create a pipeline in Azure and configure it to read the azure-pipeline.YAML. That's all we need here! We will do the infrastructure building in the YAML file.  

When the pipeline gets executed it reads the YAML file and configures itself. Every time the pipeline runs, it uses the YAML file to build and configure the infrastructure. We can build multiple parallel runs with different configurations from the same code branch. This covers a good practice of building from the same branch.  

The below snipped uses a Microsoft Hosted Agent to Build Cucumber Test in 4 threads that run in parallel. The 'options' define the profiles to use to build snapshots.  As in the example below, we can now control the number of threads we want to run in this pipeline and can also configure each thread for various configurations such as environment to run, login credentials to use, and test suite choice. You can enable CI on the pipeline in Azure and every time you check in to this branch the pipeline will be configured as per the YAML file and executed. This can be added as a stage to a CD process. 

Java
 
## Maven
## Build your Java project and run tests with Apache Maven.
## Add steps that analyze code, save build artifacts, deploy, and more:
## https://docs.microsoft.com/azure/devops/pipelines/languages/java
#


variables:
  - name: BuildParameters.mavenPOMFile
    value: pom.xml
name: $(date:yyyyMMdd)$(rev:.r)
resources:
  repositories:
    - repository: self
      type: git
      ref: refs/heads/{put branch name here}
jobs:
  - job: Batch 1 Regression
    displayName: Batch 1 Regression
    pool:
      vmImage: vs2017-win2016
    steps:
      - checkout: self
      - task: Maven@3
        displayName: Maven pom.xml
        inputs:
          mavenPOMFile: $(BuildParameters.mavenPOMFile)
          goals: compile verify
          options: -PLoginSet1 -Puat -Dcucumber.options="--tags @demo01"
          testResultsFiles: '**/target/cucumber-reports/Cucumber.xml'
      - task: CopyFiles@2
        displayName: 'Copy Files to: $(build.artifactstagingdirectory)'
        condition: succeededOrFailed()
        inputs:
          SourceFolder: $(system.defaultworkingdirectory)
          Contents: '**/*.jar'
          TargetFolder: $(build.artifactstagingdirectory)
      - task: PublishBuildArtifacts@1
        displayName: 'Publish Artifact: drop'
        condition: succeededOrFailed()
        inputs:
          PathtoPublish: $(build.artifactstagingdirectory)
  - job: Job_2
    displayName: Test Demo 2
    pool:
      vmImage: vs2017-win2016
    steps:
      - checkout: self
      - task: Maven@3
        displayName: Maven pom.xml
        inputs:
          mavenPOMFile: $(BuildParameters.mavenPOMFile)
          goals: compile verify
          options: -Pcs2 -Ptest -Dcucumber.options="--tags @demo02"
          testResultsFiles: '**/target/cucumber-reports/Cucumber.xml'
      - task: CopyFiles@2
        displayName: 'Copy Files to: $(build.artifactstagingdirectory)'
        inputs:
          SourceFolder: $(system.defaultworkingdirectory)
          Contents: '**/*.jar'
          TargetFolder: $(build.artifactstagingdirectory)
      - task: PublishBuildArtifacts@1
        displayName: 'Publish Artifact: drop copy'
        condition: succeededOrFailed()
        inputs:
          PathtoPublish: $(build.artifactstagingdirectory)
  - job: Batch 2 Regression
    displayName: Batch 2 Regression
    pool:
      vmImage: vs2017-win2016
    steps:
      - checkout: self
      - task: Maven@3
        displayName: Maven pom.xml
        inputs:
          mavenPOMFile: $(BuildParameters.mavenPOMFile)
          goals: compile verify
          options: -PLoginSet2 -Ptest -Dcucumber.options="--tags @demo03"
          testResultsFiles: '**/target/cucumber-reports/Cucumber.xml'
      - task: CopyFiles@2
        displayName: 'Copy Files to: $(build.artifactstagingdirectory) copy'
        inputs:
          SourceFolder: $(system.defaultworkingdirectory)
          Contents: '**/*.jar'
          TargetFolder: $(build.artifactstagingdirectory)
      - task: PublishBuildArtifacts@1
        displayName: 'Publish Artifact: drop copy copy'
        condition: succeededOrFailed()
        inputs:
          PathtoPublish: $(build.artifactstagingdirectory)
  - job: Batch 3 Regression
    displayName: Batch 3 Regression
    pool:
      vmImage: vs2017-win2016
    steps:
      - checkout: self
      - task: Maven@3
        displayName: Maven pom.xml
        inputs:
          mavenPOMFile: $(BuildParameters.mavenPOMFile)
          goals: compile verify
          options: -Pcs4 -Ptest -Dcucumber.options="--tags @demo04"
          testResultsFiles: '**/target/cucumber-reports/Cucumber.xml'
      - task: CopyFiles@2
        displayName: 'Copy Files to: $(build.artifactstagingdirectory) copy'
        inputs:
          SourceFolder: $(system.defaultworkingdirectory)
          Contents: '**/*.jar'
          TargetFolder: $(build.artifactstagingdirectory)
      - task: PublishBuildArtifacts@1
        displayName: 'Publish Artifact: drop copy copy'
        condition: succeededOrFailed()
        inputs:
          PathtoPublish: $(build.artifactstagingdirectory)
  - job: Batch 4 Regression
    displayName: Batch 4 Regression
    pool:
      vmImage: vs2017-win2016
    steps:
      - checkout: self
      - task: Maven@3
        displayName: Maven pom.xml
        inputs:
          mavenPOMFile: $(BuildParameters.mavenPOMFile)
          goals: compile verify
          options: -PLoginSet3 -Ptest -Dcucumber.options="--tags @demo05"
          testResultsFiles: '**/target/cucumber-reports/Cucumber.xml'
      - task: CopyFiles@2
        displayName: 'Copy Files to: $(build.artifactstagingdirectory) copy'
        inputs:
          SourceFolder: $(system.defaultworkingdirectory)
          Contents: '**/*.jar'
          TargetFolder: $(build.artifactstagingdirectory)
      - task: PublishBuildArtifacts@1
        displayName: 'Publish Artifact: drop copy copy'
        condition: succeededOrFailed()
        inputs:
          PathtoPublish: $(build.artifactstagingdirectory)
...


Hope this article helps some of you out there looking to automate your QA and DevOps needs.

Pipeline (software) Testing Profile (engineering) azure Apache Maven Continuous Integration/Deployment Property (programming)

Opinions expressed by DZone contributors are their own.

Related

  • Pipeline as a Service: How To Test Pipelines in GitLab
  • Testing Serverless Functions
  • Using Azure DevOps Pipeline With Gopaddle for No-Code Kubernetes Deployments
  • Testcontainers: From Zero To Hero [Video]

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!