visitor
Interface to ease traversing through a test suite structure.
Visitors make it easy to modify test suite structures or to collect information
from them. They work both with the :mod:executable model <robot.running.model>
and the :mod:result model <robot.result.model>, but the objects passed to
the visitor methods are slightly different depending on the model they are
used with. The main differences are that on the execution side keywords do
not have child keywords nor messages, and that only the result objects have
status related attributes like :attr:status and :attr:start_time.
This module contains :class:SuiteVisitor that implements the core logic to
visit a test suite structure, and the :mod:~robot.result package contains
:class:~robot.result.visitor.ResultVisitor that supports visiting the whole
test execution result structure. Both of these visitors should be imported
via the :mod:robot.api package when used by external code.
Visitor algorithm¶
All suite, test, keyword and message objects have a :meth:visit method that
accepts a visitor instance. These methods will then call the correct visitor
method :meth:~SuiteVisitor.visit_suite, :meth:~SuiteVisitor.visit_test,
:meth:~SuiteVisitor.visit_keyword or :meth:~SuiteVisitor.visit_message,
depending on the instance where the :meth:visit method exists.
The recommended and definitely the easiest way to implement a visitor is extending
the :class:SuiteVisitor base class. The default implementation of its
:meth:visit_x methods take care of traversing child elements of the object
:obj:x recursively. A :meth:visit_x method first calls a corresponding
:meth:start_x method (e.g. :meth:visit_suite calls :meth:start_suite),
then calls :meth:visit for all child objects of the :obj:x object, and
finally calls the corresponding :meth:end_x method. The default
implementations of :meth:start_x and :meth:end_x do nothing.
All items that can appear inside tests have their own visit methods. These
include :meth:visit_keyword, :meth:visit_message (only applicable with
results, not with executable data), :meth:visit_for, :meth:visit_if, and
so on, as well as their appropriate start/end methods like :meth:start_keyword
and :meth:end_for. If there is a need to visit all these items, it is possible to
implement only :meth:start_body_item and :meth:end_body_item methods that are,
by default, called by the appropriate start/end methods. These generic methods
are new in Robot Framework 5.0.
Visitors extending the :class:SuiteVisitor can stop visiting at a certain
level either by overriding suitable :meth:visit_x method or by returning
an explicit False from any :meth:start_x method.
Examples¶
The following example visitor modifies the test suite structure it visits.
It could be used, for example, with Robot Framework's --prerunmodifier
option to modify test data before execution.
.. literalinclude:: ../../../doc/api/code_examples/SelectEveryXthTest.py :language: python
For more examples it is possible to look at the source code of visitors used
internally by Robot Framework itself. Some good examples are
:class:~robot.model.tagsetter.TagSetter and
:mod:keyword removers <robot.result.keywordremover>.
Type hints¶
Visitor methods have type hints to give more information about the model objects
they receive to editors. Because visitors can be used with both running and result
models, the types that are used as type hints are base classes from the
:mod:robot.model module. Actual visitor implementations can import appropriate
types from the :mod:robot.running or the :mod:robot.result module instead.
For example, this visitor uses the result side model objects::
1 2 3 4 5 6 7 8 9 10 11 12 | |
Type hints were added in Robot Framework 6.1. They are optional and can be removed altogether if they get in the way.
SuiteVisitor
¶
Abstract class to ease traversing through the suite structure.
See the :mod:module level <robot.model.visitor> documentation for more
information and an example.
Source code in src/robot/model/visitor.py
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 | |
end_body_item(item)
¶
Called, by default, when keywords, messages or control structures end.
More specific :meth:end_keyword, :meth:end_message, :meth:end_for`,
etc. can be implemented to visit only keywords, messages or specific control
structures.
Default implementation does nothing.
Source code in src/robot/model/visitor.py
end_break(break_)
¶
Called when a BREAK element ends.
By default, calls :meth:end_body_item which, by default, does nothing.
end_continue(continue_)
¶
Called when a CONTINUE element ends.
By default, calls :meth:end_body_item which, by default, does nothing.
end_error(error)
¶
Called when a ERROR element ends.
By default, calls :meth:end_body_item which, by default, does nothing.
end_for(for_)
¶
Called when a FOR loop ends.
By default, calls :meth:end_body_item which, by default, does nothing.
end_for_iteration(iteration)
¶
Called when a FOR loop iteration ends.
By default, calls :meth:end_body_item which, by default, does nothing.
end_if(if_)
¶
Called when an IF/ELSE structure ends.
By default, calls :meth:end_body_item which, by default, does nothing.
end_if_branch(branch)
¶
Called when an IF/ELSE branch ends.
By default, calls :meth:end_body_item which, by default, does nothing.
end_keyword(keyword)
¶
Called when a keyword ends.
By default, calls :meth:end_body_item which, by default, does nothing.
end_message(message)
¶
Called when a message ends.
By default, calls :meth:end_body_item which, by default, does nothing.
end_return(return_)
¶
Called when a RETURN element ends.
By default, calls :meth:end_body_item which, by default, does nothing.
end_suite(suite)
¶
end_test(test)
¶
end_try(try_)
¶
Called when a TRY/EXCEPT structure ends.
By default, calls :meth:end_body_item which, by default, does nothing.
end_try_branch(branch)
¶
Called when TRY, EXCEPT, ELSE and FINALLY branches end.
By default, calls :meth:end_body_item which, by default, does nothing.
end_var(var)
¶
Called when a VAR element ends.
By default, calls :meth:end_body_item which, by default, does nothing.
end_while(while_)
¶
Called when a WHILE loop ends.
By default, calls :meth:end_body_item which, by default, does nothing.
end_while_iteration(iteration)
¶
Called when a WHILE loop iteration ends.
By default, calls :meth:end_body_item which, by default, does nothing.
start_body_item(item)
¶
Called, by default, when keywords, messages or control structures start.
More specific :meth:start_keyword, :meth:start_message, :meth:start_for`,
etc. can be implemented to visit only keywords, messages or specific control
structures.
Can return explicit False to stop visiting. Default implementation does
nothing.
Source code in src/robot/model/visitor.py
start_break(break_)
¶
Called when a BREAK element starts.
By default, calls :meth:start_body_item which, by default, does nothing.
Can return explicit False to stop visiting.
Source code in src/robot/model/visitor.py
start_continue(continue_)
¶
Called when a CONTINUE element starts.
By default, calls :meth:start_body_item which, by default, does nothing.
Can return explicit False to stop visiting.
Source code in src/robot/model/visitor.py
start_error(error)
¶
Called when a ERROR element starts.
By default, calls :meth:start_body_item which, by default, does nothing.
Can return explicit False to stop visiting.
Source code in src/robot/model/visitor.py
start_for(for_)
¶
Called when a FOR loop starts.
By default, calls :meth:start_body_item which, by default, does nothing.
Can return explicit False to stop visiting.
Source code in src/robot/model/visitor.py
start_for_iteration(iteration)
¶
Called when a FOR loop iteration starts.
By default, calls :meth:start_body_item which, by default, does nothing.
Can return explicit False to stop visiting.
Source code in src/robot/model/visitor.py
start_if(if_)
¶
Called when an IF/ELSE structure starts.
By default, calls :meth:start_body_item which, by default, does nothing.
Can return explicit False to stop visiting.
Source code in src/robot/model/visitor.py
start_if_branch(branch)
¶
Called when an IF/ELSE branch starts.
By default, calls :meth:start_body_item which, by default, does nothing.
Can return explicit False to stop visiting.
Source code in src/robot/model/visitor.py
start_keyword(keyword)
¶
Called when a keyword starts.
By default, calls :meth:start_body_item which, by default, does nothing.
Can return explicit False to stop visiting.
Source code in src/robot/model/visitor.py
start_message(message)
¶
Called when a message starts.
By default, calls :meth:start_body_item which, by default, does nothing.
Can return explicit False to stop visiting.
Source code in src/robot/model/visitor.py
start_return(return_)
¶
Called when a RETURN element starts.
By default, calls :meth:start_body_item which, by default, does nothing.
Can return explicit False to stop visiting.
Source code in src/robot/model/visitor.py
start_suite(suite)
¶
Called when a suite starts. Default implementation does nothing.
Can return explicit False to stop visiting.
start_test(test)
¶
Called when a test starts. Default implementation does nothing.
Can return explicit False to stop visiting.
start_try(try_)
¶
Called when a TRY/EXCEPT structure starts.
By default, calls :meth:start_body_item which, by default, does nothing.
Can return explicit False to stop visiting.
Source code in src/robot/model/visitor.py
start_try_branch(branch)
¶
Called when TRY, EXCEPT, ELSE or FINALLY branches start.
By default, calls :meth:start_body_item which, by default, does nothing.
Can return explicit False to stop visiting.
Source code in src/robot/model/visitor.py
start_var(var)
¶
Called when a VAR element starts.
By default, calls :meth:start_body_item which, by default, does nothing.
Can return explicit False to stop visiting.
Source code in src/robot/model/visitor.py
start_while(while_)
¶
Called when a WHILE loop starts.
By default, calls :meth:start_body_item which, by default, does nothing.
Can return explicit False to stop visiting.
Source code in src/robot/model/visitor.py
start_while_iteration(iteration)
¶
Called when a WHILE loop iteration starts.
By default, calls :meth:start_body_item which, by default, does nothing.
Can return explicit False to stop visiting.
Source code in src/robot/model/visitor.py
visit_break(break_)
¶
visit_continue(continue_)
¶
visit_error(error)
¶
Visits body items resulting from invalid syntax.
Examples include syntax like END or ELSE in wrong place and
invalid setting like [Invalid].
Source code in src/robot/model/visitor.py
visit_for(for_)
¶
Implements traversing through FOR loops.
Can be overridden to allow modifying the passed in for_ without
calling :meth:start_for or :meth:end_for nor visiting body.
Source code in src/robot/model/visitor.py
visit_for_iteration(iteration)
¶
Implements traversing through single FOR loop iteration.
This is only used with the result side model because on the running side there are no iterations.
Can be overridden to allow modifying the passed in iteration without
calling :meth:start_for_iteration or :meth:end_for_iteration nor visiting
body.
Source code in src/robot/model/visitor.py
visit_if(if_)
¶
Implements traversing through IF/ELSE structures.
Notice that if_ does not have any data directly. Actual IF/ELSE
branches are in its body and they are visited separately using
:meth:visit_if_branch.
Can be overridden to allow modifying the passed in if_ without
calling :meth:start_if or :meth:end_if nor visiting branches.
Source code in src/robot/model/visitor.py
visit_if_branch(branch)
¶
Implements traversing through single IF/ELSE branch.
Can be overridden to allow modifying the passed in branch without
calling :meth:start_if_branch or :meth:end_if_branch nor visiting body.
Source code in src/robot/model/visitor.py
visit_keyword(keyword)
¶
Implements traversing through keywords.
Can be overridden to allow modifying the passed in kw without
calling :meth:start_keyword or :meth:end_keyword nor visiting
the body of the keyword
Source code in src/robot/model/visitor.py
visit_message(message)
¶
Implements visiting messages.
Can be overridden to allow modifying the passed in msg without
calling :meth:start_message or :meth:end_message.
Source code in src/robot/model/visitor.py
visit_return(return_)
¶
visit_suite(suite)
¶
Implements traversing through suites.
Can be overridden to allow modifying the passed in suite without
calling :meth:start_suite or :meth:end_suite nor visiting child
suites, tests or setup and teardown at all.
Source code in src/robot/model/visitor.py
visit_test(test)
¶
Implements traversing through tests.
Can be overridden to allow modifying the passed in test without calling
:meth:start_test or :meth:end_test nor visiting the body of the test.
Source code in src/robot/model/visitor.py
visit_try(try_)
¶
Implements traversing through TRY/EXCEPT structures.
This method is used with the TRY/EXCEPT root element. Actual TRY, EXCEPT, ELSE
and FINALLY branches are visited separately using :meth:visit_try_branch.
Source code in src/robot/model/visitor.py
visit_try_branch(branch)
¶
Visits individual TRY, EXCEPT, ELSE and FINALLY branches.
visit_var(var)
¶
visit_while(while_)
¶
Implements traversing through WHILE loops.
Can be overridden to allow modifying the passed in while_ without
calling :meth:start_while or :meth:end_while nor visiting body.
Source code in src/robot/model/visitor.py
visit_while_iteration(iteration)
¶
Implements traversing through single WHILE loop iteration.
This is only used with the result side model because on the running side there are no iterations.
Can be overridden to allow modifying the passed in iteration without
calling :meth:start_while_iteration or :meth:end_while_iteration nor visiting
body.