cacamber-BDD-for-ABAP
A BDD framework for ABAP that turns Gherkin-style Given/When/Then scenarios into ABAP Unit test steps, matching each step against a regular expression and calling the test class method it maps to.
Given ... When ... Then comments in an ABAP Unit test describe the intent of a test but stay disconnected from the code beneath them. Cacamber closes that: each step's string is matched against a regular expression registered through CONFIGURE in the test class's SETUP, the typed parameters are extracted (string, date, time, character, integer, packed number or a data table) and the matching public method of the test class is called. A single VERIFY call can parse a whole scenario written across several Gherkin keywords, Scenario, Rule, Given, When, Then, And, Or and But, in one string, instead of calling GIVEN, WHEN and THEN separately. Its keywords are also available in German through the ZCL_CACAMBER_GERMAN subclass, so a step can stay in the language the business already uses. It has no dependencies of its own, should work on 7.5x systems, and is either copied into a system or cloned with abapGitabapGitA Git client written in ABAP that runs inside the system, so objects are cloned, pulled and pushed without leaving it; with no package manager in ABAP, a cloned repository is how code is distributed.community org, abap.
Facts
Where it sits
Who is behind it
In the atlas: maintains 2, contributes to 4@dominikpanzermaintainerLars HvamContributes to this
In the atlas: maintains 13, contributes to 92, wrote 1@larshp1 contributor
Before choosing this
Signals
ActivityQuietNo published releases; repository quiet for 40 months
It publishes no releases, and its repository has been quiet for at least 24 full months. This may be normal for stable software; check whether its current state still fits your use.
What it declares
Every artifact
- Type
- Package
- Origin
- Independently maintained
As a package
- Where it runs
- Inside its host
- Distributed through
- Copied into the projectabapGit
Connections
BDD/TDD assertion library for ABAP Unit, styled after Chai.js
Testing application logic, with test doubles for its dependencies
Download
README
quoted from dominikpanzer/cacamber-BDD-for-ABAP under MIT, readCacamber - the BDD-Framework for ABAP
Hi! Cacamber makes it possible for you to run BDD-style tests in a SAP-system. Behavior driven development is an agile approach to software development. It focusses on collaboration through a common language between the customer and developers, testers etc. by defining examples which describe the behavior of a software system in a natural language. This language has a specific format and is called Gherkin. When using the ubiquitous language it looks like this (note: Cacamber supports different languages):
Feature: Discount calculation
Scenario: Discount on Slayer albums for VIP Slayer fans (exclusive contract with BMG)
Given the customers first name is Dominik and his last name is Panzer
and his birthdate according to our CRM system is 06.06.2006
when the sales clerk lets the system calculate the customers discount on a Slayer album
then the discount is 66% \m/
These scenarios or examples will be delivered by the business or ideally by the 3 amigos and will be used as executable specifications. You guessed it right: automated tests! So how can we execute these scenarios as automated tests?
You might already know the Given ... When ... Then pattern. It's quite similar to arrange ... act ... assert. They are both techniques to give tests a clear structure. In ABAP this usually looks like this. We focus on the the feature, give the test method an according name and write an acceptance test:
METHOD discount_calculation.
* Given
sut->do_this( parameter ).
sut->do_that( parameter ).
"more complex stuff here
DATA(product) = |Slayer Album|.
* When
DATA(discount) = sut->calculate( product ).
* Then
cl_abap_unit_assert=>assert_equals( exp = 66 act = discount ).
ENDMETHOD
The Given ... When ... Then comments are not very helpful. Also the individual parts of the test are not reusable. And the whole test is not very domain-centric compared to the scenario the business actually defined.
So some people wanted to do better and started writing their tests like this:
METHOD discount_on_slayer_albums.
given_cstmr_first_last_brthdy( EXPORTING first_name = 'Dominik'
last_name = 'Panzer'
birthdate = '20060606' ).
when_the_price_is_calculated_for( 'Slayer Album' ).
then_the_discount_is_correct( ).
ENDMETHOD
That's way better! Personally I only know one ABAP project with such kind of tests. Most of the details and complexity are hidden behind well named methods - another level of abstraction has been introduced. Also, there is the possibility to change the test parameters. This makes the steps of the test more flexible and reusable. But using parameterless methods would make the code more readable.
But this solution is no way near our original test case description. It's not natural language, it is mainly code. Also, this approach is limited by ABAPs maximum method length. Developers are forced to use abbreviations etc.
If you choose to use Cacamber as a bridge between the scenario written in plain Gherkin and ABAP Unit, your test steps will look like this:
METHOD discount_on_slayer_albums.
scenario( 'Discount on Slayer albums for VIP Slayer fans (exclusive contract with BMG)' ).
given( 'the customers first name is Dominik and his last name is Panzer' ).
and( 'his birthdate according to our CRM system is 06.06.2006' ).
when( 'the sales clerk lets the system calculate the customers discount on a Slayer album' ).
then( 'the discount is 66% \m/' ).
ENDMETHOD.
If it fails ABAP Unit can tell you this way:
...
Critical Assertion Error: 'Discount Calcuation: Discount on Slayer Albums for VIP Slayer fans (exclusive contract with BMG)'
...
Your tests can even look like this:
METHOD discount_on_a_shopping_cart.
scenario( 'Discount voucher applied to whole shopping card' ).
given( 'the customers has the following items in his shopping cart:' &&
'| 2 | Slayer | Reign In Blood | LP | 9,99€ |' &&
'| 1 | Slayer | South Of Heaven | LP | 9,99€ |' &&
'| 1 | David Hasselhoff | Crazy For You | LP | 9,99€ |' ).
and( 'he adds a valid 10% voucher' ).
when( 'the customer checks out' ).
then( 'the discount is 4€.' ).
ENDMETHOD.
Or like that:
METHOD no_discount_on_shopping_cart.
verify( 'Scenario: Customer is not eligible for a discount on the shopping cart' &&
'Given the customers first name is Dominik and his last name is Panzer' &&
'And his birthdate according to our CRM system is 06.06.2006' &&
'And in his shopping cart are the following items:' &&
'| 1 | Scooter - Hyper Hyper |' &&
'| 1 | Scooter - How Much Is The Fish |' &&
'| 1 | Scooter - Maria (I like it loud) |' &&
'When the sales clerk lets the system calculate the customers discount on the shopping cart' &&
'Then the discount is 0% \m/' ).
ENDMETHOD.
Cacamber supports keywords in different languages, so there is no need for you to translate your test cases to english. Have I sparked your interest? Great.
Give a Star! ⭐
If you like or are using this project please give it a star. Thanks!
Examples
If you don't like to read docs, check out the example class ZCL_BDD_EXAMPLE and ZCL_BDD_EXAMPLE_2, which show how to use Cacamber. They provide implementations of the above scenario "Discount on Slayer albums for VIP Slayer fans (exclusive contract with BMG)".
The BDD cycle when using Cacamber
BDDs main target is to deliver quality software by making the communication between different team members easier. But most people just think about tools like Cucumber (or Cacamber ;-)) and test automation whenever they hear about BDD.
So how does BDD work and how does Cacamber fit in? Let us have a look:
- Identify the important business features of your software and prioritize them.
- Identify different scenarios of these features and prioritize them.
- Define acceptance test descriptions for these scenarios. Use the Gherkin language for this. Make sure the whole team understands them. Scenarios are no technical descriptions. They describe the users intention, what the user actually does and what he wants to achieve.
- Write the first scenario with Cacamber consisting of the relevant steps and place an
ASSERTin theTHENstep method. A step method needs to be a public method of your test class. Make sure there is just oneTHEN. You will need to inherit your test class fromZCL_CACAMBERand define aFEATUREand theCONFIGURATIONfor the steps in theSETUPof your test class. You will also need a test methodFOR TESTING, put aSCENARIOand different steps usingGIVEN,WHEN,THENand the other available methods into the test method. - The new test method will most likely fail with an exception because the step methods are not implemented or the
ASSERTfailed. It might also go green if the step methods are already implemented and the existing business logic is able to pass the criteria of theASSERT. Then you are done. - If the scenario fails, you will most likely need to write a new method for your business logic. Use TDD for this: Red-Green-Refactor. When your TDD tests are green, place the newly created or changed method into your step method. There might be more than one method call to your business logic in a single step method. You will also need to save the results of your business logic in attributes, so other step methods can access it (one step calculates a value, the next step validates it etc.)
- Repeat until your scenario is green.
- Refactor.
- Start with the next scenario and reuse your steps methods.
If this is too abstract or too high level for you, have a look at the example implementation ZCL_BDD_EXAMPLE and ZCL_BDD_EXAMPLE_2 or check out the Cacamber API documentation.
Advantages of BDD
- Increases / improves collaboration between business, development and QA
- Makes communication in the team easier by using natural domain centric language
- The team can talk about the system behavior instead of technical implementation details
- Devs know when they are "done", because the clearly defined scenarios can be used as acceptance criteria
- Test scenarios are easily readable for new devs because they are written in a natural language
- Test steps can be reused
- Tests can be easily parameterized
- Tests are a living and up-to-date documentation
- Testing is shifted to the left of the dev process
- Automated BDD tests give the devs the security that the code still works and nothing breaks
- Fosters unit testing to implement the scenarios
- Hides complexity of implementations behind an abstraction layer
- etc.
How does Cacamber technically work?
Cacamber basically works like this:
- When you call one of Cacambers methods like
GIVEN,WHEN,THEN, etc orVERIFY, you provide a string as a parameter of these methods. This string is a single step in your test (when usingGIVENetc.) or also a complete scenario (when usingVERIFY) written in natural language. - Cacamber will take this string and check it against the configuration that was provided via the
CONFIGUREmethod in theSETUPof your test class. - The configuration consists of different entries. The first entry will be used to check if the regular expression ("pattern") and the provided string match. If it does Cacamber will extract the variables from the string.
- It then will call the method that was provided via the configuration and use the variables as parameters.
- If no regular expression matches, the next configuration entry will be checked etc.
- If no configuration entry can be found, Cacamber throws an exception.
Cacamber API
This part of the document describes the public methods of Cacambers main class ZCL_CACAMBER. It provies methods for english Gherkin keywords. If you want to use another language, have a look at this mapping table:
| English | German |
|---|---|
ZCL_CACAMBER | ZCL_CACAMBER_GERMAN |
| Given | Angenommen |
| And | Und |
| Or | Oder |
| But | Aber |
| _ | _ |
| When | Wenn |
| Then | Dann |
| Feature | Funktion |
| Scenario | Szenario |
| Example | Beispiel |
| Rule | Regel |
To get startet with Cacamber using english keywords, your local test class needs to inherit from ZCL_CACAMBER. For other languages have a look at the previous table.
ZCL_CACAMBER as your superclass provides the following public methods:
FEATURE
The FEATURE method is optional and can be used to structure your test cases in a domain-centric way. Usually one test class will represents one feature, e.g. "discount calculation". This method has to be used in the SETUP of your test class. A FEATURE can be used to enhance the MSG parameter of your asserts.
Importing parameters:
FEATURE- the name of your feature, max. 255 characters long
Example:
...
feature( 'Discount Calcuation' ).
...
cl_abap_unit_assert=>assert_equals( msg = current_feature exp = expected act = actual ).
...
CONFIGURE
The method CONFIGURE maps a regex-string to a method, which should be executed whenever the regex matches. This is called a step. If you are not a regex-pro, you can use tools like regex101 to make things easier. Inside the regex you can use (.+) or other matchers to extract the variables from the string, which will be used by Cacamber as parameters for the method call. The order of the variables must match the order of the parameters of the step method which should be called when the regex matches. Your method is only allowed to have IMPORTINGparameters. The configuration is usually done in the SETUP-method of your test class.
Supported types and regular expressions: Currently Cacamber is able to handle the following basic datatypes, which you can use in your step methods parameters. You can also use DDIC types based on these.
| datatype | example matcher | description | example value |
|---|---|---|---|
STRING | ^hello (.+)$ | a string can basically by anything, use this as a fallback, ALPHA IN will be applied | Dominik |
DATE | ^today is (.+)$ | DD.MM.YYYY a date will automatically be converted to internal format | 24.12.2023 |
TIMS | ^it's (.+) o'clock$ | HH:MM:SS a time will automatically be converted to internal format | 14:01:00 |
CHAR | ^add (.+) to cart$ | a character sequence | book |
INTEGER | ^I am (.+) years old$ | for positive or negative integers | -200 |
PACKED | ^the price is (.+)$ | a number with decimals seperated by a dot | 1001.50 |
| datatable | ^Slayer had the following members:(.+)$ | a line or a table | see section about datatables |
Importing parameters:
PATTERN- a REGEX-string which is used as a matcherMETHODNAME- name of a public method of your test class with a matching interface. Can be upper or lower case.
Example:
...
configure->( pattern = '^the customers first name is (.+) and his last name is (.+)$' methodname = 'set_first_and_second_name' ).
...
The public method of your test class then must look like this:
...
PUBLIC SECTION.
METHODS set_first_and_second_name IMPORTING first_name TYPE char30
last_name TYPE char30.
...
METHOD set_first_and_second_name.
discount_calculator->set_first_name( first_name ).
discount_calculator->set_last_name( last_name ).
ENDMETHOD.
Your test method looks like this:
METHOD discount_on_slayer_albums.
...
given( 'the customers first name is Dominik and his last name is Panzer' ).
...
ENDMETHOD.
SCENARIO
A scenario describes a variant of a feature and represents a test case. Therefore the SCENARIO method is usually used as the first method call in a test method of your local test class. A SCENARIO can be used to enhance the MSG parameter of your asserts.
Importing parameters:
SCENARIO- the name of the scenario, max. 255 characters long
Example:
...
scenario( 'Discount on Slayer Albums for VIP Slayer fans (exclusive contract with BMG)' ).
...
cl_abap_unit_assert=>assert_equals( msg = current_scenario exp = expected act = actual ).
...
EXAMPLE
The method EXAMPLE works the same way SCENARIO does.
Importing parameters:
SCENARIO- the name of the scenario, max. 255 characters long
Example:
...
example( 'Discount on Slayer Albums for VIP Slayer fans (exclusive contract with BMG)' ).
...
cl_abap_unit_assert=>assert_equals( msg = current_scenario exp = expected act = actual ).
...
RULE
With the method RULE you can describe a single business rule which will be implemented. It can be used in your local test methods just like SCENARIO or EXAMPLE. A RULE can be used to enhance the MSG parameter of your asserts.
Importing parameters:
RULE- description of a business rule, max. 255 characters long
Example:
...
rule( 'only VIP customers can buy the album 7 days before the officiall realease date' ).
...
cl_abap_unit_assert=>assert_equals( msg = current_rule exp = expected act = actual ).
...
GIVEN
The GIVEN method is an actual keyword of the Gherkin language. It represents a step. A BDD test case consists of steps which combined represent an expectation of the bahavior of the system. The paramter STEP will be matched against the regex-patterns of the configuration to find an actual method to process the data provided by the step.
A step can use any supported data type. If this doesnt suit your usecase, import the variable as a STRING into your step method and convert it there.
Importing parameters:
STEP- a string describing something relevant to the business using the ubiquitious language.
Example:
...
given( 'the customers first name is Dominik and his last name is Panzer' ).
...
given( 'the customers has the following items in his shopping cart:' &&
'| 2 | Slayer | Reign In Blood | LP | 9,99€ |' &&
'| 1 | Slayer | South Of Heaven | LP | 9,99€ |' &&
'| 1 | David Hasselhoff | Crazy For You | LP | 9,99€ |' ).
...
AND
Also a Gherkin keyword to write tests in a natural language. The method AND works like GIVEN.
Importing parameters:
STEP- a string describing something relevant to the business using the ubiquitious language.
Example:
...
and( 'his birthdate according to our CRM system is 06.06.2006' ).
...
OR
Also a Gherkin keyword to write tests in a natural language. The method OR works like GIVEN.
Importing parameters:
STEP- a string describing something relevant to the business using the ubiquitious language.
Example:
...
or( 'his birthdate according to our CRM system is 01.01.2001' ).
...
BUT
Also a Gherkin keyword to write tests in a natural language. The method Bb works like GIVEN.
Importing parameters:
STEP- a string describing something relevant to the business using the ubiquitious language.
Example:
...
but( 'today is not the Monday' ).
...
_ (underscore)
The underscore method _ can be used to define a list, because - is not an allowed name for a method in ABAP.
Importing parameters:
STEP- a string describing something relevant to the business using the ubiquitious language.
Example: ``ABAP ... given( 'in the shopping cart there are: ). _( '3 laptops' ). _( '5 ipads' ). _( '1 Slayer album' ). -( '1 David Hassehoff album' ). ...
### WHEN
Also a Gherkin keyword to write tests in a natural language. It usually desribes an action. The method `WHEN` works like `GIVEN`.
Importing parameters:
* `STEP` - a string describing something relevant to the business using the ubiquitious language.
Example:
```ABAP
...
when( 'the sales clerk lets the system calculate the customers discount on a Slayer Album' ).
...
THEN
Also a Gherkin keyword to write tests in a natural language. It describes an expected reaction of the system. The method THEN works like GIVEN.
Importing parameters:
STEP- a string describing something relevant to the business using the ubiquitious language.
Example:
...
then( 'the discount is 66% \m/' ).
...
VERIFY
Verify makes it possible to parse a whole scenario at once. So you don't need to call the methods GIVEN THEN WHEN etc. Just one method call is enought. Instead you just use the Gherkin keywords you need in your description. Currently supported are:
Scenario:(optional)Rule:(optional)Given,When,Then,And,Or,But
Important: All Keywords start with a capital letter.
The scenario will be split at these keywords into singular steps. The steps will be parsed by the configuration. Sadly ABAP doesn't allow multiline strings without connecting them via &&. ZCL_BDD_EXAMPLE_2 shows how to use VERIFY.
Importing parameters:
SCENARIO- a string containing the whole scenario
Example:
...
METHOD discount_on_slayer_albums.
verify( 'Scenario: Discount on Slayer Albums for VIP Slayer fans (exclusive contract with BMG)' &&
'Given the customers first name is Dominik and his last name is Panzer' &&
'And his birthdate according to our CRM system is 06.06.2006' &&
'When the sales clerk lets the system calculate the customers discount on the Slayer Album' &&
'Then the discount is 66% \m/' ).
ENDMETHOD.
...
GET_CURRENT_FEATURE
Returns the name of the current feature which was set with FEATURE.
Returning parameters:
CURRENT_FEATURE- a string describing the current feature.
Example:
...
DATA(feature) = get_current_feature( ).
...
GET_CURRENT_SCENARIO
Returns the name of the current scenario which was set with SCENARIO / EXAMPLE or during a VERIFY.
Returning parameters:
CURRENT_SCENARIO- a string describing the current scenario.
Example:
...
DATA(scenario) = get_current_scenario( ).
...
GET_CURRENT_RULE
Returns the name of the current rule which was set with RULE or during a VERIFY.
Returning parameters:
CURRENT_RULE- a string describing the current rule.
Example:
...
DATA(rule) = get_current_rule( ).
...
Datatable API
If you want to use datatables in your steps, you can use the class ZCL_DATATABLE to work with them in your test methods.
FROM_STRING
To parse the table defined in your step to a datatable, you have to use the static method TO_STRING.
Importing parameters:
TABLE_AS_STRING- the table from your step configuration which has been extracted via your regex. Returning parameters:DATATABLE- instance ofZCL_DATATABLE
Example:
CLASS testclass DEFINITION FINAL FOR TESTING INHERITING FROM zcl_cacamber DURATION SHORT RISK LEVEL HARMLESS.
PUBLIC SECTION.
METHODS: process_shopping_cart IMPORTING shopping_cart_raw TYPE string.
...
PRIVATE SECTION.
METHODS: setup.
METHODS: no_discount_on_shopping_cart FOR TESTING RAISING cx_static_check.
...
CLASS testclass IMPLEMENTATION.
METHOD setup.
...
configure( pattern = '^in his shopping cart are the following items:(.*)$' methodname = 'process_shopping_cart' ).
...
ENDMETHOD.
METHOD process_shopping_cart.
shopping_cart = zcl_datatable=>from_string( shopping_cart_raw ).
ENDMETHOD.
METHOD no_discount_on_shopping_cart.
scenario( 'Customer is not eligible for a discount on the shopping cart' ).
given( 'in his shopping cart are the following items:' &&
'| 1 | Scooter - Hyper Hyper |' &&
'| 1 | Scooter - How Much Is The Fish |' &&
'| 1 | Scooter - Maria (I like it loud) |' ).
...
ENDMETHOD.
...
READ_ROW
With READ_ROW you can get the values of all columns of a certain row of your table as a table of strings for further processing.
Importing parameters:
ROWNUMBER- the number of the row you want to read Returning parameters:LINE- the values of the cells of the row as a string table
Example:
...
DATA(line) = datatable->read_row( 666 ).
...
READ_CELL
With READ_CELL you can get the values of a cell of your table
Importing parameters:
ROWNUMBER- the number of the row you want to readCOLUMNNUMBER- the number of the column you want to read Returning parameters:VALUE- the values of the cell as a string for further processing
Example:
...
DATA(cell) = datatable->read_cell( rownumber = 23 columnnumber = 23 ).
...
TO_TABLE
TO_TABLE will transform your datatable into a plain internal table of a specified table type.
Importing parameters:
DDIC_TABLE_TYPE_NAME- the name of a table type Exporting parameters:TABLE- the converted table
Example:
...
DATA internal_table TYPE ztt_bdd_demo.
datatable->to_table( EXPORTING ddic_table_type_name = 'ZTT_BDD_DEMO'
IMPORTING table = internal_table ).
...
How to install Cacamber
You can copy and paste the source code into your system or simply clone this repository with abapGit. There are currently no dependencies and it should work on 7.5x systems.
Feature List
I like to create a simple acceptance test list or feature lists before I start coding. It's my personal todo-list. Often the list is very domain-centric, this one is quite technical.
| Feature List |
|---|
| ✅ first proof of concept somehow seems to works |
| ✅ a user can use the gherkin keyword "example" and it behaves like "scenario" |
| ✅ a user can use the gherkin keyword "but" and it behaves like "scenario" |
| ✅ a user can use the gherkin keyword "" for lists. because "" is not allowed in ABAP an underscore should be used. it behaves like "scenario" |
| ✅ a user can add a rule via the keyword "rule" and it is stored so it can be used in assertions |
| ✅ error handling: method doesnt have the same number of parameters as variables exist |
| ✅ error handling: no regex match / no method found should throw |
| ✅ error handling: dynamic method call for the step-method fails. it should throw. |
| ✅ a user can define tables and those are parsed and successfully |
| ✅ a user can can read values from those tables |
| ✅ a user can transform the table into a real internal table |
| ✅ a user can use empty cells in a table |
| ✅ set up a class as example on how to use cacamber |
| ✅ update the docs 👹 |
| ✅ fix the linter |
| ✅ a user can use a float number in the tests (1000.25) and it is parsed into a packed datatype succcessfully |
| ✅ a user can use a time in the test (12:00:00 or 14:01:00) and it is parsed into TIMS datatype successfully |
| ✅ update the docs 👹 |
| ✅ add a method verify(string) which can parse a whole scenario in a string format and no single given() when() then() etc methods need to be called |
| ✅ find beta testers |
| ✅ add ADRs |
| ✅ check compatibility to 7.5x-systems |
| ✅ introduce versioning |
| ✅ 💥 FIRST PUBLIC RELEASE 💥 Twitter + Blog |
| ✅ enable some kind of i18n to support german Gherkin keywords |
| ✅ fix the unit tests runner - thanks Lars |
| 🔲 get rid of ddic objects |
| 🔲 maybe text file parsing is a good idea? maybe not? |
| 🔲 your awesome idea |
Solution Architecture
You will find a product vision as well as all architectural decisions for Cacamber documented as Architecture Decision Records in this folder of the repository.
How to support this project
PRs are welcome! You can also just pick one of the test list entries from above and implement the solution, add your favourite language or implement your own idea. Fix a bug. Improve the docs... whatever suits you. Please keep the current ADRs in mind.
Greetings, Dominik
History
Removed 1, Features 1, Changed 1, Fixes 2
Notes
Added
- none
Fixed
- data table now parses dates (dd.mm.yyyy) correctly
- data table now parses time (hh:mm:ss) correctly
Changed
- none
Removed
- none
Removed 1, Features 1, Changed 1, Fixes 1
Notes
Added
- none
Fixed
- unit tests on Github are now running fine
Changed
- none
Removed
- none
Removed 1, Features 3, Changed 1, Fixes 1
Notes
Added
- support for german keywords (class
ZCL_CACAMBER_GERMAN) (verfiy-feature + keyword-methods) - keywords for
VERIFYetc. can be configured in the constructor to enable i18n. just write a wrapper, example seeZCL_CACAMBER_GERMAN - current scenario / rule / feature can be accessed by public getters
Fixed
- test examples did a wrong date comparsion
Changed
- in the past Cacamber threw the exception
ZCX_CACAMBER_ERRORwhen the framework couldn't find a step method or something else was wrong. The exception now has aadditional texts that descibe the actual problem so the user can change his configuration/coding accordingly.
Removed
- none
- support for german keywords (class
Removed 1, Features 1, Changed 1, Fixes 1
Notes
Added
- first public release
Fixed
- none
Changed
- none
Removed
- none
Others providing
Compare all 21 on the Unit testing page →- abap-senchaabap-senchaA BDD/TDD assertion library for ABAP Unit, styled after the JavaScript library Chai.js, that wraps cl_abap_unit_assert in chainable expect, should and assert styles.independent, abapBDD/TDD assertion library for ABAP Unit, styled after Chai.js
- abap2UI5 headless frontendabap2UI5 headless frontendPlays the frontend's side of the abap2UI5 request/response contract in ABAP, so an app class is driven and asserted on from a plain ABAP Unit test.community org, abapDrives abap2UI5 app classes from ABAP Unit tests
- @abap2ui5/mcp-server@abap2ui5/mcp-serverAn MCP server that puts the abap2UI5 development loop on the machine an agent runs on: check the view the ABAP builds, photograph it, deploy the class into a sandbox, boot the app headless and read the errors.community org, abapMCP server for the abap2UI5 check, deploy and run loop
- assertassertA fluent assertion helper for ABAP Unit tests that wraps cl_abap_unit_assert in chained calls such as assert(x)->equals(y), also usable outside tests through ZCL_ASSERTABLE.independent, abapFluent assertion helper for ABAP Unit tests
- @abaplint/transpiler@abaplint/transpilerTranspiles ABAP 7.02 syntax to ES6 JavaScript, so ABAP code and its unit tests run on Node.js in CI without an ABAP system, with optional SQLite, PostgreSQL, Snowflake or SAP HANA drivers.community org, abapTranspiles ABAP to JavaScript to run on Node.js
- Modernization Agents for SAP on AWSModernization Agents for SAP on AWSAWS's suite of agents for SAP modernisation work: custom ABAP converted for S/4HANA, PI/PO interfaces moved to Integration Suite, BW objects moved to SAP Datasphere, deployed into a customer's own AWS account and reached only after registration.partner, abapAWS agents for ABAP, PI/PO and BW modernisation work
- abap_db_preparatorabap_db_preparatorA wrapper over ABAP's OpenSQL replacement service that exports chosen rows into a stored bundle and, in a unit test's setup, replays it as fake table content in two method calls.independent, abapReplays stored database snapshots in ABAP unit tests
- abap-utesthelpabap-utesthelpTwo helper classes for ABAP Unit tests: one verifies a domain constant class against its domain's fixed values, the other creates test doubles without naming the interface.independent, abapHelper classes for ABAP Unit tests and test doubles
- regression_testregression_testA snapshot library for ABAP that records a value once and compares against it on every later run, from either the debugger or a unit test, storing snapshots in eCATT test data containers.independent, abapSnapshot testing library for ABAP, from debugger or unit test
- abapCovabapCovA report, ZABAPCOV, that uploads ABAP Unit test code coverage results to codecov.io, once the repository is installed through abapGit and codecov.io's certificates through STRUST.independent, abapUploads ABAP Unit code coverage to codecov.io
- ABAP remote filesystemABAP remote filesystemA Visual Studio Code extension that opens an ABAP system over ADT as an editable filesystem and exposes system tools to GitHub Copilot and external MCP clients.independent, abapVS Code extension editing ABAP systems over ADT as a filesystem
- open-steamgateopen-steamgateAn ABAP application server you clone and run on your own machine: transpiled ABAP serving classic /IWBEP/ OData v2 to Fiori over a local database, with no SAP system attached.independent, abapLocal ABAP server serving /IWBEP/ OData v2 without an SAP system
- express-icf-shimexpress-icf-shimA shim that runs an ABAP ICF handler written against if_http_extension behind an Express 4.x server, for ABAP transpiled to JavaScript and run on Node.js in testing and continuous integration.community org, abapShim running an ABAP ICF handler behind an Express 4.x server
- open-abap-coreopen-abap-coreReusable ABAP functionality for code transpiled by @abaplint/transpiler: the core ABAP artifacts that code runs against on Node.js.community org, abapCore ABAP artifacts for code transpiled by @abaplint/transpiler
- mockup_loadermockup_loaderA tool that loads ABAP unit test data prepared in Excel as TAB-delimited text into ABAP structures and tables, and generates interface stubs that return that mock data.independent, abapLoader of Excel-prepared ABAP unit test data, with stub generation
- mockAmockAA free mocking framework for ABAP, published under the Apache License 2.0.independent, abapA free mocking framework for ABAP, published under the Apache License 2.0.
- Vise_for_ABAPVise_for_ABAPA characterisation-test helper: ZCL_VISE=>GRIP records a field's value once and fails a later run if it has changed.independent, abapA characterisation-test helper: `ZCL_VISE=>GRIP` records a field's value once and fails a later run if it has changed.
- abap-senchaabap-senchaA BDD/TDD assertion library for ABAP Unit, styled after the JavaScript library Chai.js, that wraps cl_abap_unit_assert in chainable expect, should and assert styles.independent, abapBDD/TDD assertion library for ABAP Unit, styled after Chai.js
- abap-test-containerabap-test-containerA test data container for ABAP Cloud that loads unit test data in JSON, XML or raw formats from GitHub and maps it onto the target structure, filling the platform's missing native one.independent, abapGitHub-hosted test data container for ABAP Cloud
- abap-unit-runnerabap-unit-runnerAn application job that runs and schedules ABAP Unit tests in SAP's ABAP Environment through the SAP_COM_0735 API, where the on-premise test runner has no SAP GUI to run from.independent, abapApplication job that runs and schedules ABAP Unit tests in the cloud
- adash-servicesadash-servicesThe backend service behind ADASH Cli, exposing ABAP Unit test runs and coverage as REST and OData services for CI/CD pipelines, with a report scheduled to run tests per package.independent, abapBackend exposing ABAP Unit runs and coverage over REST and OData
Details
Sources
Sources are graph entities: the same page may back several entries, and an unreachable source flags every row that rests on it.
Compatibility and provenance
abaplint
Contributors
History in the atlas
- First seen.
For your agent
- Ref
artifact:dominikpanzer-cacamber-bdd-for-abap- JSON
- /artifacts/dominikpanzer-cacamber-bdd-for-abap.json
- MCP
- Connecting an agent