Copado Test Automation: Running Apex Tests and UI Tests in Your Pipeline

Copado Test Automation: Running Apex Tests and UI Tests in Your Pipeline

Deploying Salesforce metadata without automated tests is flying blind. A single broken Apex trigger or a misconfigured flow can take down business-critical processes the moment code hits production. Copado's testing framework integrates testing directly into your pipeline so that bad code never advances past QA. This guide covers the full testing stack — from Apex unit tests to UI automation with Copado Robotic Testing.

How Copado Approaches Testing

Copado doesn't replace Salesforce's native testing capabilities — it orchestrates them. The platform can:

  • Trigger Apex test runs during or after deployment to a target org
  • Integrate with third-party UI automation tools like Provar, Selenium Grid, and Tosca
  • Use Copado Robotic Testing (CRT) for no-code and low-code UI test execution
  • Block promotions when tests fail, preventing broken code from advancing in the pipeline
  • Display test results directly on the User Story or Deployment record

The philosophy is: tests are gates. Every stage transition in your pipeline can require a set of tests to pass before the promotion is allowed to proceed.

Running Apex Tests in Your Pipeline

Apex tests are the foundation. Salesforce requires at least 75% code coverage for production deployments, but Copado lets you go beyond compliance and run meaningful unit and integration tests at each pipeline stage.

Configuring Apex Test Execution

Navigate to your Pipeline record and open the Test Settings section. Here you configure which tests run at which stage. Options include:

  • Run all local tests — runs every test class in the org
  • Run specified tests — runs a named list of Apex test classes
  • Run tests in the deployment package — only runs tests that cover the metadata being deployed

For most teams, "Run tests in the deployment package" is the right starting point. It keeps test execution fast by only running relevant tests rather than the entire test suite.

Creating Effective Apex Test Classes

Your Apex test classes need to follow standard Salesforce patterns, but there are Copado-specific considerations. A well-structured test class looks like this:

@isTest
public class OpportunityValidationTest {

    @TestSetup
    static void setupTestData() {
        Account acc = new Account(
            Name = 'Test Account',
            Industry = 'Technology'
        );
        insert acc;

        Opportunity opp = new Opportunity(
            Name = 'Test Opportunity',
            AccountId = acc.Id,
            StageName = 'Prospecting',
            CloseDate = Date.today().addDays(30)
        );
        insert opp;
    }

    @isTest
    static void testValidCloseDate() {
        Opportunity opp = [
            SELECT Id, CloseDate, StageName
            FROM Opportunity
            LIMIT 1
        ];

        Test.startTest();
        opp.CloseDate = Date.today().addDays(60);
        update opp;
        Test.stopTest();

        Opportunity updated = [SELECT CloseDate FROM Opportunity WHERE Id = :opp.Id];
        System.assertEquals(
            Date.today().addDays(60),
            updated.CloseDate,
            'Close date should update successfully'
        );
    }

    @isTest
    static void testPastCloseDateBlocked() {
        Opportunity opp = [SELECT Id, CloseDate FROM Opportunity LIMIT 1];

        Test.startTest();
        opp.CloseDate = Date.today().addDays(-1);
        try {
            update opp;
            System.assert(false, 'Expected exception was not thrown');
        } catch (DmlException e) {
            System.assert(
                e.getMessage().contains('Close date cannot be in the past'),
                'Unexpected error message: ' + e.getMessage()
            );
        }
        Test.stopTest();
    }
}

Key practices for Copado-compatible test classes:

  • Use @TestSetup for data creation to avoid duplicate data issues across test methods
  • Always use Test.startTest() and Test.stopTest() to isolate governor limit consumption
  • Assert specific values, not just that no exception was thrown
  • Aim for test methods that each test a single behavior

Viewing Apex Test Results in Copado

After a deployment completes, the Promotion record shows an Apex Tests tab with:

  • Total tests run
  • Pass/fail count
  • Individual test method results with failure messages
  • Code coverage percentage per class

If any test fails, Copado marks the deployment as failed. The user story cannot be promoted to the next stage until the tests pass.

Configuring Minimum Coverage Thresholds

In Pipeline Settings, you can set a minimum code coverage threshold above the Salesforce default of 75%. Regulated industries often require 80% or higher. Set this in the pipeline configuration, and Copado will block deployments that don't meet the threshold even if all individual tests pass.

Integrating Provar for Salesforce UI Testing

For functional UI testing — verifying that a page layout, flow, or Lightning component actually works for end users — many Copado teams integrate Provar, a Salesforce-specific test automation tool.

How the Integration Works

Provar tests are stored in a Git repository alongside your Salesforce metadata. When Copado promotes a user story, it can trigger a Continuous Integration (CI) job that:

  1. Spins up a Provar test execution environment
  2. Runs the specified test suite against the target org
  3. Reports results back to Copado via webhook or API call
  4. Passes or fails the deployment based on test outcomes

Configuring a Provar CI Job in Copado

Create a Function record in Copado (found under Copado Functions in the App Launcher). Functions are reusable scripts that can be attached to pipeline steps. A Provar function typically:

# Copado Function configuration (simplified)
name: Run Provar Tests
type: Shell Script
script: |
  cd $PROVAR_PROJECT_DIR
  ant runtests -DtestSuite=RegressionSuite \
    -Dorg.username=$SF_USERNAME \
    -Dorg.password=$SF_PASSWORD \
    -Dorg.serverUrl=$SF_LOGIN_URL
  # Parse results and exit with non-zero code on failure

Attach this function to your QA pipeline stage so it runs automatically after every deployment.

Selenium Grid Integration

If your team uses Selenium directly, Copado can integrate via a similar Function approach. Your shell script calls your Selenium test runner (pytest, TestNG, etc.) against the deployed org's URL, and the exit code determines whether the pipeline step passes or fails.

