AbapGit
A source-verified project description is not available yet. Open the detail page or wait for a manual refresh.
Source facts need a manual refresh
The source repository does not currently provide a readable project description. See the README below for project goals and usage guidance.
The source repository does not currently provide a readable project description. See the README below for project goals and usage guidance.
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.
If you like or are using this project please give it a star. Thanks!
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)".
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:
ASSERT in the THEN step method. A step method needs to be a public method of your test class. Make sure there is just one THEN. You will need to inherit your test class from ZCL_CACAMBER and define a FEATURE and the CONFIGURATION for the steps in the SETUP of your test class. You will also need a test method FOR TESTING, put a SCENARIO and different steps using GIVEN, WHEN, THEN and the other available methods into the test method.ASSERT failed. It might also go green if the step methods are already implemented and the existing business logic is able to pass the criteria of the ASSERT. Then you are done.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.
Cacamber basically works like this:
GIVEN, WHEN, THEN, etc or VERIFY, you provide a string as a parameter of these methods. This string is a single step in your test (when using GIVEN etc.) or also a complete scenario (when using VERIFY) written in natural language.CONFIGURE method in the SETUP of your test class.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:
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 longExample:
...
feature( 'Discount Calcuation' ).
...
cl_abap_unit_assert=>assert_equals( msg = current_feature exp = expected act = actual ).
...
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:
To keep this page readable, only the first part of the README is shown. Open the original README for the full document.