Software development has evolved into a craft which needs quite a few tools. Writing source code is merely a small part of software development. A software developer is expected to understand how software gets delivered. These days, most of the steps in the delivery mechanism are actually executed by original developers of the software.
This blog is an attempt to throw some light on the various tools or systems that are needed by software developers in general. It is intended for college students who have learnt programming and are ready to start working in the industry.
Tools and systems needed by the industrial software developer:
- Source Code Management System
- Build System
- Test frameworks
- Continuous Integration / Continuous Deployment
Source Code Management System (SCM)
Generally, we develop software iteratively. We try out something to achieve an interim goal and target the next milestone, thus evolving our software. The ability to store software (code, configurations, tests, scripts) in a safe place is provided by a source code management system. This system enables us to go back to an earlier version, and prevents accidentally losing our work forever. This is typically hosted on a server where we don’t actively work.
A good SCM system should enable you to work in a team. Someone makes code changes and pushes them to the server, and you can get his / her changes. It will also allow you to revert or remove your own changes and someone else’s changes if they are not needed or are plain wrong.
There are many SCM softwares available. To begin with I would recommend creating your own github account. Git is a very powerful SCM tool and an industry standard these days. There are many alternatives to git, like svn, perforce, clearcase etc.
Generally students start learning a programming language on an IDE (eg: eclipse, netbeans, Visual Studio). The same IDE then gets used for building and debugging. There is a very intuitive GUI from which you can start the build, run the code and debug using the debugger.
When we work in a team and everybody is contributing their code to some SCM, we need to build from the code which is contributed by everyone in the team. This is done on a build server. The build server pulls all these changes and runs a build. Usually command line is used for scripting these builds. The commands for these builds are provided by the build system.
As there is no need to rebuild components for which code has not changed, the build system identifies components that are affected by the code change. It minimises build times by rebuilding only the affected components. The build times are crucial in industrial software where source code easily goes over a few hundred thousand lines.
For platform dependent languages like C / C++ which need platform specific compilers, the build system creates the command line for each platform. Eg. On Windows, the build system would create solution files for MSVC while on Linux, the same build system could create Makefiles. The same source tree is used for both Linux as well as Windows builds.
While learning programming, we try to run the code and see if it performs as we expect it to. If it does not, then we start making changes for all the cases that fail. In industry it is preferred, rather compulsory, to write test cases which can be run automatically. If someone makes a change in code to fix a bug, he / she could run the tests and see if something else is broken because of the change. Once all the tests pass, a new test case is added to the suite of tests, for which the change was made.
The issue with modern software is that it is usually only a part of the whole system / workflow. Hence we need tests at different levels. If you have written a concrete class in Java or C++, you would automate its testing, so that new changes don’t accidentally break your class. Your class would be a part of a whole library and be used by other classes in the library. Then you need to automate tests at a library level. If your component runs as a separate process, then you could automate tests at component level. Based on the inputs to your process, it would generate output or log, which could be tested against expected output. Finally you could automate tests at the system level. This automation could get different processes up and running and simulate user behaviour, be it GUI or messages from other systems.
Continuous Integration / Continuous Deployment
Once a software developer is confident of his changes, he / she pushes it to the source code management system. We need a way to build his / her changes along with everyone else’s code and run automated tests on it. This process is called continuous integration. Jenkins is one of the open source tools available for this.
Continuous deployment is the automation of delivering that software further for testing to the QA or UAT deployments.
Other than the actual code, most of the work done / described above needs some form of scripting. There are many scripting languages and custom scripting languages for tools like CMake.
Essentially, if a software developer is repeating any of his steps during his day to day job, he could write scripts to automate these steps. Python is a very popular scripting language, and sometimes even used for product development. I would recommend using python regularly. Knowing bash scripting also helps if you are a Linux user.
Software development is much more than writing code for solving a business problem. Knowledge of the entire delivery mechanism makes a software developer complete.