-
Notifications
You must be signed in to change notification settings - Fork 0
BDD
behave is the module this framework uses for its behavior-driven development test implementation. Be sure to read the behave docs so you know the basics of how behave expects things to be organized and also so you know how to kick off and run your test scenarios.
Test cases themselves in a BDD framework are always provided as "scenarios" which exist within "features". behave mandates a very specific folder structure that this framework complies with. Every single feature and scenario lives within the root-level /features/ directory or any subdirectory therein.
In the examples provided here, you can find two feature files within /features/wikipedia_features/. Each of these feature files contains one-or-more scenarios that correspond to the actual test cases that are executed when you run tests with behave.
As a best practice, your test suites should be logically divided into broad feature areas, with each feature containing specific granular scenarios that represent specific use cases or key areas of functionality. The steps within a scenario should be written in a high-level language that does not get overly bogged down in technical details.
Every step of a test scenario begins with Given, When, or Then. (Some additional keywords like And & But are also available which are syntactic sugar provided to make the written scenarios "flow" better when read by a human.)
The code that is actually executed for each step is declared in a step definitions module. behave is rather strict in this regard and mandates that all step definitions exist directly under the /features/steps/ directory. Unlike with feature files, step definitions cannot exist within deeper subdirectories.
If you look within the /features/steps/ directory you will see two wikipedia_*_steps.py modules which contain all of the step definitions used for the two example Wikipedia feature files.
As a best practice, step definitions should be written as concisely as possible, ideally containing nothing more than simple object instantiations and function calls. Complex test and functional logic should not be written directly within the step definition and should instead be abstracted away. And you certainly do not want to include Selenium locators (XPath, CSS selectors, etc.) directly in your step definitions - use Page Object Model instead!
The /features/environment.py module should contain all of the setup and teardown logic that needs to execute for the test framework. Things such as creating/destroying web browser instances, reading config files, generating mock test data, etc. should be defined here.
fixtures are used for this process, and they can either be coded to always be used or to only be used when certain @tags are specified within the test scenarios or features. In this example framework, the logic for constructing and destroying a web browser instance using Selenium is activated by tagging any scenario or feature with the @fixture.browser tag, and this logic is defined here.
Frankly, it's not enough to just write some functional automation logic for your steps and call it a day. An automation framework is only as good as the failures it generates - a test case that passes 100% of the time is worthless!
It's important to test the tests. As you write your verifications & asserts in your Then steps, you should write test scenarios against your own code to verify that your test logic can fail and throw errors under the appropriate circumstances.
A few steps and some use case examples have already been provided around this area. /features/framework_regression_features/ contains a single feature file with some scenarios that intentionally "incorrect" results so that we can verify that our tests generate proper test failures. A few special step definitions are used to capture and validate the assertion errors thrown by arbitrary scenarios, and you can find the appropriate step definitions under the /features/steps/ directory.