Lesson 12 - Golden Rules of Functional Testing
A Recap
Over the previous lessons we have used a couple of simple applications to learn how to use a BDD framework to test them.
Along the way, there have been some key lessons, that I will summarise here:
- Quality is not a reactive task, nor is it something injected at the end of a process, but an ongoing discipline.
- It’s really difficult to build a test framework that makes tests easy to write and maintain, so don’t do it - use an existing one.
- A test framework does more than drive UI interactions, it has its own expressive high-level testing language and produces shareable reports.
- If you are writing raw Selenium or Playwright commands, you are already creating more work for yourself.
- System tests should prove that user behaviour is supported by the application.
- System tests should not check the UI structure, input validation or individual system components.
- Requirements discovery and refinement should be a joint activity of the QA and business teams.
- Requirements can be automated using BDD before the application is implemented.
- Splitting the test framework into layers makes test design, implementation, refactoring and maintenance much easier.
- Thinking about the test framework in layers makes it easier to discover gaps in the requirements.
- Good BDD Scenarios are short, focussed and devoid of any implementation detail.
- BDD Scenarios can be reviewed by non-QA teams before any tests are automated.
- PageObjects should consist of nothing but the (Target) locators we find that we need as we write the tests.
- Using Dynamic Target locators drastically cuts down the amount of the UI that we need to specify as individual locators.
- Test code that performs Interaction and Question tasks lives in helper classes - separate from both Step Definitions and PageObjects.
- Helper classes should do one thing but be flexible enough to handle different inputs - allowing us to expand test coverage easily.
- If the requirements or implementation make it hard to write tests, QA needs to ask for either or both to change.
- Never trust the UI - and do not scrape it for test inputs.
- If the requirements are unclear, ask for concrete examples.
- Bugs hide behind unasked questions.
- Requirements discovery is an iterative process, not a one-off task.
- It’s never too late to ask questions.
- We don’t need to test everything through the UI. Use APIs and database access whenever needed.
- As we iterate over the tests, it’s OK to rewrite them at any level, including the Scenarios if we can make the tests clearer.
- Always check the simplest case first.
- Always vary your inputs.