#!/bin/bash
pytest tests/salesforce_ui/ \
  --base-url=$SF_INSTANCE_URL \
  --username=$SF_USERNAME \
  --password=$SF_PASSWORD \
  --junit-xml=results.xml

# Copado reads the exit code
exit $?

Copado Robotic Testing (CRT)

Copado Robotic Testing is Copado's own UI automation solution, built to lower the barrier to entry for functional test automation. Unlike Provar or Selenium, CRT is designed to be used by QA analysts and business analysts — not just developers.

What CRT Provides

  • Record-and-replay test creation — testers can record interactions in a browser and CRT generates the test script automatically
  • Salesforce-aware selectors — CRT understands Salesforce's dynamic IDs and component patterns, reducing selector brittleness
  • Cloud test execution — tests run on Copado's managed infrastructure, no local test runner required
  • Native Copado integration — results appear directly in the Promotion record, no webhook configuration needed

Creating a CRT Test Suite

In the Copado app, navigate to Robotic Tests. Click New Test and choose your starting point:

  • Record from scratch — opens a recording session in Chrome
  • Create manually — write test steps directly in CRT's scripting language

A recorded CRT test looks like this:

# CRT Test Script - Opportunity Creation
Navigate to: /lightning/o/Opportunity/new
Click: "New Opportunity" button
Set field "Opportunity Name" to: "Test Opportunity - CRT"
Set field "Close Date" to: [Today + 30 days]
Set field "Stage" to: "Prospecting"
Click: "Save" button
Assert: Page title contains "Test Opportunity - CRT"
Assert: Field "Stage" equals "Prospecting"

Running CRT Tests in the Pipeline

In your Pipeline configuration, attach a Test Suite to a specific stage. Select the CRT tests you want to run at that stage. When a promotion reaches that stage, Copado automatically:

  1. Provisions a cloud browser session
  2. Authenticates to the target org
  3. Runs the CRT test suite
  4. Reports pass/fail per test case
  5. Blocks or allows the promotion based on results

CRT vs. Provar vs. Selenium

CRT Provar Selenium
Setup complexity Low Medium High
Salesforce-specific features High High Low
Scripting flexibility Medium High Very High
Maintenance overhead Low Medium High
License cost Included in Copado Separate license Open source

CRT is the right choice for teams without dedicated automation engineers. Provar is better for teams with complex Salesforce test scenarios requiring detailed assertions. Selenium is appropriate when you need maximum flexibility or are testing custom Lightning components that CRT and Provar struggle with.

Setting Up Test Suites

A Test Suite in Copado groups related tests that should run together. You might have:

  • Smoke Suite — 5-10 critical path tests that run on every deployment (fast, catches major regressions)
  • Regression Suite — comprehensive tests that run before UAT promotion (thorough, slower)
  • Deployment Suite — Apex tests specific to the metadata being deployed

Creating a Test Suite

Navigate to Test Suites > New. Add tests from your available CRT tests, Apex test classes, or Function-based tests. Set the Execution Order if some tests depend on data created by earlier tests.

Assign the suite to a pipeline stage by editing the pipeline connection and selecting the test suite in the Test Suite field. The suite runs automatically on every promotion through that stage.

Interpreting Test Results

Reading Apex Test Failures

When an Apex test fails, the error message in Copado shows:

OpportunityValidationTest.testPastCloseDateBlocked: System.AssertException:
Assertion Failed: Expected exception was not thrown
Stack trace:
  Class.OpportunityValidationTest.testPastCloseDateBlocked: line 42, column 1

This tells you exactly which test method failed and where. Click into the Deployment Log for the full context, including which metadata components were deployed before the test failure.

Reading CRT Test Failures

CRT failures show a screenshot of the browser at the point of failure, plus the failed step. This is invaluable for debugging — you can see exactly what the UI looked like when the assertion failed.

Deployment Failure Behavior

When tests fail, Copado sets the Promotion status to Failed and stops the pipeline. The user story remains in its current stage. The developer must:

  1. Investigate the failure from the test results on the Promotion record
  2. Fix the code or the test (depending on whether it's a real bug or a test that needs updating)
  3. Commit the fix to the feature branch
  4. Re-attempt the promotion

This loop is intentional. It prevents "I'll just merge it and fix it in the next release" behavior that leads to broken production orgs.

Blocking Deployments on Test Failures

The most important configuration is making sure test failures actually block deployments. In Copado's pipeline stage configuration:

  1. Open the Pipeline Connection record for the stage
  2. Set Block Deployment on Test Failure to true
  3. Set Minimum Code Coverage to your required threshold (e.g., 80%)

With this configuration, no human can override a test failure and force a deployment through. The pipeline is the authority, not the release manager's judgment call at 5pm on Friday.

Common Testing Pitfalls

Not creating independent test data — Tests that depend on data created by other tests fail intermittently depending on execution order. Always use @TestSetup or create data within each test method.

Using hard-coded IDs — IDs differ between sandboxes. Any test that references a hard-coded record ID will fail in any org other than the one it was written in.

Testing only the happy path — Tests that only verify things work when inputs are valid miss the bugs that actually reach production. Test error conditions, boundary cases, and unexpected inputs.

Ignoring test maintenance — As your Salesforce org evolves, test data setup requirements change. A test suite that was green six months ago may fail today because a required field was added. Treat tests as production code that requires ongoing maintenance.

Running too many tests on every deployment — Running 2,000 tests on every user story promotion kills developer velocity. Use targeted test execution (tests relevant to the deployed metadata) for developer-stage pipelines and save full regression for UAT.

A well-configured Copado testing pipeline catches bugs at the cheapest point — before they reach production — and gives your team the confidence to deploy frequently without fear.

Read more

Start now free