如何处理 BDD 中的环境先决条件?

How to handle environment prerequisites in BDD?

我正在做一个自动化测试项目(使用 Pytest BDD),我经常遇到如何使用 BDD 和 Gherkin 处理环境先决条件的问题。例如,几乎所有场景都需要创建新实体 (users/admins/sites/organizations/etc) 只是为了有一些东西可以使用。

我认为我不应该在 'Given' 部分中写下所有先决条件操作(这似乎是反 BDD),但我不想迷失在什么场景设置什么以及如何设置的问题上。

例如,我永远不想创建这个:

Scenario: A user can buy a ticket from a webshop.
Given an item available in the webshop
And a user is created
And the user has at least one payment option set up
And the user is logged in
When the user buys the item in the webshop
Then the user owns the item

人们通常如何以一种将来可读和可维护的方式写下这些动作和实体?

使用 Cucumber 的 "Background" keyword:

Background in Cucumber is used to define a step or series of steps which are common to all the tests in the feature file. It allows you to add some context to the scenarios for a feature where it is defined.

又见官方docs.

一种方式 - 使用@BeforeClass(一次性设置)

@RunWith(Cucumber.class)
@CucumberOptions(features = "classpath:features/checkoutmodule/registereduser/",
                     glue = {"com.ann.automation.test.steps" },
                     tags = { "@SignIn" },
                   plugin = { "pretty","json:target/cucumber.json",
                              "junit:target/cucumber-reports/Cucumber.xml", "html:target/cucumber-reports",
                              "com.cucumber.listener.ExtentCucumberFormatter"},
                   strict = false,
                   dryRun = false,
               monochrome = true)

public class RunCuke {

    // ----------------------------- Extent Report Configuration -----------------------------
    @BeforeClass
    public static void setup() {
        // below is dummy code just to showcase
        File newFile = new File(Constants.EXTENT_REPORT_PATH);
        ExtentCucumberFormatter.initiateExtentCucumberFormatter(newFile,true);
        ExtentCucumberFormatter.loadConfig(new File(Constants.EXTENT_CONFIG_FILE_PATH));
        ExtentCucumberFormatter.addSystemInfo("Browser Name", Constants.BROWSER);
        ExtentCucumberFormatter.addSystemInfo("Browser version", Constants.BROWSER_VERSION);
        ExtentCucumberFormatter.addSystemInfo("Selenium version", Constants.SELENIUM_VERSION);
    }
}

其他方式-使用背景(在每个场景之前设置)

Cucumber 通过提供 Background 关键字为此提供了一种机制 您可以在哪里指定

  • 特征文件中所有测试通用的一个步骤或一系列步骤。
  • 一个步骤或一系列步骤应该 运行 在每个场景之前 特征。通常这些将是给定的步骤,但您可以使用任何步骤 你需要的。

示例: 在这里,在每次 scenario/outline 执行之前,我们希望用户转到网站主页并搜索产品。那么让我们看看实现。

  Background: 
    Given User is on Brand Home Page "https://www.anntaylor.com/"
    Given User searches for a styleId for <Site> and makes product selection on the basis of given color and size
      | Style_ID  | Product_Size | Product_Color |
      | TestData1 | TestData1    | TestData1     |
      | TestData2 | TestData2    | TestData2     |

  @guest_search
  Scenario Outline: Validation of UseCase Guest User Order Placement flow from Search
    Then Clicking on Cart icon shall take user to Shopping Bag
    When Proceeding to checkout as "GuestUser" with emailId <EmailID> shall take user to Shipping Page
    And Entering FN as <FName> LN as <LName> Add as <AddL1> ZCode as <ZipCode> PNo as <PhoneNo> shall take user to payment page
    And Submitting CCardNo as <CCNo>" Month as <CCMonth> Year as <CCYear> and CVV as <CVV> shall take user to Order Review Page
    Then Verify Order gets placed successfully

    Examples: Checkout User Information
      | EmailID   | FName     | LName     | AddL1     | ZipCode   | PhoneNo   | CCNo      | CCMonth   | CCYear    | CVV       |
      | TestData2 | TestData2 | TestData2 | TestData2 | TestData2 | TestData2 | TestData2 | TestData2 | TestData2 | TestData2 |

最后的方法 - 使用@Before(在每个场景之前设置)

@Before
    public void setUpScenario(Scenario scenario){
        log.info("***** FEATURE FILE :-- " + Utility.featureFileName(scenario.getId().split(";")[0].replace("-"," ")) + " --: *****");
        log.info("---------- Scenario Name :-- " + scenario.getName() + "----------");
        log.info("---------- Scenario Execution Started at " + Utility.getCurrentTime() + "----------");
        BasePage.message=scenario;
        ExtentTestManager.startTest("Scenario No . " + (x = x + 1) + " : " + scenario.getName());
        ExtentTestManager.getTest().log(Status.INFO, "Scenario No . "+ x + " Started : - " + scenario.getName());
    //  Utility.setupAUTTestRecorder();
        // --------- Opening Browser() before every test case execution for the URL given in Feature File. ---------
        BaseSteps.getInstance().getBrowserInstantiation();
    }