For Web Applications, Focus on Function, not Form
Like a helium balloon, the demand for web applications keeps rising. With this demand comes the responsibility of resiliency. In order to bake resiliency into a software system, the developer community is largely practicing the best-practice of TDD or Test Driven Development. The three golden rules of TDD from Uncle Bob are:
1. You must write a failing test before you write any production code.
2. You must not write more of a test than is sufficient to fail, or fail to compile.
3. You must not write more production code than is sufficient to make the currently failing test pass.
These tenets are simple, practical and easy to follow. However, the tests are usually implemented as Unit Tests. When we are trying to build rich, interactive web applications, unit tests fall short in helping us achieve our objective of resiliency. In such a scenario, web application engineers would be better suited to have Functional Tests as the foundation of TDD.
In case you’re not familiar with Functional Tests, the shortest explanation one can think of is:
A test that checks if a module is doing what it is intended to do.
In web applications, we frequently encounter elements like buttons, checkboxes, radio-buttons, dropdowns and so on. These elements are designed for different functions. Depending on the domain use case, they can be wired differently. Simple unit tests, by definition, cannot capture the complexity of these use cases and interactions. If we want to supercharge our workflow, writing Functional Tests first has become the need of the hour.
Say, you’re a web application engineer working on a button. When implementing TDD with Functional Tests, one must ask — what does this button do? What services does it communicate with? What happens when you click it? Are there multiple steps that need to be executed after the button is clicked e.g showing an animation, fetching data from a service and then updating the UI? Or is there a single action that happens on button click e.g a redirect? What would happen if this button errors out?
These questions would be answered by writing Functional Tests for all possible use cases first. Then, writing code to implement the functional cases, while continuing to add unit tests. This ensures that all possible use cases are covered with a corresponding test + implementation. Unit tests are still important to ensure future refactoring. But for interactive experiences, functional tests are a better technique to create a deterministic system.
We realize the importance of functional tests. So, on Walmart.com applications, we write and run thousands of functional tests every day to deliver a reliable, consistent experience to our customers.
There are some highly praised tools and frameworks available that can help you write and run functional tests e.g Cypress and TestArmada.(Read about being creative with TestArmada). So, pick the one that suits your needs and go forth to build wonderful things. Just make sure that you write the functional tests first.