---
# System prepended metadata

title: 7/22共筆

---

# 7/22共筆

{%hackmd 1lpg7PuqRoaui6XyJcrylw %}

##  Handel Test Fail

```flow
execute_test=>start: 執行測試
pass=>end: 結束
fail=>end: 測試失敗
execute_step=>operation: 執行測試步驟
teardown=>operation: Teardown

is_step_pass=>condition: 步驟成功？
is_last_step=>condition: 還有步驟？

execute_test->execute_step->is_step_pass
is_step_pass(yes)->is_last_step
is_step_pass(no)->fail
is_last_step(yes)->execute_step
is_last_step(no)->pass
```

### behave(Cucumber)

- 用`feature`, `scenario`, `step`獲取狀態
    - `feature.status` [^feature.status]
        - `untested`
            The feature was has not been completely tested yet.
        - `skipped`
            One or more steps of this feature was passed over during testing.
        - `passed`
            The feature was tested successfully.
        -  `failed`
            One or more steps of this feature failed.
    - `scenario.status`[^scenario.status]
        - `untested`
            The scenario was has not been completely tested yet.
        - `skipped`
            One or more steps of this scenario was passed over during testing.
        - `passed`
            The scenario was tested successfully.
        - `failed`
            One or more steps of this scenario failed.
    - `step.status` [^step.status]
        - `untested`
            This step was not run (yet).
        - `skipped`
            This step was skipped during testing.
        - `passed`
            The step was tested successfully.
        - `failed`
            The step failed.
        - `undefined`
            The step has no matching step implementation.

[^feature.status]: [feature.status](https://behave.readthedocs.io/en/stable/api.html?highlight=.status#behave.model.Feature.status)
[^scenario.status]: [scenario.status](https://behave.readthedocs.io/en/stable/api.html?highlight=.status#behave.model.Scenario.status)
[^step.status]: [step.status](https://behave.readthedocs.io/en/stable/api.html?highlight=.status#behave.model.Step.status)
            
- **其中一種常用的作法**是配合`envirnment.py`的Environmental Controls Function
    - `after_step(context, step)`
    - `after_scenario(context, scenario)`
    - `after_feature(context, feature)`

- 或是配合自定義的argument和`pdb`[^pdb]（Python build-in的Debugger）
[^pdb]: [The_Python_Debugger](https://docs.python.org/3/library/pdb.html)

- 範例
    ```python
    # envirnmnet.py
    def debug_on_error(userdata):
        """
        Turn the debug on error on/off.

        Use the "behave" command  to inpust the value.
            behave --no-capture -D DEBUG_ON_ERROR      (to enable  debug-on-error)
            behave --no-capture -D DEBUG_ON_ERROR=yes  (to enable  debug-on-error)
            ehave --no-capture -D DEBUG_ON_ERROR=no   (to disable debug-on-error)
        """
        global DEBUG_ON_ERROR
        DEBUG_ON_ERROR = userdata.getbool("DEBUG_ON_ERROR")

    def before_all(context):
        debug_on_error(context.config.userdata)
        
    def after_step(context, step):
    if DEBUG_ON_ERROR and step.status == "failed":
        import pdb
        pdb.post_mortem(step.exc_traceback)
    ```

### Robot Framework
-  Test and suite statuses `PASS`, `FAIL` or `SKIP` 
- 用Build-in Keyword寫在`.robot`[^continue_on_failure]
    - `Run Keyword And Ignore Error and Run Keyword And Expect Error keywords`
    - `Run Keyword And Warn On Failure`
    - `Special failures from keywords`
    - `Run Keyword And Continue On Failure keyword`
- 用`robot:continue-on-failure`的tags[^controlling-continue-on-failure-using-reserved-tags]
```
*** Test Cases ***
Test 1
    Run Keyword and Continue on Failure    Should be Equal   1   2
    User Keyword 1

Test 2
    [Tags]    robot:continue-on-failure
    Should be Equal   1   2
    User Keyword 2

*** Keywords ***
User Keyword 1
    Run Keyword and Continue on Failure    Should be Equal   3   4
    Log   this message is logged

User Keyword 2
    [Tags]    robot:continue-on-failure
    Should be Equal   3   4
    Log   this message is logged
```


[^continue_on_failure]: [Continue_on_failure](https://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#continue-on-failure)

[^controlling-continue-on-failure-using-reserved-tags]: [controlling-continue-on-failure-using-reserved-tags](https://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#controlling-continue-on-failure-using-reserved-tags)

- 寫在`Implement Code`，用robot API
    - `robot.api`
    - `robot.result`
    - `robot.running`

```python=
import sys
from robot.api import ExecutionResult, ResultVisitor


class ExecutionTimeChecker(ResultVisitor):

    def __init__(self, max_seconds):
        self.max_milliseconds = max_seconds * 1000

    def visit_test(self, test):
        if test.status == 'PASS' and test.elapsedtime > self.max_milliseconds:
            test.status = 'FAIL'
            test.message = 'Test execution took too long.'
```

---

## 補充
![](https://i.imgur.com/eXmei6n.png)


