背景

以前写接口自动化,一般都会用到数据驱动,假设 bdd 在没有数据驱动的情况下会怎么写?

  1. Feature: Eating
  2. Scenario: Eat 5 out of 12
  3. Given there are 12 cucumbers
  4. When I eat 5 cucumbers
  5. Then I should have 7 cucumbers
  6. Scenario: Eat 5 out of 20
  7. Given there are 20 cucumbers
  8. When I eat 5 cucumbers
  9. Then I should have 15 cucumbers

Given、When、Then 高度重复,只是数据不一致而已
如何解决数据参数化的问题?就是通过 outlines

  1. Scenario Outline: Eating
  2. Given there are <start> cucumbers
  3. When I eat <eat> cucumbers
  4. Then I should have <left> cucumbers
  5. Examples:
  6. | start | eat | left |
  7. | 12 | 5 | 7 |
  8. | 20 | 5 | 15 |

outline 重点

  • Examples 的第一行不会被当做数据进行运行,从第二行开始读取数据并运行,一行代表一个测试场景
  • 通过 <占位符>来表示变量参数,它可以卸载 Given、When、Then 步骤中

实际 🌰

outline.feature

  1. Scenario Outline: Eating
  2. Given there are <start> cucumbers
  3. When I eat <eat> cucumbers
  4. Then I should have <left> cucumbers
  5. Examples:
  6. | start | eat | left |
  7. | 12 | 5 | 7 |
  8. | 20 | 5 | 15 |

test_outline.py

  1. from pytest_bdd import given, then, parsers, scenarios, when
  2. scenarios('outline.feature')
  3. @given(parsers.parse("there are {start} cucumbers"))
  4. def get_cucumbers(start):
  5. print(f"there ara {start} cucumbers")
  6. return start
  7. @when(parsers.parse("I eat {eat} cucumbers"))
  8. def eat_cucumbers(eat):
  9. print(f"I eat {eat} cucumbers")
  10. return eat
  11. @then(parsers.parse("I should have {left} cucumbers"))
  12. def left_cucumbers(left, eat, start):
  13. print(f"I should have {left} cucumbers")
  14. assert int(left) == (int(start) - int(eat))
  15. print("=== end ===")

命令行运行

  1. pytest -sq test_outline.py

运行结果

  1. there ara 12 cucumbers
  2. I eat 5 cucumbers
  3. I should have 7 cucumbers
  4. === end ===
  5. .there ara 20 cucumbers
  6. I eat 5 cucumbers
  7. I should have 15 cucumbers
  8. === end ===
  9. .
  10. 2 passed in 0.01s

可看到,收集了两个测试用例