Skip to content

Refactoring Plan: zmsapiautomation → ATAF-based #1890

@ThomasAFink

Description

@ThomasAFink

Overview

We plan to refactor the zmsapiautomation module to integrate with ATAF (Test Automation Framework
), which will be open-sourced in the coming days. In the meantime, we will configure the setup to already run internally using our local zmsbo database.

Once ATAF is publicly available, we will be able to consume it from Maven Central and update the GitHub Actions pipeline for zmsapiautomation accordingly.

As part of this effort, we will also rename the module from zmsapiautomation to zmsautomation to accommodate potential future UI test automation.

Aspect Current State Target State
Framework Plain REST-assured + JUnit ATAF + Cucumber + REST-assured
Test format Java test classes .feature files + Step definitions
API coverage zmsapi, zmscitizenapi Same
Jira integration None Disabled (local features)
CI/CD GitHub Actions Actions paused until ATAF is OSS
Database setup Flyway Keep Flyway (unchanged)

Phase 1: Project Setup

Copy zmsapiautomation to a new module folder zmsautomation. Then begin refactoring in zmsautomation.

1.1 Update pom.xml with ATAF Dependencies

<!-- zmsautomation/pom.xml -->
<profiles>
  <!-- Default: Current REST-assured tests (GitHub Actions) -->
  <profile>
    <id>standalone</id>
    <activation>
      <activeByDefault>true</activeByDefault>
    </activation>
    <!-- Keep existing dependencies -->
  </profile>
  
  <!-- ATAF profile: City laptop only -->
  <profile>
    <id>ataf</id>
    <repositories>
      <repository>
        <id>lhm-artifactory</id>
        <url>https://artifactory.muenchen.de/artifactory/mvn-repos</url>
      </repository>
    </repositories>
    <dependencies>
      <dependency>
        <groupId>de.muenchen.ataf.java</groupId>
        <artifactId>core</artifactId>
        <version>0.2</version>
      </dependency>
      <dependency>
        <groupId>de.muenchen.ataf.java</groupId>
        <artifactId>rest</artifactId>
        <version>0.2</version>
      </dependency>
    </dependencies>
  </profile>
</profiles>

1.2 Create Directory Structure

zmsautomation/
├── src/
│   ├── main/resources/
│   │   └── db/migration/              # Keep existing Flyway migrations
│   │
│   └── test/
│       ├── java/
│       │   └── zms/
│       │       ├── api/               # Current REST-assured tests (keep)
│       │       │   └── ...
│       │       │
│       │       └── ataf/              # NEW: ATAF-based tests
│       │           ├── data/
│       │           │   └── TestData.java
│       │           ├── hooks/
│       │           │   └── DatabaseHook.java
│       │           ├── runner/
│       │           │   └── TestRunner.java
│       │           └── steps/
│       │               ├── ZmsApiSteps.java
│       │               └── CitizenApiSteps.java
│       │
│       └── resources/
│           ├── features/              # NEW: Cucumber feature files
│           │   ├── zmsapi/
│           │   │   ├── availability.feature
│           │   │   ├── appointments.feature
│           │   │   └── scopes.feature
│           │   └── zmscitizenapi/
│           │       ├── booking.feature
│           │       └── cancellation.feature
│           │
│           ├── cucumber.properties    # NEW
│           ├── testautomation.properties  # NEW
│           └── log4j2-test.properties # NEW

Phase 2: Configuration Files

2.1 cucumber.properties

cucumber.publish.enabled=false
cucumber.publish.quiet=true
cucumber.features=src/test/resources/features
cucumber.plugin=json:target/cucumber.json,html:target/site/cucumber-pretty
cucumber.glue=zms.ataf.steps,zms.ataf.hooks,ataf.rest.steps

2.2 testautomation.properties

# No browser needed for API tests
testautomation.logLevel=INFO

# API base URLs (configured via environment or here)
# These will be read in TestData.java

2.3 log4j2-test.properties

appenders=console
appender.console.type=Console
appender.console.name=STDOUT
appender.console.layout.type=PatternLayout
appender.console.layout.pattern=[%T] %d{HH:mm:ss} %-5p %c{1}:%L - %m%n
rootLogger.level=info
rootLogger.appenderRefs=stdout
rootLogger.appenderRef.stdout.ref=STDOUT

Phase 3: ATAF Integration Code

3.1 TestData.java - Environment Configuration

package zms.ataf.data;

import ataf.core.data.Environment;
import ataf.core.logging.ScenarioLogManager;

public class TestData {
    public static final Environment LOCAL = new Environment("Environment", "LOCAL");
    public static final Environment DEV = new Environment("Environment", "DEV");
    
    public static void init() {
        ScenarioLogManager.getLogger().info("Initializing ZMS API test environments");
        
        // Local development (devcontainer/DDEV)
        String baseUri = System.getenv().getOrDefault("BASE_URI", 
            "http://localhost:8080/terminvereinbarung/api/2");
        String citizenUri = System.getenv().getOrDefault("CITIZEN_API_BASE_URI",
            "http://localhost:8080/terminvereinbarung/api/citizen");
        
        LOCAL.addSystem("ZMS-API", baseUri);
        LOCAL.addSystem("ZMS-Citizen-API", citizenUri);
        
        // City DEV environment (optional)
        DEV.addSystem("ZMS-API", "https://zms-dev.muenchen.de/terminvereinbarung/api/2");
        DEV.addSystem("ZMS-Citizen-API", "https://zms-dev.muenchen.de/terminvereinbarung/api/citizen");
    }
}

