Testing SAP Integrations: IDocs, BAPIs and the API Layer

Why SAP integration testing needs different assertions than UI testing, across IDocs, BAPIs and OData. IDoc status 53 means the IDoc processed

There is a particular kind of production incident that SAP teams will recognize. Everything is green. The interface monitoring shows messages flowing. The sending system reports success. And somewhere downstream, a business process has been quietly producing wrong documents for three days.

Integration is where that happens, and it happens for a structural reason: **in SAP integration, technical success and business correctness are different things, and most monitoring only checks the first one.**

IDoc status 53 means the IDoc processed. It does not mean the document it created is right.

This piece covers what makes the integration layer different from anything above it, the specific failure modes in IDocs, BAPIs and the modern OData surface, where failures hide from monitoring, and what to assert instead.

Three properties separate this layer from the Fiori applications above it, and each one breaks an assumption that UI testing relies on.

It is asynchronous by default. An IDoc is fire-and-forget. You post it, it enters a queue, it processes when the system gets to it. “Did this work” is genuinely unanswerable at the moment of sending, which means any assertion made immediately after the send is asserting on the wrong thing, usually that the message was accepted, not that anything happened as a result.

It spans systems, and therefore teams. The sending system’s team tests that it sent correctly. The receiving system’s team tests that it processes correctly what it receives. Both are right within scope, and the interesting failures live in the gap between two correct scopes, a field one side treats as optional and the other requires, a code the sender uses that the receiver maps differently.

Recovery is routine, which hides failure rates. Reprocessing failed IDocs through BD87 is normal operations in most SAP shops. Once reprocessed, a message that failed twice looks identical in its end state to one that worked immediately. So the error rate becomes invisible unless someone is specifically measuring it, and the underlying cause never gets fixed because the symptom keeps getting cleared.

IDoc status codes are the primary monitoring signal in most SAP landscapes, and they answer a narrower question than they are usually taken to answer.

StatusMeansDoes Not Mean
53Application document postedThat the document contains correct values, hit the right accounts, or reflects what the sender intended
51Application document not postedNecessarily a defect, some 51s are the correct outcome for invalid input
64Ready to be transferred to applicationThat it will be. An IDoc can sit at 64 indefinitely if the processing job is not running
12 / 03Dispatched / passed to port (outbound)That the receiver got it, parsed it, or did anything with it
69IDoc was editedThat the edit was correct, manual edits bypass the validation the original failed

The 53 row is the one that matters most, because it is the status everyone treats as “done.” An inbound IDoc creating a sales order can post successfully while the order has the wrong pricing condition, a substituted material because the sent one was blocked, or a delivery date derived from the wrong calendar. Status 53. Document created. Business outcome wrong.

The 69 row deserves a specific note because it is a governance issue as much as a testing one. When someone edits an IDoc to make it process, they are bypassing the validation that rejected it. The document that results was never validated by the same rules as one that came through cleanly, and status 69 is frequently treated as equivalent to 53 in monitoring.

A manually edited IDoc is a document your validation rules rejected, that a human overrode, that your monitoring counts as a success.

The status 64 case is quieter and catches people during cutover and after upgrades: the IDoc arrived and is technically ready, and the background job that processes it is not scheduled or has failed. Everything looks fine from the sender. Nothing has happened.

BAPIs are synchronous, which removes the timing problem, and introduces two of their own that are among the most common defects in SAP integration code.

The commit that never happened

BAPIs do not commit their own work. A separate call to BAPI_TRANSACTION_COMMIT is required, and without it the database work is rolled back when the session ends.

The failure mode this produces is specific: the BAPI returns success, the calling code checks the return and sees success, and nothing persists. A test that asserts on the BAPI response passes. A test that asserts on the resulting document finds nothing, which is exactly why the assertion has to be on the document rather than on the response.

The return table that says both things

BAPIs return a RETURN table, not a single status. That table can contain multiple rows with different message types, S for success, E for error, W for warning, I for information, A for abort, and it is entirely normal for a single call to return several.

The common defect is checking only the first row, or checking whether any success message exists rather than whether any error message exists. A BAPI can return an S row and an E row in the same table, and code that reads the first row concludes everything worked.

The correct assertion is negative: no rows of type E or A anywhere in the table, rather than the presence of an S somewhere in it.

The newer integration surface behaves more like conventional API testing, with a few SAP-specific characteristics worth knowing.

OData services are stateful in ways REST usually is not. Deep inserts, batch requests and change sets group operations into a single transactional unit. A batch that partially succeeds is a different situation from a REST call that fails, and testing needs to assert on what committed rather than on the HTTP status of the batch.

The Gateway layer can succeed while the backend does not. SAP Gateway sits between the caller and the business logic. A 200 response confirms Gateway processed the request; whether the underlying business object was created correctly is a separate question answered in the backend tables.

Integration Suite absorbs failures by design. Middleware exists to decouple systems, which is exactly what makes it good at hiding problems. A message accepted by an iFlow, transformed and routed can fail at the receiver while the sender holds a successful acknowledgement. Monitoring each hop individually shows green at the hop that matters to you.

The general principle that applies to all three is the same one running through this article: the response tells you about the transport, and the business outcome lives somewhere else.

Four places integration defects sit undetected, all of which pass conventional monitoring.

  • Behind successful reprocessing. BD87 clears the error and the end state looks clean. Unless failure counts before reprocessing are tracked separately, a systematically broken interface presents as a healthy one with some operational overhead.
  • In queues nobody watches. Entries stuck in the tRFC queue (SM58) or qRFC inbound and outbound queues (SMQ1, SMQ2) are not IDoc errors and do not appear in IDoc monitoring. A blocked queue entry holds up everything behind it, silently, until someone looks.
  • Between the sender’s acknowledgement and the receiver’s reality. The most common integration incident shape. Both sides believe they are correct because each is looking at its own half.
  • In correctly-processed documents with wrong content. The status 53 problem. No error anywhere, and the business result is wrong. This category is invisible to every technical monitor and only surfaces through business-level validation or a customer complaint.
