Behaviour Driven Development (BDD): Difference between revisions
Jump to navigation
Jump to search
No edit summary |
|||
Line 19: | Line 19: | ||
## Refactor any code that needs refactoring. N.B. If code is duplicated in more than one area then this may suggest that the code should be refactored. The eradication of technical debt and evolution towards an elegant design may also influence refactoring efforts. Unit tests can also be refactored for improved maintainability. | ## Refactor any code that needs refactoring. N.B. If code is duplicated in more than one area then this may suggest that the code should be refactored. The eradication of technical debt and evolution towards an elegant design may also influence refactoring efforts. Unit tests can also be refactored for improved maintainability. | ||
## Goto the first step. N.B. Many small TDD cycles tend to work best especially when incorporating refactoring efforts rather than writing a bulk of tests, then writing a bulk of code and then having to fix a bulk of failed tests. | ## Goto the first step. N.B. Many small TDD cycles tend to work best especially when incorporating refactoring efforts rather than writing a bulk of tests, then writing a bulk of code and then having to fix a bulk of failed tests. | ||
# | # Refactor the suite of feature definitions to update existing ones or add new ones as needed | ||
# Repeat the process to refine the feature definitions and associated tests | |||
==Benefits== | ==Benefits== |
Revision as of 06:07, 21 January 2019
Behaviour Driven Development or BDD is a technique used to gain technical and functional feedback using written feature definition to generate step definitions that in turn execute unit tests, such as those that are used with Test Driven Development (TDD) via a test agent.
The approach closes the feedback loop from functional requirements to technical unit tests and provides a functional context for the unit tests.
Behaviour Driven Development Cycle
- The cycle of BDD starts with writing a feature definition or testable spec using the Gherkin Format to outline the pre-conditions, actions and expected results
- Tests can be parameterised to cover boundary conditions and cater for rainy day tests etc.
- The feature definition is then used by a BDD framework such as Cucumber or SpecFlow for example to create step definitions that are unit testing stubs that correspond to the feature definition tests
- The step definitions can then be completed and used to either run specific unit tests or call other existing unit tests.
- From this point the unit tests can be defined as with Test Driven Development (TDD):
- The next step is to run the suite of tests and determine which ones fail
- If a test fails then write some code to resolve the test failure. N.B. If a rainy day test receives an expected exception, then this is a pass, in that, this is expected behaviour. ## If it received a different exception or no exception at all, then this would be deviating away from the expected behaviour stated in the unit test, and hence, would be a failed test.
- Next run the tests again to ensure that the test suite passes
- Refactor any code that needs refactoring. N.B. If code is duplicated in more than one area then this may suggest that the code should be refactored. The eradication of technical debt and evolution towards an elegant design may also influence refactoring efforts. Unit tests can also be refactored for improved maintainability.
- Goto the first step. N.B. Many small TDD cycles tend to work best especially when incorporating refactoring efforts rather than writing a bulk of tests, then writing a bulk of code and then having to fix a bulk of failed tests.
- Refactor the suite of feature definitions to update existing ones or add new ones as needed
- Repeat the process to refine the feature definitions and associated tests
Benefits
- Refactoring and enhancing code with full suites of unit tests can be done quickly as running the unit tests provides immediate feedback as to whether there are any issues
- Other forms of testing such as functional testing and integration testing benefit from code that has been hardened with unit tests
- Development efforts tend to be more focussed to satisfy the expected behaviour in tests rather than over developing code
- If refatoring is incorporated well during the TDD cycles the code design grows in an elegant form that meets the expected behaviour rather than introducing assumptions, which may later be realised as constraints.
- A suite of passed tests provides a very good level of confidence in the team that their code works
Challenges
- Time taken to write tests can be exhaustive when compared to new code development time and may be very tempting to skip tests and just write code.
- New testing skills may need to be introduced to developers, as they are now tasked with providing enough test coverage of their code. Boundary value analysis for example, may be a new skill to be acquired by the developers to ensure that they have sufficient test coverage.
- The number of rainy day unit tests when compared to the number of sunny tests has been quoted as being as much as 10 rainy day to 1 sunny day, which may be a new discipline for developers.
- For extensive suites of unit tests, these may be overwhelming to maintain and keep current. Hence, refactoring tests may be just as important as refactoring code.
See Also
References
- https://docs.cucumber.io/gherkin/reference/, accessed 21 Jan 2019
- Test Driven Development: By Example, Kent Beck, 2001
- Extreme Programming Explained, Kent Beck and Cynthia Andres, 2004