Victor is a full stack software engineer who loves travelling and building things. Most recently created Ewolo, a cross-platform workout logger.
Teach testing first

The hallmark of an successful long term software project is its maintainablity. Maintainabity is a very loaded term in terms of software engineering and is usually dependent upon the software in question itself. In general however, decoupled code with a flexible overall system architecture is considered to be the best approach. Moreover, having comprehensive automated testing leads to highly resilient software. In recent years there has been a strong push towards Test Driven Development (TDD) which has become a rather polarising debate and this article does not focus on TDD but rather testing in general.

Testing in this article can mean unit testing, integration testing as well as end-to-end integration testing interchangably. There is a well-know testing pyramid that visualizes the effort required for writing tests as one goes higher up. As the title suggests, the premise really is: "Why isn't programming taught with a focus on testing first?" and "Will a focus on testing broaden the tip of the pyramid to make fully automated end-to-end integration testing easier?"

The complexity and effort of writing and executing tests increases as one goes up the pyramid.

When teaching programming, the general approach is to start with the basics such as setting up the environment, writing your first "Hello World" program, move on to programming concepts such as variables, loops, conditionals, etc. Towards the end, stuffed into advanced topics, is an introduction to unit testing. Some resources, such as the first hit on DDG for learning python (learnpython.org) feature no testing at all! Recently however, testing has improved its position and can be found somewhere in the middle of the textbook in some instances, e.g learncpp.com.

Consider now that instead of jumping into variables and loops after "Hello World", we started with a test. It might be confusing at first as there are many concepts at play here, but assuming that "Hello World" was magic enough, a little bit more magic wouldn't harm given the long term benefits. In fact the hardest part here would be to actually enable a "Hello World" test to be written because we are not talking about a unit test, but rather a full integration test that runs the program which writes to stdout and then verifies that the output is correct.

Moving on, the teaching process itself could be simplified with excercises provided in the form of tests, e.g. write a program that makes this test pass. Of course, students will also need to learn that writing a program that makes a test pass does not necessarily mean that the program does what it is supposed to! The hardest part will likely be teaching UI testing. Currently, it is a lot of effort to setup end-to-end UI integration tests. There are many approaches and it might be enough to take a really simple approach to begin with, e.g. use an in-memory db with selenium for a web application, however, we should not let this deter us from coming up with better software that enable testing from the ground up.

The benefits of teaching testing first are rather clear, students will learn how to develop and test their software leading to better software being written. This will also force us to focus on making software testable, e.g. a desktop environment that can be programmatically queried regarding contents. There are of course, security concerns here but they could be mitigated by allowing a whitelist of software that can be interacted with on a per session basis but this is probably a post for a whole another article.

We can start small perhaps, teach unit testing for languages as early as possible and any new library or framework produced should also provide clear testing guidelines. Open source code should always have a section on testing along with project setup. The goal should be making testing a first class citizen!