Lesson 2 of 5
Self-contained tests
19 min
Listen to this lesson
A self-contained test creates the data it needs, uses it, and leaves the system in a known state. It does not depend on what another test or a person did earlier. The ISTQB Test Automation Engineering syllabus (v2.0) describes this use of automation explicitly: test scripts that create test data can be placed in a setup step, and cleanup can follow the run. For SAP the question is not whether to do this, but for which objects and through which interface.
Arrange, act, assert, clean up
- ArrangeCreate or find prerequisite data: business partner, product extension, stock, conditions. Record every key created.
- ActRun the business step under test through the UI or service, exactly as a user or interface would.
- AssertCheck the business outcome: document created, status, amounts, follow-on documents.
- Clean upReverse, cancel, block or mark the data so it cannot disturb later runs.
- EvidenceWrite the keys, timestamps and results to the log so a failure can be traced.
Contoso's order-to-cash regression test is a good example. The old version opened sales order entry for customer Great Lakes Fleet Services and material CMC-ALT-100 and hoped both were in good shape. The new version first creates a fresh customer through the business partner API with the sales area 1710 / 10 / 00 extension, then confirms the material is sellable and has stock, then runs the order through the Fiori app, the delivery and billing, and finally blocks the test customer for further sales so nobody else uses it.
Which interface creates the data
Creating data through the user interface is slow and fragile; that is the very thing you are trying to test, not the thing you want in your setup. Prefer service-level creation. SAP S/4HANA exposes released APIs for most master and transactional data, listed on the SAP Business Accelerator Hub. Common choices include the Business Partner API (API_BUSINESS_PARTNER), the Product Master API and the Sales Order API (API_SALES_ORDER_SRV). For on-premise and private cloud systems, BAPIs such as BAPI_GOODSMVT_CREATE for goods movements are a long-standing alternative. Check which APIs are released for your release and which fields and movement types each one supports before you build on it; some APIs reject fields or movement types they do not support.
| Option | Speed and stability | Watch out for |
|---|---|---|
| Released OData or SOAP API | Fast, stable contract, versioned | Field and scenario coverage varies by API; needs a technical user with the right roles |
| BAPI or function module via RFC | Fast, mature, wide coverage on-premise | Commit handling (BAPI_TRANSACTION_COMMIT); not available in the public cloud |
| Custom data helper (ABAP class) | Fast and tailored | Must be maintained, transported and kept out of production |
| UI-driven setup | Slow and brittle | Turns every UI change into a setup failure; use only when no service exists |
What not to create inside the test
Some data is too expensive or too risky to create per run. Organizational units, company code settings, plants, pricing procedures, account determination and output configuration are configuration, delivered by transport. Tests should rely on them and check them at the start of a run, not create them. Large master data such as a product with full MRP, costing and valuation views is borderline: creating it is possible but slow, so many teams create one product per release cycle and reuse it, keeping only the transactional data per run.
Make the data unique and traceable
Every record a test creates should carry a run reference: a search term, an external reference field or a naming pattern such as AUTO-<run id>. This lets parallel runs avoid each other, lets cleanup jobs find leftovers, and lets an analyst link a failed test to the exact documents it touched. Avoid encoding meaning in the generated keys themselves; the number range decides the key and you read it back from the API response.
What would you do?
Kenji proposes that every regression test creates its own plant and storage location so tests are fully isolated. What is the best response?
- A self-contained test arranges its own data, acts, asserts the business outcome and cleans up.
- Create prerequisite data through released APIs or BAPIs, not through the UI under test.
- Wrap creation in a reusable data factory so changes are fixed in one place.
- Configuration and org units are verified, not created; volatile transactional data is created per run.
- Tag every created record with a run reference for isolation, cleanup and traceability.
Check your understanding · not graded
Lesson check
1. Which interface is usually the best choice for creating prerequisite data in an automated SAP test?
2. Why should every record a test creates carry a run reference?
3. Which object should a test normally verify rather than create?
4. What is the main benefit of a data factory function such as ensureStock()?