The automatic test program components that code or formatted data, should consider any expectations on the string level: A
assert_equal ()
is the expected result but wrote down quickly, the code does but inflexible. Small, irrelevant changes in the issuance by the string comparison as an error. For example XML: Often, in an XML document, the order they appear in the same elements names are not important. And almost always, it does not matter whether or how much space is between the elements. The string comparison is for the verification of XML documents, a level too low. To test really the essence of the issue, it is advisable to use a parser for the output format. For standard formats like XML and CSV established pathways with it. For other formats or code lines is not a parser at hand, or he is too powerful for the area to be used. In these cases one can take the trouble take a mini-parser in the infrastructure of the tests, which is just sufficient to verify the expected results. A practical example: I wanted a method called get_where_adrc (protect) by module tests generated from user-made address details a Where condition for selection of the database table ADRC (part of the central address management). This is then later in ABAP Open SQL
used as follows: data: string type lv_where_adrc ... lv_where_adrc = get_where_adrc (is_selections). into table select * from ADRC lt_adrc for all entries in lt_knvk
where eq addrnumber lt_knvk-adrnp_2
and (lv_where_adrc). ... It contains the structure is_selections the user-entered constraints of Selection: The five components
plz
, place , land ,
street and house number the structure are in particular, some of indexed columns Table ADRC shown, but usually searched with a pattern. A typical clause is generated
mc_city1 like '% Beuson NENDAZ%%' and mc_street like '% RUE GASPARD%%' and house_num1 like '% 15%' For each of the five components of a value can be specified or not. That's a total 32 possible combinations of these selections. One could choose equivalence classes of similar tests and test for each class only one representative. It seemed to me the number 32 in this case straightforward enough to play through all the possibilities-performance in a unit test class. I will not discuss whether the generation has been a dynamic where clause for this problem the right design decision. Also I do not question the specific terms that are generated from the selections. An alternative would be rejected after all, for each selection a Range fill with the option CP (contains pattern), all of these rank in the select statement and specify the work to generate the correct statement to let the database interface. Either way, it is in any case
cases in which the supply of ABAP dynamic Where clause is reasonable. I am talking in this blog only a question of how such dynamically generated code parts can be tested sense.
gv_where = go_ref-> get_where_for_adrc (gs_sel).
The module test class for the method
get_where_adrc ()
should therefore not make a string comparison, as this would be too inflexible. Actually, only to be ensured in every test case that
all selections in the specified Result occur
does not occur is not specified selections in the result,
the component names are mapped to the right column names in the database table,
that the values in the expected manner to a
LIKE
pattern or in a comparison value for
EQ
be mapped
that the individual terms are syntactically lined up correctly with
AND
.
not to be tested, however, occur in what order the individual conditions in the Where clause. Even though space is to act as a separator between each word - but it should not matter what or how much Space stands.
order on failure to have a nice overview, added to which combinations does not work, I use 32 test methods whose name is a concatenation of feature names have been given for the selections:
hausnr_ort_plz method.
gs_sel-house number = '15 '.
gs_sel-location = 'Beuson-Nendaz'.
gs_sel-zip = '1996 '.
check_where_clause_for ('HAUSNR_ORT_PLZ').
ENDMETHOD. "Hausnr_ort_plz
course I have not written down these 32 methods of hand. After looking at the implementation an exemplary test method had become clear, I wrote a Perl program I generated the code of these methods to insert in the ABAP-test class. Here it is: my%
values = (zip => '1996 'place,
=>' Beuson-Nendaz '
country =>' CH ', street
=>' Rue Gaspard ', House No.
=>' 15 ');
my @ names = sort keys% values;
my ($ fieldset, $ generate, $ pos, @ fields);
for $ generate (\\ & generate_method_definition,
\\ & generate_method_implementation fieldset) {
$ = 0;
for (1 .31) {
vec ($ fieldset, 0.8) = $ _;
$ pos = 0;
# The fields fieldset with in $ the bit to take @ fields = grep {vec ($ fieldset, $ pos + +, 1) } @ names; # implementation or definition code generating print & $ generate (@ fields); } }
sub generate_method_implementation { my $ assignments = join "\\ n", map {"gs_sel $ _ = '$ values {$_}'." } @ _;
my $ methname = join '_', @ _;
return sprintf \u0026lt;\u0026lt;METHOD_IMPL, uc ($ methname); $ methname method.
$ Assignments check_where_clause_for ('% s'). ENDMETHOD.
METHOD_IMPL } sub generate_method_definition { my $ methname = join '_', @ _; return "$ methname for testing, \\ n"; } generated this script one after the definition and implementation part of the test methods Transfer to the local unit test class. It should be essentially self-explanatory. A special feature is probably the use of the variable $
fieldset bitfield dar. The bit field is the correct data structure for the present education of all subsets of a given basic set: each test is indeed a certain selection specified components of a selection. bit fields are used in Perl with the built-in function
vec ()
. This has the pleasant property that occur on both the left and on the right side of an assignment can be. If they left, the bit field is filled as a string of bits from the specified offset to the right-most value. Is it right, the bit field at the specified offset is read.
The main loop goes through so the numbers from 1 to 31 and transmits them in a bit field. By bit test of the five relevant items is then used to determine which components of the test should be used and which not. Sun 31 test methods arise from the type of above. The 32nd Test method called empty () in the event that absolutely no selections have been handed over, plays a special role and has been implemented by hand. The announced parsing of the generated where clause is now in the central test method
check_where_clause_for (fields) are carried out
: check_where_clause_for method. data: lt_expected_fields type ty_field_exp_tab,
lv_subject type string,
lv_predicate type string,
lv_object type string,
lv_conjunction type string value 'and',
lv_last_conjunction type string,
lv_off type i, type i lv_moff, lv_mlen type i, type string lv_s field-symbols: type \u0026lt;ls_field_exp> ty_field_exp.
* Which fields are expected in the Where condition?
get_expected_fields (
exporting iv_fields = iv_fields
importing et_expected_fields = lt_expected_fields).
Thurs
lv_last_conjunction = lv_conjunction.
clear: lv_subject, lv_predicate, lv_object, lv_conjunction.
* Mini-Where parser * * Finds atomic conditions of the Where clause such as: * * mc_city1 like '% Beuson NENDAZ%%' and * * and assigns: * * * subject = predicate = mc_city1 like * object =%% Beuson NENDAZ% (without quotes) * conjunction = and (or blank if not applicable) * find regex '\\ s * (\\ w +) \\ s + (like match length lv_mlen ignoring case.
if sy-subrc ne 0lv_s condense.
* Statement is completed
lv_s = gv_where + lv_off.
assert_initial (act = lv_s
msg = 'Unexpected text at end of statement "). exit.
else. * Last
single condition must continue with and assert_equal (act = lv_last_conjunction
exp = 'and'
- msg = 'terms must be separated by and').
-
* unexpected parts of the last condition? - if lv_moff> lv_off.
lv_s = gv_where + lv_off. - assert_initial (act = lv_s
msg = `Statement contains unexpected characters'). - endif. * offset increment for next iteration lv_off lv_mlen lv_off = +.
- read table lt_expected_fields assigning \u0026lt;ls_field_exp> table with key = dbname lv_subject. if sy-subrc eq 0th
concatenate
`value '`
\u0026lt;ls_field_exp>-exp
`for`
\u0026lt;ls_field_exp> name-* field was found, delete from table of the expected fields
into gv_msg respecting blanks.
assert_equal (act = lv_object
exp =-exp \u0026lt;ls_field_exp>
msg = gv_msg).
delete from table lt_expected_fields \u0026lt;ls_field_exp>.
else.
* Unexpected field
'unexpected box
lv_subject
concatenate' is selected that does not appear in the selections'
into gv_msg respecting blanks.
fail (gv_msg).
endif.
endif.
ENDDO.
assert_initial (act = lv_last_conjunction msg = 'must come after last term is no longer AND').
assert_initial (act = lt_expected_fields
msg = 'in the SELECT statement is missing fields,' & 'were specified in the selection').
ENDMETHOD. "Check_where_clause_for
core of this mini-parser for Where conditions is a regular expression to basic selection criteria as
mc_city1 like '% Beuson NENDAZ%%' and
fit. He cut such a term in a subject, predicate, object and the optional conjunction
and linking this to the next term if necessary. For the passed list
iv_fields
the selection fields used an internal table
lt_expected_fields
is built with the test expectations. This is like a scratch list after every found term reduced and must be empty at the end (otherwise the statement was larger than expected).
be just Thus, the above expectations tested to check but without white space and order. For example, if this is a new field in the selection of running all existing Tests without errors. One can write down further tests for the new field or generate - only then you have to expand at a point, the table of expectations for the new field.
Of course the tests in more than five degrees of freedom is too unwieldy, we will have to be restricted to a meaningful subset. The mini-parser but still remains useful.
is crucial to implement such a parser with a sense of proportion : He was just as much understanding of SQL as is needed for the tests. Finally, it is only a helper to expectations to consider flexible. The relationship is no longer true if we work on more such Helpers to use as the actual tests.
This is a different situation than with XML - where parser and even their own, again listed in XML validation languages such as Schematron are available, we can use easily to us all to focus on the tests and test expectations.
0 comments:
Post a Comment