3.2 DatabaseHook.java - Flyway Setup

package zms.ataf.hooks;

import io.cucumber.java.BeforeAll;
import org.flywaydb.core.Flyway;

public class DatabaseHook {
    
    @BeforeAll
    public static void setupDatabase() {
        String dbUrl = String.format("jdbc:mysql://%s:%s/%s",
            System.getenv().getOrDefault("MYSQL_HOST", "db"),
            System.getenv().getOrDefault("MYSQL_PORT", "3306"),
            System.getenv().getOrDefault("MYSQL_DATABASE", "zmsbo"));
        
        Flyway flyway = Flyway.configure()
            .dataSource(dbUrl, 
                System.getenv().getOrDefault("MYSQL_USER", "zmsbo"),
                System.getenv().getOrDefault("MYSQL_PASSWORD", "zmsbo"))
            .locations("classpath:db/migration")
            .cleanDisabled(false)
            .load();
        
        flyway.clean();
        flyway.migrate();
    }
}

3.3 TestRunner.java

package zms.ataf.runner;

import ataf.core.runner.BasicTestNGRunner;
import zms.ataf.data.TestData;

public class TestRunner extends BasicTestNGRunner {
    static {
        TestData.init();
    }
}

3.4 ZmsApiSteps.java - Step Definitions

package zms.ataf.steps;

import ataf.rest.steps.BaseRestSteps;
import io.cucumber.java.en.Given;
import io.cucumber.java.en.When;
import io.cucumber.java.en.Then;
import io.restassured.response.Response;

import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;

public class ZmsApiSteps extends BaseRestSteps {
    
    private Response response;
    private String baseUri;
    
    @Given("the ZMS API is available")
    public void theZmsApiIsAvailable() {
        baseUri = System.getenv().getOrDefault("BASE_URI", 
            "http://localhost:8080/terminvereinbarung/api/2");
        
        given()
            .baseUri(baseUri)
        .when()
            .get("/status/")
        .then()
            .statusCode(200);
    }
    
    @When("I request available appointments for scope {int}")
    public void iRequestAvailableAppointments(int scopeId) {
        response = given()
            .baseUri(baseUri)
            .pathParam("scopeId", scopeId)
        .when()
            .get("/scope/{scopeId}/availability/");
    }
    
    @Then("the response status code should be {int}")
    public void theResponseStatusCodeShouldBe(int statusCode) {
        response.then().statusCode(statusCode);
    }
    
    @Then("the response should contain available slots")
    public void theResponseShouldContainSlots() {
        response.then()
            .body("data", not(empty()));
    }
}

Phase 4: Feature Files

4.1 features/zmsapi/availability.feature

@rest @zmsapi
Feature: ZMS API Availability
  As a client application
  I want to check appointment availability
  So that I can offer booking options to citizens

  Background:
    Given the ZMS API is available

  @smoke
  Scenario: Get availability for a valid scope
    When I request available appointments for scope 141
    Then the response status code should be 200
    And the response should contain available slots

  Scenario: Get availability for invalid scope returns empty
    When I request available appointments for scope 99999
    Then the response status code should be 200

4.2 features/zmscitizenapi/booking.feature

@rest @citizenapi
Feature: Citizen API Booking Flow
  As a citizen
  I want to book an appointment
  So that I can visit the office at a scheduled time

  @smoke
  Scenario: Successful appointment booking
    Given the Citizen API is available
    And I have selected a valid service and location
    When I submit a booking request with valid data
    Then the response status code should be 201
    And I should receive a confirmation number

Phase 5: Running Tests

5.1 On City Laptop (with Artifactory access)

# Inside devcontainer or with local ZMS running
cd zmsautomation

# Run ATAF-based tests
mvn test -Pataf -Dcucumber.filter.tags="@smoke"

# Run all ATAF tests
mvn test -Pataf

5.2 Environment Variables

export BASE_URI="http://localhost:8080/terminvereinbarung/api/2"
export CITIZEN_API_BASE_URI="http://localhost:8080/terminvereinbarung/api/citizen"
export MYSQL_HOST="db"
export MYSQL_PORT="3306"
export MYSQL_DATABASE="zmsbo"
export MYSQL_USER="zmsbo"
export MYSQL_PASSWORD="zmsbo"

Phase 6: Migration Strategy

6.1 Migration

Nr. Task
1 Set up ATAF profile and config files
2 Create TestData, DatabaseHook, TestRunner
3 Convert 2-3 existing tests to Cucumber features
4 Add step definitions for core API operations
5 Convert remaining tests, validate on city laptop
6 Document and clean up
7 Switch to Maven Central and Add the Github Actions

6.2 Keep Both Test Suites

# GitHub Actions: Original tests (continue working)
mvn test

# City Laptop: ATAF tests (new)
mvn test -Pataf

Phase 7: Future (When ATAF is Open Source)

  1. Remove <repositories> section from pom.xml
  2. Update ATAF version to Maven Central release
  3. Enable -Pataf as default profile
  4. Add GitHub Actions workflow for ATAF tests
  5. (Optional) Enable Jira/Xray integration

Metadata

Metadata

Assignees

No one assigned

    Labels

    automationTest automationrefactor to refarchEverything related for future modules projects which refactor to it@m refarch

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions