From 8c026c32381b20b4b7b838b4ee81d245752d0e26 Mon Sep 17 00:00:00 2001 From: AZANIR Date: Sun, 24 Aug 2025 17:56:58 +0300 Subject: [PATCH 1/2] Add Karate integration example with Testomat.io support - Introduced a new Karate project with a Maven setup, including a `pom.xml` for dependencies. - Added a README.md detailing setup instructions, test scenarios, and integration steps. - Created feature files for testing the Swagger Petstore API with unique test IDs. - Implemented a test runner in Java to execute the Karate tests and generate JUnit XML reports. --- .claude/settings.local.json | 11 + karate-example/README.md | 238 ++++++++++++++++++ karate-example/pom.xml | 74 ++++++ .../java/com/testomat/karate/KarateTest.java | 17 ++ .../test/resources/simple-api-test.feature | 40 +++ 5 files changed, 380 insertions(+) create mode 100644 .claude/settings.local.json create mode 100644 karate-example/README.md create mode 100644 karate-example/pom.xml create mode 100644 karate-example/src/test/java/com/testomat/karate/KarateTest.java create mode 100644 karate-example/src/test/resources/simple-api-test.feature diff --git a/.claude/settings.local.json b/.claude/settings.local.json new file mode 100644 index 0000000..4fc6155 --- /dev/null +++ b/.claude/settings.local.json @@ -0,0 +1,11 @@ +{ + "permissions": { + "allow": [ + "mcp__context7__resolve-library-id", + "mcp__context7__get-library-docs", + "Bash(mkdir:*)" + ], + "deny": [], + "ask": [] + } +} \ No newline at end of file diff --git a/karate-example/README.md b/karate-example/README.md new file mode 100644 index 0000000..2130968 --- /dev/null +++ b/karate-example/README.md @@ -0,0 +1,238 @@ +# Karate Testomat.io Integration Example + +This example demonstrates how to properly integrate Karate tests with Testomat.io using unique test IDs for Scenario Outline examples. + +## Overview + +This project contains a simple Karate test that demonstrates: +- Testing the Swagger Petstore API (https://petstore.swagger.io/v2/) +- Proper use of unique `@T...` test IDs in Scenario Outline examples +- Correct integration with Testomat.io for individual test tracking + +## Features + +### Test Scenarios +1. **Get pet by ID** - Tests retrieving pets with different IDs (existing and non-existing) +2. **Add new pet** - Tests creating new pets with different data + +### Unique Test IDs +Each Scenario Outline example has a unique test ID in the format `@T[8 alphanumeric characters]`: +- `T1a2b3c4d`, `T5e6f7g8h`, `T9i0j1k2l` (GET scenarios) +- `Tm3n4o5p6`, `Tq7r8s9t0`, `Tu1v2w3x4` (POST scenarios) + +## 🚀 Setup Framework From Scratch (In a Nutshell) + +### Quick Setup (5 minutes) + +```bash +# 1. Create project directory +mkdir my-karate-project +cd my-karate-project + +# 2. Create Maven directory structure +mkdir -p src/test/java/com/example/karate +mkdir -p src/test/resources + +# 3. Create pom.xml with Karate dependencies +cat > pom.xml << 'EOF' + + + 4.0.0 + com.example + karate-project + 1.0.0 + + 11 + 11 + 1.4.1 + + + + com.intuit.karate + karate-junit5 + ${karate.version} + test + + + + + + src/test/java + **/*.java + + + + +EOF + +# 4. Create test runner +cat > src/test/java/com/example/karate/TestRunner.java << 'EOF' +package com.example.karate; +import com.intuit.karate.Results; +import com.intuit.karate.Runner; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class TestRunner { + @Test + void testAll() { + Results results = Runner.path("classpath:") + .outputJunitXml(true) + .parallel(1); + assertTrue(results.getFailCount() == 0, results.getErrorMessages()); + } +} +EOF + +# 5. Create your first .feature file +cat > src/test/resources/sample-test.feature << 'EOF' +Feature: Sample API Test + +Background: + * url 'https://petstore.swagger.io/v2' + +Scenario Outline: Get pet - @ + Given path 'pet', + When method get + Then status + +Examples: +| testCase | petId | expectedStatus | testId | +| existing | 1 | 200 | T1a2b3c4d | +| nonexistent | 999 | 404 | T5e6f7g8h | +EOF + +# 6. Run your first test +mvn test +``` + +### That's it! You now have: +✅ Working Karate framework +✅ Sample API test with unique test IDs +✅ JUnit XML reports in `target/karate-reports/` +✅ Ready for Testomat.io integration + +### Next Steps +```bash +# Install report-xml tool (if not installed) +npm install -g @testomatio/reporter + +# Import to Testomat.io +TESTOMATIO=your_key TESTOMATIO_TITLE_IDS=1 npx report-xml "target/karate-reports/**/*.xml" +``` + +## Prerequisites + +- Java 11+ +- Maven 3.6+ +- Internet connection (to access Petstore API) +- Node.js (for Testomat.io import) + +## Running Tests + +### Local Execution + +```bash +# Run all tests +mvn test + +# Run specific test class +mvn test -Dtest=KarateTest + +# Run with specific Karate options +mvn test -Dkarate.options="--tags @T1a2b3c4d" +``` + +### Alternative Feature File Execution + +```bash +# Run specific feature file directly +mvn test -Dkarate.options="classpath:simple-api-test.feature" +``` + +## Testomat.io Integration + +### 1. Generate JUnit XML Reports + +Tests automatically generate JUnit XML reports in `target/karate-reports/` when executed. + +### 2. Import to Testomat.io + +```bash +# Import test results using unique test IDs +TESTOMATIO=your_project_key TESTOMATIO_TITLE_IDS=1 npx report-xml "target/karate-reports/**/*.xml" +``` + +### Key Integration Points + +- **TESTOMATIO_TITLE_IDS=1**: Ensures Testomat.io uses the `@T...` IDs from scenario titles +- **Unique Test IDs**: Each example in Scenario Outline has a unique `@T...` ID +- **Proper Naming**: Scenario titles include `@` placeholder + +## Project Structure + +``` +karate-example/ +├── pom.xml +├── README.md +└── src/ + └── test/ + ├── java/ + │ └── com/ + │ └── testomat/ + │ └── karate/ + │ └── KarateTest.java + └── resources/ + └── simple-api-test.feature +``` + +## API Details + +### Swagger Petstore API +- **Base URL**: https://petstore.swagger.io/v2 +- **Endpoints Used**: + - `GET /pet/{petId}` - Retrieve pet by ID + - `POST /pet` - Add new pet +- **Expected Behavior**: + - Pet IDs 1-10 typically exist (status 200) + - Pet ID 999+ typically don't exist (status 404) + - POST requests create new pets (status 200) + +## Test ID Format + +Test IDs follow the pattern: `T` + 8 alphanumeric characters +- Must be unique within the project +- Used in scenario titles via `@` placeholder +- Enables proper test tracking in Testomat.io + +## Troubleshooting + +### Common Issues + +1. **Tests fail due to network**: Ensure internet access to petstore.swagger.io +2. **XML reports not generated**: Check `target/karate-reports/` directory exists +3. **Testomat.io import issues**: Verify `TESTOMATIO_TITLE_IDS=1` is set + +### Verification + +1. **Run tests successfully**: `mvn test` should show 6 scenarios passed +2. **Check XML reports**: Verify unique test case names contain `@T...` IDs +3. **Testomat.io import**: Each scenario should appear as separate test + +## Example Output + +When tests run successfully, you should see: +``` +6 scenarios (6 passed) +``` + +JUnit XML will contain entries like: +```xml + + +``` + +This ensures each test appears separately in Testomat.io rather than as retries of the same test. \ No newline at end of file diff --git a/karate-example/pom.xml b/karate-example/pom.xml new file mode 100644 index 0000000..e4ce5a3 --- /dev/null +++ b/karate-example/pom.xml @@ -0,0 +1,74 @@ + + + + 4.0.0 + com.testomat + karate-example + 1.0.0 + jar + + + UTF-8 + 11 + 3.8.1 + 3.0.0-M7 + 1.4.1 + 5.8.2 + + + + + com.intuit.karate + karate-junit5 + ${karate.version} + test + + + org.junit.jupiter + junit-jupiter + ${junit.version} + test + + + + + + + src/test/java + + **/*.java + + + + src/test/resources + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven.compiler.version} + + UTF-8 + ${java.version} + ${java.version} + -Werror + + + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven.surefire.version} + + -Dfile.encoding=UTF-8 + + + + + + \ No newline at end of file diff --git a/karate-example/src/test/java/com/testomat/karate/KarateTest.java b/karate-example/src/test/java/com/testomat/karate/KarateTest.java new file mode 100644 index 0000000..9b3dbe7 --- /dev/null +++ b/karate-example/src/test/java/com/testomat/karate/KarateTest.java @@ -0,0 +1,17 @@ +package com.testomat.karate; + +import com.intuit.karate.Results; +import com.intuit.karate.Runner; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class KarateTest { + + @Test + void testAll() { + Results results = Runner.path("classpath:simple-api-test.feature") + .outputJunitXml(true) + .parallel(1); + assertTrue(results.getFailCount() == 0, results.getErrorMessages()); + } +} \ No newline at end of file diff --git a/karate-example/src/test/resources/simple-api-test.feature b/karate-example/src/test/resources/simple-api-test.feature new file mode 100644 index 0000000..c21ff77 --- /dev/null +++ b/karate-example/src/test/resources/simple-api-test.feature @@ -0,0 +1,40 @@ +Feature: Pet Store API Testing + +# This feature demonstrates proper Karate-Testomat.io integration +# Each Scenario Outline example has a unique @T... ID for proper test separation + +Background: + * url 'https://petstore.swagger.io/v2' + +Scenario Outline: Get pet by ID - Pet @ + # Test retrieving pets with different IDs and expected status codes + Given path 'pet', + When method get + Then status + # Log successful retrievals for debugging + * if ( == 200) karate.log('Pet found:', response.name) + # Log not found cases for debugging + * if ( == 404) karate.log('Pet not found for ID:', ) + +Examples: +| petId | expectedStatus | testId | +| 1 | 200 | T1a2b3c4d | +| 2 | 200 | T5e6f7g8h | +| 999 | 404 | T9i0j1k2l | + +Scenario Outline: Add new pet - @ + # Test creating new pets with different data + * def petData = { "id": , "name": "", "status": "available" } + Given path 'pet' + And request petData + When method post + Then status + # Validate response contains the pet data + * if ( == 200) match response.name == '' + * if ( == 200) match response.id == + +Examples: +| petId | petName | expectedStatus | testId | +| 1001 | Buddy | 200 | Tm3n4o5p6 | +| 1002 | Rex | 200 | Tq7r8s9t0 | +| 1003 | Fluffy | 200 | Tu1v2w3x4 | \ No newline at end of file From d8da73660ae34a5063c7811fdaae0cc9f2fe29d1 Mon Sep 17 00:00:00 2001 From: AZANIR Date: Mon, 29 Sep 2025 12:00:00 +0300 Subject: [PATCH 2/2] Add Karate integration examples with unique test IDs for Testomat.io --- karate_task_prompt.md | 139 +++++++++++++++++++++++++++++++++ karate_testomat_integration.md | 97 +++++++++++++++++++++++ 2 files changed, 236 insertions(+) create mode 100644 karate_task_prompt.md create mode 100644 karate_testomat_integration.md diff --git a/karate_task_prompt.md b/karate_task_prompt.md new file mode 100644 index 0000000..4711b1f --- /dev/null +++ b/karate_task_prompt.md @@ -0,0 +1,139 @@ +# Таска: Створення простого прикладу Karate з інтеграцією Testomat.io + +## Мета завдання +Створити простий приклад тесту на фреймворку Karate, який демонструє правильну інтеграцію з Testomat.io з використанням унікальних test ID для кожного прикладу в Scenario Outline. + +## Вимоги до реалізації + +### 1. Структура .feature файлу +Створити файл `simple-api-test.feature` з наступними компонентами: +- Feature з описом +- Background секція з базовою конфігурацією +- Scenario Outline з плейсхолдером `` в назві +- Examples таблиця з унікальними test ID + +### 2. Технічні вимоги +- **Використати Swagger Petstore API** (https://petstore.swagger.io/v2/) +- Тестувати ендпоінт `/pet/{petId}` з різними pet ID +- Кожен приклад повинен мати унікальний `@T...` ID в форматі `T[alphanumeric]` +- Examples таблиця має містити мінімум 3 різні test cases з різними pet ID та очікуваними статусами + +### 3. Структура test ID +- Формат: `T` + 8 буквено-цифрових символів (наприклад, `T1a2b3c4d`) +- Кожен ID має бути унікальний в межах проекту +- ID повинні включатись в назву сценарію через плейсхолдер + +### 4. Конкретний робочий приклад +```gherkin +Feature: Pet Store API Testing + +Background: + * url 'https://petstore.swagger.io/v2' + +Scenario Outline: Get pet by ID - Pet @ + Given path 'pet', + When method get + Then status + * if ( == 200) karate.log('Pet found:', response.name) + * if ( == 404) karate.log('Pet not found for ID:', ) + +Examples: +| petId | expectedStatus | testId | +| 1 | 200 | T1a2b3c4d | +| 999 | 404 | T5e6f7g8h | +| 123 | 200 | T9i0j1k2l | +``` + +**Альтернативний варіант з POST:** +```gherkin +Scenario Outline: Add new pet - @ + * def petData = { "id": , "name": "", "status": "available" } + Given path 'pet' + And request petData + When method post + Then status + +Examples: +| petId | petName | expectedStatus | testId | +| 1001 | Buddy | 200 | Tm3n4o5p6 | +| 1002 | Rex | 200 | Tq7r8s9t0 | +| 1003 | Fluffy | 200 | Tu1v2w3x4 | +``` + +### 5. Команди для виконання (готові до використання) +```bash +# Запуск тестів +mvn test -Dtest=KarateTest + +# Альтернативний запуск для конкретного .feature файлу +mvn test -Dkarate.options="classpath:simple-api-test.feature" + +# Імпорт результатів в Testomat.io +TESTOMATIO=your_project_key TESTOMATIO_TITLE_IDS=1 npx report-xml "target/karate-reports/**/*.xml" +``` + +**Перевірка працездатності:** +- Pet API доступне 24/7 без аутентифікації +- Pet ID 1-10 зазвичай існують в системі (статус 200) +- Pet ID 999+ зазвичай не існують (статус 404) +- POST запити створюють нові записи + +### 6. Мінімальне налаштування проекту +**pom.xml dependencies:** +```xml + + com.intuit.karate + karate-junit5 + 1.4.1 + test + +``` + +**KarateTest.java runner:** +```java +@Test +void testAll() { + Results results = Runner.path("classpath:simple-api-test.feature") + .outputJunitXml(true) + .parallel(1); + assertTrue(results.getFailCount() == 0, results.getErrorMessages()); +} +``` + +### 7. Додаткові вимоги +- Додати коментарі в .feature файлі, що пояснюють логіку +- Створити простий приклад без складних залежностей +- Забезпечити, щоб тест можна було запустити "з коробки" + +## Критерії приймання +- [ ] .feature файл створено з використанням Swagger Petstore API +- [ ] Тести реально працюють при запуску (перевірено на Pet API) +- [ ] Кожен приклад має унікальний test ID у форматі T[8 символів] +- [ ] Test ID включені в назви сценаріїв через плейсхолдери `@` +- [ ] Examples таблиця містить робочі pet ID з правильними очікуваними статусами +- [ ] При запуску генерується JUnit XML з унікальними testcase назвами +- [ ] Додані команди Maven для запуску та NPX для імпорту +- [ ] Код добре документований та готовий до використання +- [ ] **ВАЖЛИВО:** Приклад протестований та гарантовано працює + +## Додаткові матеріали +- Базуватись на документації про інтеграцію Karate з Testomat.io +- Використовувати TESTOMATIO_TITLE_IDS=1 для правильного розпізнавання тестів +- Уникати статичних тегів @T... над Scenario Outline + +## Приклад очікуваного використання +Після виконання таски розробник повинен мати готовий .feature файл, який можна: +1. **Запустити локально та отримати успішні результати** (Pet API завжди доступне) +2. Отримати JUnit XML звіт з унікальними назвами testcase +3. Імпортувати в Testomat.io з правильним розділенням тестів на окремі записи + +**🔥 КРИТИЧНО ВАЖЛИВО:** +- Приклад ОБОВ'ЯЗКОВО має бути протестований перед здачею +- Використовувати Pet ID, які гарантовано працюють (1-10 для 200, 999+ для 404) +- Переконатися, що XML містить правильні @T... теги в назвах + +**Термін виконання:** [вказати термін] +**Відповідальний:** [вказати виконавця] + +--- +*Цей приклад базується на реальному Pet Store API та гарантовано працює при правильній реалізації.* \ No newline at end of file diff --git a/karate_testomat_integration.md b/karate_testomat_integration.md new file mode 100644 index 0000000..5ee545f --- /dev/null +++ b/karate_testomat_integration.md @@ -0,0 +1,97 @@ +# Integrating Karate with Testomat.io — Unique `testId` for Scenario Outline Examples + +## Overview + +By default, Karate Scenario Outline examples generate multiple `` entries within the same ``, often with identical `@T…` test IDs. If you import the JUnit XML into Testomat.io using `TESTOMATIO_TITLE_IDS=1`, those examples are merged into a single test with multiple retries. + +To ensure each example appears as a distinct test, assign a **unique `@T…` ID** in the scenario title using placeholders from the `Examples` table. + +--- + +## Recommended `.feature` File Structure + +```gherkin +Feature: Timestamp API + +Background: + * url api_host_proxy + * def pdf = { read: 'classpath:apiTests/assets/contract.pdf', filename: 'contract.pdf', contentType: 'multipart/form-data' } + +Scenario Outline: Add a timestamp signature – @ + * def tokenResult = karate.call('classpath:apiTests/support/generate_jwt_token.feature', { tenant: }) + * def jwtToken = tokenResult.jwtToken + Given path 'timestamp/documents' + And header Authorization = 'Bearer ' + jwtToken + And multipart file files = pdf + When method post + Then status + +Examples: +| env | tenantId | expectedStatus | testId | +| gcpdev | tenant_id | 200 | T49e2ba77 | +| sandbox | tenant_sandbox_id | 400 | T8a1bc222 | +``` + +### Why This Works + +- The `` placeholder is replaced from the `Examples` table, ensuring each example carries a unique `@T…`. +- The XML report generates distinct `` names (e.g., `... @T49e2ba77`, `... @T8a1bc222`), allowing Testomat.io to import them as **separate tests** rather than retries. + +--- + +## Running Tests and Importing to Testomat.io + +```bash +mvn test -Dkarate.env=$env -Dtest=KarateTest + +TESTOMATIO=your_key_here TESTOMATIO_TITLE_IDS=1 npx report-xml "target/karate-reports/**/*.xml" +``` + +- Using `TESTOMATIO_TITLE_IDS=1` ensures Testomat.io bases test identification on the `@T…` in the scenario title. + +--- + +## Best Practices + +- **Avoid static tags** like `@T…` placed above the Scenario Outline—they apply to all examples identically and defeat uniqueness. +- Each `testId` should be: + - **Unique** within the project. + - Begin with `T` and contain alphanumeric characters (e.g., `T1a2b3c4d`). + - When referencing existing tests in Testomat.io, reuse their `@T` IDs to maintain continuity. +- For brand‑new tests, generate and use fresh, unique IDs consistently moving forward. + +--- + +## Alternative Without `testId` + +If you'd prefer not to use IDs: + +1. Import without `TESTOMATIO_TITLE_IDS=1`. +2. Ensure scenario titles are inherently unique (e.g., include ``). + +```gherkin +Scenario Outline: Add a timestamp signature – +``` + +Testomat.io will then differentiate tests based on the full name—though without ID mapping. + +--- + +## Implementation Checklist + +| Step | Action | +|------|--------| +| 1. | Identify existing Testomat.io tests and copy their `@T` IDs. | +| 2. | Populate the `testId` column in `.feature` files accordingly or generate new ones. | +| 3. | Ensure all `testId`s are unique. | +| 4. | Run tests and import using `TESTOMATIO_TITLE_IDS=1`. | +| 5. | Verify in Testomat.io that each example appears as a distinct test. | + +--- + +## Summary + +- Use `TESTOMATIO_TITLE_IDS=1` with unique `@T` per example to achieve one-to-one mapping. +- This approach ensures clean test tracking and reliable linking in Testomat.io. +- If not using IDs, rely on unique scenario names, though mapping precision is reduced. +