AssertInstead OfCatches
The resulting business document is correctIDoc status 53 / HTTP 200 / BAPI successStatus-53-but-wrong, the invisible category
The document persisted after commitThe BAPI return table aloneMissing BAPI_TRANSACTION_COMMIT
No E or A rows anywhere in RETURNFirst row, or presence of an S rowMixed success and error in one response
Processing completed within an expected windowImmediate assertion after sendStatus 64 backlogs and unscheduled jobs
Sender and receiver hold matching valuesEach system’s own viewMapping and transformation drift
Failure counts before reprocessingEnd-state status onlySystematic errors masked by routine recovery

The first row carries most of the value. Everything else on this list is a technical assertion that improves signal quality; asserting on the resulting document is the only one that catches the category nothing else does.

The fourth row needs a design decision rather than just a check: because processing is asynchronous, the test has to wait for a state rather than assert immediately, and the wait needs a defined timeout that reflects the interface expected latency. Too short produces false failures during normal load; too long turns a stalled interface into a slow test.

Sofy’s SAP agents validate at the data layer, which is what the first row of that table actually requires.

For an inbound interface, that means asserting on the created document rather than the IDoc status, whether a sales order carries the right pricing conditions and material, whether a posting hit the correct G/L account and period, whether the receiving document reflects what the sender intended. The IDoc status is checked too, because a 51 is still worth knowing about; it is just not the assertion the test rests on.

For asynchronous flows, agents wait for the resulting state rather than asserting at send time, which is the behaviour the async model requires and the one conventional test scripts most often get wrong.

And because agents coordinate across layers (multi-agent orchestration), an interface test can span the sending system, the middleware hop and the receiving document as one validated journey, rather than three separate checks whose combined result nobody assembles.

For SAP FI/CO agent testing specifically, the same data-layer approach means an inbound posting can be validated against the same criteria as any other document, accounts, dimensions, period, and reconciliation, rather than being treated as a separate class because it arrived through an interface.

Three things that remain necessary.

  • Interface monitoring. Status monitoring, queue monitoring and Integration Suite message tracking are operational tools and this does not substitute for them. Testing tells you an interface works correctly; monitoring tells you it is working right now. Both are needed and they answer different questions.
  • The IDoc test tool. WE19 remains the right instrument for constructing a specific IDoc and stepping through inbound processing during development. It is a debugging tool rather than a regression mechanism, and it is good at what it does.
  • Middleware-side testing. Where Integration Suite performs meaningful transformation, that mapping logic deserves its own tests at the middleware layer. End-to-end validation confirms the outcome; it does not tell you which of five mapping steps corrupted a field.

What should IDoc testing actually assert?

The resulting business document, not the IDoc status. Status 53 confirms the IDoc processed, it does not confirm the document created is correct. An inbound IDoc can post successfully while producing a sales order with the wrong pricing condition, a substituted material or an incorrect delivery date. Check the status too, since a 51 matters, but rest the assertion on what was created.

Why do BAPI tests pass when nothing was saved?

Because BAPIs do not commit their own work. BAPI_TRANSACTION_COMMIT is a separate call, and without it the database work rolls back at session end. The BAPI returns success, the calling code sees success, and nothing persists. Asserting on the resulting document rather than the BAPI response is what catches it.

How do you test asynchronous SAP interfaces?

By waiting for the resulting state rather than asserting at send time. Because IDocs and queued RFC calls process independently of the send, an immediate assertion tests only that the message was accepted. The test needs a defined wait for the expected end state, with a timeout reflecting the interface’s normal latency, too short creates false failures under load, too long turns a stalled interface into a slow test.

What is the difference between testing SAP OData services and normal REST APIs?

Mostly the transactional grouping and the Gateway layer. OData supports deep inserts, batch requests and change sets, so a batch can partially succeed in a way a single REST call cannot, the assertion needs to cover what committed. And a 200 from SAP Gateway confirms Gateway processed the request; whether the backend business object was created correctly is a separate question answered in the underlying tables.

Why do integration errors stay hidden?

Four common places: behind routine reprocessing through BD87, which clears the symptom and leaves the end state looking clean; in tRFC and qRFC queues that IDoc monitoring does not cover; between a sender’s successful acknowledgement and a receiver that never processed the message; and in documents that processed correctly with wrong content, which no technical monitor can detect.

SAP integration monitoring answers one question well: did the message move. That question matters, and the tooling around it, status codes, queue monitors, message tracking, is mature and useful.

It is not the question that determines whether the business is correct. A document can post cleanly and be wrong. A BAPI can return success and persist nothing. A middleware hop can acknowledge a message the receiver never processed. Every one of those states looks healthy on a monitor.

Which is why integration assertions belong on the resulting document rather than on the transport. The status tells you something happened. Only the document tells you the right thing happened.

Validate the Document, Not the Status

See agents assert on the business outcome an interface produced, waiting for asynchronous processing to complete, then checking what was actually created.

See Sofy in action. Book your demo.

We’ll show you exactly how it works for your team in 30 minutes.

Scriptless test automation—no coding or framework setup

Run tests on hundreds of real iOS and Android devices

Integrate with your CI/CD in minutes

Self-healing test that adapt as your app changes

Real-time debugging with logs, crash reports, and performance data