enterprise-integration-testing について
SAP連携システムやシステム間の業務フローをテストするためのスキルです。プロトコルに応じたエージェント選定を案内し、連携境界、データ整合性、リリース基準を検証します。
主な機能
- 01エンドツーエンド業務フローの整理
- 02連携プロトコル別のエージェント選定
- 03契約とデータの検証
- 04システム間データ整合性の確認
- 05エラー復旧と認可のテスト
- 06企業向けリリース基準の設定
活用シーン
- 01SAP連携システムのテスト
- 02受注から入金までのフロー検証
- 03SAP、WMS、CRM間のデータ照合
- 04企業リリース準備状況の評価
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ proffesor-for-testing/ agentic-qe --skill enterprise-integration-testingインストール後、Claude Code で/enterprise-integration-testingを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
evals/enterprise-integration-testing.yamlschemas/output.jsonscripts/validate-config.json詳細
エンタープライズ統合テスト
ブラウザーエンジン
UI レベルのエンタープライズ統合チェック(SAP Fiori ローンチパッドのスモークテスト、管理 UI の検証)には、qe-browser フリートスキルを使用してください。RFC/BAPI/IDoc/OData/SOAP のテストには、引き続き専用の qe-soap-tester、qe-sap-rfc-tester、qe-sap-idoc-tester、qe-odata-contract-tester エージェントを使用します。.claude/skills/qe-browser/SKILL.md を参照してください。
<default_to_action> エンタープライズ統合または SAP 接続システムをテストする場合:
- エンドツーエンドのフローを把握します(Web -> API -> ミドルウェア -> バックエンド -> レスポンス)
- 統合ポイントとプロトコルを特定します(REST、SOAP、RFC、IDoc、OData、EDI)
- 統合タイプごとに適切なエージェントを選択します
- 各統合境界をコントラクトとデータの検証によってテストします
- システム間のデータ整合性を検証します(SAP <-> WMS <-> ミドルウェア)
- エンタープライズのエラー処理を実行します(補償、再試行、アラート)
- エンタープライズ固有の品質基準でリリースを判定します
エージェント選択ガイド:
- SAP RFC/BAPI 呼び出し ->
qe-sap-rfc-tester - SAP IDoc フロー ->
qe-sap-idoc-tester - OData/Fiori サービス ->
qe-odata-contract-tester - SOAP/ESB エンドポイント ->
qe-soap-tester - メッセージブローカーフロー ->
qe-message-broker-tester - ミドルウェアのルーティング/変換 ->
qe-middleware-validator - 認可/SoD の競合 ->
qe-sod-analyzer
重要な成功要因:
- エンタープライズテストはシステム横断で行います。単独のシステムだけをテストすることはありません
- システム間のデータ整合性が、最も重要な品質指標です
- 環境へのアクセスとテストデータが、最大のボトルネックです </default_to_action>
クイックリファレンスカード
使用する場面
- SAP 接続エンタープライズシステム(S/4HANA、ECC、BW)のテスト
- エンドツーエンドのビジネスプロセス(受注から入金まで、調達から支払いまで)の検証
- ミドルウェア/ESB 統合(IIB、MuleSoft、SAP PI/PO)のテスト
- システム間のデータ照合(SAP <-> WMS <-> CRM)
- エンタープライズリリースの準備状況評価
エンタープライズ統合タイプ
| 統合 | プロトコル | エージェント | 典型的な用途 |
|---|---|---|---|
| SAP RFC/BAPI | RFC | qe-sap-rfc-tester | SAP 関数のリアルタイム呼び出し |
| SAP IDoc | ALE/EDI | qe-sap-idoc-tester | 非同期のドキュメント交換 |
| SAP OData | REST/OData | qe-odata-contract-tester | Fiori アプリ、外部 API |
| SOAP/ESB | SOAP/HTTP | qe-soap-tester | レガシーサービスの統合 |
| メッセージブローカー | AMQP/JMS | qe-message-broker-tester | 非同期メッセージング(MQ、Kafka) |
| ミドルウェア | 各種 | qe-middleware-validator | ルーティング、変換 |
| 認可 | SAP Auth | qe-sod-analyzer | SoD の競合、ロールテスト |
重要なテストシナリオ
| シナリオ | 必須テスト | 例 |
|---|---|---|
| E2E 注文フロー | 注文のライフサイクル全体 | Web 注文 -> SAP 販売伝票 -> WMS ピッキング -> 出荷 -> 請求書 |
| データ整合性 | システム間の一致 | SAP 在庫 = WMS 在庫 |
| IDoc 処理 | インバウンド/アウトバウンド | 購買発注 IDoc -> SAP 購買発注の作成 |
| 認可 | SoD 準拠 | ユーザーは購買発注の作成と承認を両方行えない |
| エラー回復 | 補償 | 支払い失敗 -> 在庫引当の取り消し |
| マスターデータ同期 | レプリケーションの正確性 | SAP の品目マスター = WMS の製品 |
ツール
- SAP:SAP GUI、トランザクションコード(SE37、WE19、SEGW)、Eclipse ADT
- ミドルウェア:IBM IIB/ACE、MuleSoft、SAP PI/PO/CPI
- テスト:SoapUI、Postman、qe-browser(Fiori/Web UI には Vibium 経由)、カスタムハーネス
- モニタリング:SAP Solution Manager、Splunk、Dynatrace
- データ:SAP LSMW、SECATT、eCATT
エージェントの連携
qe-sap-rfc-tester:SAP RFC/BAPI 関数モジュールのテストqe-sap-idoc-tester:IDoc のインバウンド/アウトバウンド処理の検証qe-odata-contract-tester:OData サービスのコントラクトと Fiori アプリのテストqe-soap-tester:SOAP/WSDL コントラクトの検証と WS-Securityqe-message-broker-tester:メッセージブローカーのフロー、DLQ、順序制御qe-middleware-validator:ESB のルーティング、変換、EIP パターンqe-sod-analyzer:職務分掌と認可のテスト
エンタープライズ E2E フローテスト
受注から入金までのフロー
describe('Order-to-Cash E2E Flow', () => {
it('processes web order through SAP to warehouse fulfillment', async () => {
// Step 1: Create order via web API
const webOrder = await api.post('/orders', {
customerId: 'CUST-1000',
items: [{ materialNumber: 'MAT-500', quantity: 10 }],
shippingAddress: { city: 'Portland', state: 'OR' }
});
expect(webOrder.status).toBe(201);
const webOrderId = webOrder.body.orderId;
// Step 2: Verify SAP Sales Order created via middleware
const sapOrder = await sapClient.call('BAPI_SALESORDER_GETLIST', {
CUSTOMER_NUMBER: 'CUST-1000',
SALES_ORGANIZATION: '1000'
});
const matchingSapOrder = sapOrder.find(o => o.PURCHASE_ORDER_NO === webOrderId);
expect(matchingSapOrder).toBeDefined();
const sapOrderId = matchingSapOrder.SD_DOC;
// Step 3: Verify WMS received pick instruction
const wmsPickTask = await wmsApi.get(`/pick-tasks?externalRef=${sapOrderId}`);
expect(wmsPickTask.status).toBe(200);
expect(wmsPickTask.body.status).toBe('PENDING');
// Step 4: Complete pick in WMS
await wmsApi.post(`/pick-tasks/${wmsPickTask.body.taskId}/complete`, {
pickedItems: [{ sku: 'MAT-500', quantity: 10, location: 'A-01-03' }]
});
// Step 5: Verify SAP delivery created (via IDoc confirmation)
await waitFor(async () => {
const delivery = await sapClient.call('BAPI_DELIVERYPROCESSING_GETLIST', {
SALES_ORDER: sapOrderId
});
return delivery.length > 0 && delivery[0].DELVRY_STATUS === 'C';
}, { timeout: 30000, interval: 3000 });
// Step 6: Verify invoice posted in SAP
await waitFor(async () => {
const invoice = await sapClient.call('BAPI_BILLINGDOC_GETLIST', {
REFDOCNUMBER: sapOrderId
});
return invoice.length > 0;
}, { timeout: 30000, interval: 3000 });
});
});
調達から支払いまでのフロー
describe('Procure-to-Pay E2E Flow', () => {
it('creates purchase requisition through to vendor payment', async () => {
// Step 1: Create Purchase Requisition
const prResult = await sapClient.call('BAPI_PR_CREATE', {
PRHEADER: { PR_TYPE: 'NB', CTRL_IND: '' },
PRHEADERX: { PR_TYPE: 'X' },
PRITEMS: [{ MATERIAL: 'MAT-RAW-100', QUANTITY: 500, UNIT: 'EA', PLANT: '1000' }]
});
expect(prResult.NUMBER).toBeDefined();
const prNumber = prResult.NUMBER;
// Step 2: Verify PR triggers sourcing (ME57 equivalent)
const sourcingResult = await sapClient.call('BAPI_PR_GETDETAIL', {
NUMBER: prNumber
});
expect(sourcingResult.PRITEM[0].PREQ_NO).toBe(prNumber);
// Step 3: Create Purchase Order from PR
const poResult = await sapClient.call('BAPI_PO_CREATE1', {
POHEADER: { COMP_CODE: '1000', DOC_TYPE: 'NB', VENDOR: 'VEND-500' },
POITEMS: [{ PO_ITEM: '00010', MATERIAL: 'MAT-RAW-100', QUANTITY: 500, PLANT: '1000' }]
});
expect(poResult.PO_NUMBER).toBeDefined();
// Step 4: Verify PO IDoc sent to vendor
const idocStatus = await sapClient.call('IDOC_STATUS_READ', {
DOCNUM: poResult.IDOC_NUMBER
});
expect(idocStatus.STATUS).toBe('03'); // Successfully sent
});
});
SAP 固有のテストパターン
RFC/BAPI テスト
describe('SAP RFC/BAPI Testing', () => {
it('validates BAPI return structure and error handling', async () => {
// Test with valid input
const result = await sapClient.call('BAPI_MATERIAL_GETDETAIL', {
MATERIAL: 'MAT-EXIST'
});
expect(result.RETURN.TYPE).not.toBe('E');
expect(result.MATERIAL_GENERAL_DATA.MATL_DESC).toBeDefined();
// Test with invalid material
const errorResult = await sapClient.call('BAPI_MATERIAL_GETDETAIL', {
MATERIAL: 'MAT-NONEXIST'
});
expect(errorResult.RETURN.TYPE).toBe('E');
expect(errorResult.RETURN.MESSAGE).toContain('does not exist');
});
it('handles BAPI commit correctly', async () => {
const createResult = await sapClient.call('BAPI_SALESORDER_CREATEFROMDAT2', {
ORDER_HEADER_IN: {
DOC_TYPE: 'OR',
SALES_ORG: '1000',
DISTR_CHAN: '10',
DIVISION: '00'
},
ORDER_PARTNERS: [{ PARTN_ROLE: 'AG', PARTN_NUMB: 'CUST-1000' }],
ORDER_ITEMS_IN: [{ MATERIAL: 'MAT-500', TARGET_QTY: 10 }]
});
// Must call BAPI_TRANSACTION_COMMIT to persist
await sapClient.call('BAPI_TRANSACTION_COMMIT', { WAIT: 'X' });
// Verify order exists after commit
const getResult = await sapClient.call('BAPI_SALESORDER_GETDETAIL', {
SALESDOCUMENT: createResult.SALESDOCUMENT
});
expect(getResult.ORDER_HEADER_OUT.SD_DOC_CAT).toBe('C');
});
});
IDoc テスト
describe('SAP IDoc Processing', () => {
it('validates inbound IDoc creates correct SAP document', async () => {
// Send IDoc via middleware
const idocPayload = {
IDOCTYP: 'ORDERS05',
MESTYP: 'ORDERS',
SNDPOR: 'SAPEXT',
SNDPRT: 'LS',
SNDPRN: 'EXTERN',
RCVPOR: 'SAPSI1',
RCVPRT: 'LS',
RCVPRN: 'SAPCLNT100',
segments: {
E1EDK01: { BELNR: 'EXT-PO-001' },
E1EDK14: [{ QUESSION: '001', ORGID: '1000' }],
E1EDP01: [{ POSEX: '000010', MENGE: '100', MENEE: 'EA', MATNR: 'MAT-500' }]
}
};
const idocNumber = await middlewareClient.sendIDoc(idocPayload);
// Wait for IDoc processing in SAP
await waitFor(async () => {
const status = await sapClient.call('IDOC_STATUS_READ', { DOCNUM: idocNumber });
return status.STATUS === '53'; // Application document posted successfully
}, { timeout: 60000, interval: 5000 });
// Verify SAP document was created
const sapDoc = await sapClient.call('BAPI_SALESORDER_GETLIST', {
PURCHASE_ORDER_NO: 'EXT-PO-001'
});
expect(sapDoc).toHaveLength(1);
});
it('handles IDoc error status correctly', async () => {
// Send IDoc with invalid material
const idocPayload = buildIdocPayload({ materialNumber: 'INVALID-MAT' });
const idocNumber = await middlewareClient.sendIDoc(idocPayload);
await waitFor(async () => {
const status = await sapClient.call('IDOC_STATUS_READ', { DOCNUM: idocNumber });
return ['51', '56'].includes(status.STATUS); // Error statuses
}, { timeout: 60000 });
const status = await sapClient.call('IDOC_STATUS_READ', { DOCNUM: idocNumber });
expect(status.STATUS_TEXT).toContain('Material');
});
});
OData サービスのテスト
describe('SAP OData Service Testing', () => {
it('validates OData entity CRUD operations', async () => {
// CREATE
const createResponse = await odataClient.post('/sap/opu/odata/sap/API_SALES_ORDER_SRV/A_SalesOrder', {
SalesOrderType: 'OR',
SalesOrganization: '1000',
DistributionChannel: '10',
OrganizationDivision: '00',
SoldToParty: 'CUST-1000'
});
expect(createResponse.status).toBe(201);
const salesOrder = createResponse.body.d.SalesOrder;
// READ with $expand
const readResponse = await odataClient.get(
`/sap/opu/odata/sap/API_SALES_ORDER_SRV/A_SalesOrder('${salesOrder}')?$expand=to_Item`
);
expect(readResponse.status).toBe(200);
expect(readResponse.body.d.SalesOrder).toBe(salesOrder);
// READ collection with $filter
const listResponse = await odataClient.get(
`/sap/opu/odata/sap/API_SALES_ORDER_SRV/A_SalesOrder?$filter=SoldToParty eq 'CUST-1000'&$top=10`
);
expect(listResponse.status).toBe(200);
expect(listResponse.body.d.results.length).toBeGreaterThan(0);
});
it('validates OData $metadata contract', async () => {
const metadata = await odataClient.get(
'/sap/opu/odata/sap/API_SALES_ORDER_SRV/$metadata'
);
expect(metadata.status).toBe(200);
const parsedMetadata = parseEdmx(metadata.body);
expect(parsedMetadata.entityTypes).toContain('A_SalesOrder');
expect(parsedMetadata.entityTypes).toContain('A_SalesOrderItem');
// Validate required properties exist
const salesOrderType = parsedMetadata.getEntityType('A_SalesOrder');
expect(salesOrderType.properties).toContain('SalesOrder');
expect(salesOrderType.properties).toContain('SalesOrderType');
expect(salesOrderType.navigationProperties).toContain('to_Item');
});
});
Fiori Launchpad のテスト
describe('Fiori Launchpad App Testing', () => {
it('validates Fiori tile loads and displays correct data', async () => {
await page.goto(`${fioriLaunchpadUrl}#SalesOrder-manage`);
// Wait for OData call to complete
await page.waitForResponse(resp =>
resp.url().includes('API_SALES_ORDER_SRV') && resp.status() === 200
);
// Verify smart table loaded with data
const tableRows = await page.locator('table tbody tr');
expect(await tableRows.count()).toBeGreaterThan(0);
// Verify filter bar is functional
await page.fill('[data-sap-ui="filterField-SalesOrder"]', '1000000');
await page.click('[data-sap-ui="btnGo"]');
await page.waitForResponse(resp =>
resp.url().includes("$filter=SalesOrder eq '1000000'")
);
});
});
システム間のデータ検証
describe('Cross-System Data Consistency', () => {
it('SAP inventory matches WMS inventory', async () => {
const materials = ['MAT-100', 'MAT-200', 'MAT-300'];
for (const material of materials) {
// Get SAP stock
const sapStock = await sapClient.call('BAPI_MATERIAL_STOCK_REQ_LIST', {
MATERIAL: material,
PLANT: '1000'
});
const sapQuantity = parseFloat(sapStock.TOTAL_STOCK);
// Get WMS inventory
const wmsInventory = await wmsApi.get(`/inventory/${material}`);
const wmsQuantity = wmsInventory.body.availableQuantity;
expect(wmsQuantity).toBe(sapQuantity);
}
});
it('customer master data is consistent across systems', async () => {
const customerId = 'CUST-1000';
const sapCustomer = await sapClient.call('BAPI_CUSTOMER_GETDETAIL', {
CUSTOMERNO: customerId
});
const crmCustomer = await crmApi.get(`/customers/${customerId}`);
const wmsCustomer = await wmsApi.get(`/customers/${customerId}`);
// Core fields must match
expect(crmCustomer.body.name).toBe(sapCustomer.CUSTOMER_GENERAL_DATA.NAME);
expect(wmsCustomer.body.name).toBe(sapCustomer.CUSTOMER_GENERAL_DATA.NAME);
expect(crmCustomer.body.taxId).toBe(sapCustomer.CUSTOMER_GENERAL_DATA.TAX_NUMBER);
});
it('order status is synchronized across all systems', async () => {
const orderId = 'ORD-SYNC-TEST';
// Create order and wait for propagation
await api.post('/orders', { orderId, customerId: 'CUST-1000', items: [{ sku: 'MAT-100', qty: 5 }] });
await sleep(10000); // Allow for async propagation
const webStatus = (await api.get(`/orders/${orderId}`)).body.status;
const sapStatus = (await sapClient.call('BAPI_SALESORDER_GETDETAIL', {
SALESDOCUMENT: orderId
})).ORDER_HEADER_OUT.DOC_STATUS;
const wmsStatus = (await wmsApi.get(`/orders/${orderId}`)).body.status;
// All systems should reflect same logical status
expect(mapSapStatus(sapStatus)).toBe(webStatus);
expect(mapWmsStatus(wmsStatus)).toBe(webStatus);
});
});
エンタープライズのテストデータ管理
describe('Enterprise Test Data Strategy', () => {
// Master data setup - reusable across test suites
const masterDataFixture = {
async setup() {
// Create customer in SAP (source of truth)
const customer = await sapClient.call('BAPI_CUSTOMER_CREATE', {
PI_COPYREFERENCE: { SALESORG: '1000', DISTR_CHAN: '10' },
PI_PERSONALDATA: { FIRSTNAME: 'Test', LASTNAME: `Customer-${Date.now()}` }
});
await sapClient.call('BAPI_TRANSACTION_COMMIT', { WAIT: 'X' });
// Wait for replication to downstream systems
await waitFor(async () => {
const wms = await wmsApi.get(`/customers/${customer.CUSTOMERNO}`);
return wms.status === 200;
}, { timeout: 60000 });
return { customerId: customer.CUSTOMERNO };
},
async teardown(customerId) {
// Mark customer for deletion (SAP does not hard delete)
await sapClient.call('BAPI_CUSTOMER_CHANGEFROMDATA', {
CUSTOMERNO: customerId,
PI_PERSONALDATA: { DELETION_FLAG: 'X' }
});
await sapClient.call('BAPI_TRANSACTION_COMMIT', { WAIT: 'X' });
}
};
let testCustomer;
beforeAll(async () => {
testCustomer = await masterDataFixture.setup();
});
afterAll(async () => {
await masterDataFixture.teardown(testCustomer.customerId);
});
it('uses properly replicated test customer', async () => {
const order = await api.post('/orders', {
customerId: testCustomer.customerId,
items: [{ sku: 'MAT-100', qty: 1 }]
});
expect(order.status).toBe(201);
});
});
環境戦略
エンタープライズ環境マトリクス
| 環境 | 目的 | データ | SAP クライアント | アクセス |
|---|---|---|---|---|
| サンドボックス(SBX) | 開発者による探索 | サンプルデータ | 100 | オープン |
| 開発(DEV) | 機能開発 | 合成データ | 200 | 開発チーム |
| 統合(INT) | システム横断テスト | 管理されたデータセット | 300 | QE + 開発チーム |
| 品質(QAS) | リリース検証 | 本番相当のデータ | 400 | QE のみ |
| 本番前(PRE) | 最終確認 | マスキング済みの本番コピー | 500 | リリースチーム |
| 本番(PRD) | 稼働システム | 実データ | 600 | 運用チーム |
// Environment-aware test configuration
const envConfig = {
INT: {
sapClient: '300',
sapHost: 'sap-int.company.com',
wmsHost: 'wms-int.company.com',
middlewareHost: 'esb-int.company.com',
testDataStrategy: 'synthetic', // Create and teardown
maxParallelTests: 5
},
QAS: {
sapClient: '400',
sapHost: 'sap-qas.company.com',
wmsHost: 'wms-qas.company.com',
middlewareHost: 'esb-qas.company.com',
testDataStrategy: 'reserved-sets', // Pre-allocated test data
maxParallelTests: 3
}
};
function getTestConfig() {
const env = process.env.TEST_ENVIRONMENT || 'INT';
return envConfig[env];
}
エンタープライズの品質ゲート
エンタープライズシステムの QCSD フラグ
const enterpriseFlags = {
HAS_MIDDLEWARE: true, // ESB/middleware in the flow
HAS_SAP_INTEGRATION: true, // SAP RFC/BAPI/IDoc/OData calls
HAS_AUTHORIZATION: true, // SoD and role-based access
HAS_CROSS_SYSTEM_DATA: true, // Data replicated across systems
HAS_ASYNC_PROCESSING: true, // IDoc, message queue, batch jobs
HAS_LEGACY_PROTOCOL: true // SOAP, RFC, flat-file, EDI
};
リリース準備完了の基準
describe('Enterprise Release Readiness', () => {
it('passes all enterprise quality gates', async () => {
const gates = [
{
name: 'Cross-System Data Consistency',
check: async () => {
const results = await runDataReconciliation(['MAT-100', 'MAT-200']);
return results.every(r => r.consistent);
}
},
{
name: 'IDoc Processing Success Rate',
check: async () => {
const stats = await sapClient.call('IDOC_STATUS_SUMMARY', { PERIOD: 'LAST_24H' });
const successRate = stats.SUCCESS / stats.TOTAL;
return successRate >= 0.99; // 99% threshold
}
},
{
name: 'Middleware Error Rate',
check: async () => {
const errors = await middlewareMonitor.getErrorCount({ period: '24h' });
return errors < 10; // Less than 10 errors in 24h
}
},
{
name: 'SoD Violations',
check: async () => {
const violations = await sodAnalyzer.scan({ scope: 'changed-roles' });
return violations.critical === 0;
}
},
{
name: 'E2E Order Flow',
check: async () => {
const result = await runE2EOrderFlow();
return result.allStepsCompleted && result.duration < 120000; // Under 2 minutes
}
}
];
for (const gate of gates) {
const passed = await gate.check();
expect(passed).toBe(true);
}
});
});
ベストプラクティス
実施すること
- テストを書く前に E2E フロー全体をマッピングします
- 各統合境界を個別に、かつエンドツーエンドでテストします
- SAP に対応したテストデータ管理を使用します(BAPI で作成、使用、後処理を行います)
- 統合イベントのたびに、すべてのシステム間でデータの整合性を検証します
- テストアサーションに IDoc ステータスの監視を含めます
- すべてのエンタープライズリリースゲートの一環として、認可(職務分掌)をテストします
- プロビジョニングが難しいシステムにはサービス仮想化を使用します
避けること
- API レベルのテストをせず、UI(Fiori/SAP GUI)だけで SAP をテストすること
- IDoc のエラーステータス(51、56)を無視し、正常系だけを確認すること
- 予約の仕組みなしで、チーム間でテストデータを共有すること
- サンドボックス環境だけでエンタープライズフローをテストすること
- 作成/更新 BAPI の後に BAPI_TRANSACTION_COMMIT を実行しないこと
- システム間のデータが即時に整合すると想定すること(非同期の伝播を考慮します)
- 変更した認可ロールの職務分掌への準拠を確認せずにデプロイすること
エージェント支援によるエンタープライズテスト
// SAP RFC/BAPI function testing
await Task("SAP BAPI Validation", {
bapis: ['BAPI_SALESORDER_CREATEFROMDAT2', 'BAPI_SALESORDER_GETDETAIL'],
testScenarios: ['valid-input', 'missing-required', 'invalid-customer', 'commit-rollback'],
validateReturnStructure: true
}, "qe-sap-rfc-tester");
// IDoc processing validation
await Task("IDoc Flow Validation", {
idocType: 'ORDERS05',
direction: 'inbound',
testStatuses: ['53-success', '51-application-error', '56-syntax-error'],
validateSapDocument: true
}, "qe-sap-idoc-tester");
// OData contract testing
await Task("OData Service Contract Test", {
serviceUrl: '/sap/opu/odata/sap/API_SALES_ORDER_SRV',
validateMetadata: true,
testCrud: true,
testFilters: ['$filter', '$expand', '$orderby', '$top', '$skip'],
checkBackwardCompatibility: true
}, "qe-odata-contract-tester");
// SOAP service validation
await Task("SOAP Service Validation", {
wsdl: 'services/OrderService.wsdl',
operations: ['CreateOrder', 'GetOrderStatus'],
testWsSecurity: true,
testFaultCodes: true
}, "qe-soap-tester");
// Middleware flow validation
await Task("Middleware Integration Test", {
flow: 'order-to-cash',
stages: ['web-api', 'esb-routing', 'sap-rfc', 'wms-api'],
testDLQ: true,
testCompensation: true,
validateCorrelationIds: true
}, "qe-middleware-validator");
// Message broker testing
await Task("Message Broker Validation", {
broker: 'ibm-mq',
queues: ['orders.inbound', 'orders.sap', 'orders.wms', 'orders.dlq'],
testOrdering: true,
testRetry: true
}, "qe-message-broker-tester");
// Segregation of Duties analysis
await Task("SoD Conflict Analysis", {
scope: 'changed-roles',
ruleSet: 'sap-standard',
criticalTransactions: ['ME21N', 'ME29N', 'MIRO', 'FB60'],
reportFormat: 'matrix'
}, "qe-sod-analyzer");
エージェント連携のヒント
メモリの名前空間
aqe/enterprise-integration/
flows/ - E2E flow definitions and test results
sap/
rfc-results/ - RFC/BAPI test outcomes
idoc-results/ - IDoc processing validation
odata-contracts/ - OData $metadata snapshots and diffs
middleware/
routing/ - ESB routing test results
transforms/ - Transformation validation
cross-system/
reconciliation/ - Data consistency reports
master-data/ - Master data sync validation
authorization/
sod-reports/ - SoD conflict analysis results
role-testing/ - Role and permission test results
quality-gates/ - Enterprise release gate results
フリートの連携
const enterpriseFleet = await FleetManager.coordinate({
strategy: 'enterprise-integration',
agents: [
'qe-sap-rfc-tester', // SAP function module testing
'qe-sap-idoc-tester', // IDoc processing validation
'qe-odata-contract-tester', // OData/Fiori service testing
'qe-soap-tester', // SOAP/ESB endpoint testing
'qe-message-broker-tester', // Message broker flows
'qe-middleware-validator', // Middleware routing/transformation
'qe-sod-analyzer' // Authorization and SoD
],
topology: 'hierarchical'
});
await enterpriseFleet.execute({
flow: 'order-to-cash',
phases: [
{ name: 'contract-validation', agents: ['qe-odata-contract-tester', 'qe-soap-tester'] },
{ name: 'integration-testing', agents: ['qe-sap-rfc-tester', 'qe-sap-idoc-tester', 'qe-middleware-validator'] },
{ name: 'e2e-validation', agents: ['qe-message-broker-tester'] },
{ name: 'authorization-check', agents: ['qe-sod-analyzer'] }
]
});
関連スキル
- api-testing-patterns - REST/GraphQL API テストの基礎
- contract-testing - Pact を使用したコンシューマー駆動コントラクトテスト
- middleware-testing-patterns - ESB、ルーティング、変換、DLQ
- wms-testing-patterns - 倉庫管理システムのテスト
- chaos-engineering-resilience - エンタープライズシステム向けのフォールトインジェクション
- database-testing - データベースの整合性とマイグレーションのテスト
- security-testing - セキュリティと認可のテスト
覚えておくこと
エンタープライズ統合テストでは、それぞれ単独では正しく動作するシステム同士が、連携時にも正しく動作することを検証します。システムは単独で存在するものではありません。各統合境界をプロトコルに適したツールでテストし、システム間のデータ整合性を検証して、必ず認可と職務分掌(SoD)のチェックを含めます。最大のリスクは、システム内部ではなく、システム間のつなぎ目にあります。
エージェントの活用: RFC、IDoc、OData、SOAP、メッセージングなど、統合の種類ごとに特化したエージェントを使用します。階層的にオーケストレーションします。まずコントラクト検証、次に統合テスト、その後に E2E フロー、最後に認可を行います。エンタープライズのエージェント群は、単一システムのテストではまったく検出できないシステム間の不整合を検出します。