The past year I've been working on a software solution based on a concept that I think is fairly unique, so I thought I would describe it here. Its an idea that can solve some problems that some software projects face around productivity and maintainability. While the specific solution I worked on last year is proprietary to my current job, I think the idea behind it is one that the software industry can benefit from, and I plan to spend the upcoming year seeking to open source different implementations stemming from the concept.
In typical software development projects, teams create a specification detailing what the end product will look like. This specification is used as a form of communication between a variety of teams such as development, test, business stakeholders, and more. The development team will then build the product according to the behaviors described in the specification.
Divergence Over Time
Over time, the code evolves. Various stakeholders use the software and discover that the specification either is not appropriate, or is lacking information. New requirements are discovered. Keeping the specification up to date becomes time consuming at best. At worst, it stops being updated at all. This is a big problem when people need to understand what the product is supposed to do.
Executable Spec To the Rescue
One proposed solution that has become popular is the idea of an executable specification. In this case, you write a layer of code that makes your specification language executable on your system. Toolkits have been written that enable to developers to write their specifications in a way that can be executed, such as FIT, Fitnesse, Cucumber to name only a few. In this model, you write your specification in the form that your tooling looks for (html tables with fit/fitnesse, gherkin with Cucumber), and your test code runs against your project, validating the specification described. Then you know that if your tests pass, then your project is running as specified.
With Executable Spec, you still have some of the problems you had with traditional specifications.
- You still keep 2 descriptions of your requirements - your code, and your spec. Changes require both to be updated.
- Whether the spec does what it says is up to the glue code that ties the language to the system, and its not guaranteed that the glue code was done correctly.
- If there is a new requirement, its still possible to implement that requirement in code and not update the executable specification.
- As the spec language is tied to the underlying test code, the one who owns the tests tend to own the spec, making it difficult to get buy-in from groups like business stakeholders
Improving on Executable Spec
What if the specification language is actually your code, rather than your tests?
If we can describe our specification in JSON and store it in our product's database, then we can easily write reusable code that renders User Interfaces, and even other behaviors based on those specifications.
This opens up lots of possibilities:
- Add and change User Interfaces and system behavior with only spec updates.
- Develop "WYSIWYG" editors to allow non-technical people on your team to update specifications, and thus product behavior.
- Develop reusable and sharable rendering libraries that work on specific spec schemas
- Focus tests on truly unique behavior within the project
- Drop complex forms into your web application by the use of an existing simple widget or web component.
While using JSON to specify your UI (and other behavior) at runtime is not a replacement for BDD, it can take some of the burden off of it to be the actual spec, and let it do what's in its wheelhouse, which is drive development of unique behavior and provide a regression suite. I think that that using specs to actually drive the code in a system has great potential to give all the stakeholders in the system a nice view of how it is actually working, and reduce the cost and complexity of making changes. Look for more in this space in the coming year.