-
Notifications
You must be signed in to change notification settings - Fork 1
Open
Labels
automationTest automationTest automationrefactor to refarchEverything related for future modules projects which refactor to it@m refarchEverything related for future modules projects which refactor to it@m refarch
Description
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.steps2.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.java2.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=STDOUTPhase 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 2004.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 numberPhase 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 -Pataf5.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 -PatafPhase 7: Future (When ATAF is Open Source)
- Remove
<repositories>section from pom.xml - Update ATAF version to Maven Central release
- Enable
-Patafas default profile - Add GitHub Actions workflow for ATAF tests
- (Optional) Enable Jira/Xray integration
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
automationTest automationTest automationrefactor to refarchEverything related for future modules projects which refactor to it@m refarchEverything related for future modules projects which refactor to it@m refarch