All developers know that they need to test their code. What new developers don’t understand is that the longer a bug exists in their code throughout the software developer lifecycle, the more expensive it costs to fix it. So what do you do? You start with the basic techniques I discussed in my last post. But that is not the end, only the beginning of the quality journey. Your next step is to bake Quality into your process, whether it is waterfall, agile, kanban, lean, etc. You think about quality in every stage. See some examples below of how to include testing throughout each phase of your software development process.
- Architectural Design – Plan your solution out before you write your code. This includes how you will test your application. Sometimes this means writing your functions or methods differently, or creating some test harness code. Plan this out beforehand.
- Code Standards, Conventions, and Style Guides – Set the standards with the team, making code easier to read, modify, test, and predict. Do you want to follow certain naming conventions? Are you a fan of Hungarian Style? Particular about indenting? Does bracket placement matter? How about spacing? Document it all, and stick to it.
- Use your User Personas – I bet at one time or another, you or yours UX department has defined a series of personas to help define and prioritize features. You should do the same for your code – use the journey of your personas to help you define what is critical for testing.
- Unit test your front end code, too – You have probably written lots of unit tests against your service layer and database code. And, you probably have functional tests to exercise all that front end code. But don’t forget to unit test that front end code, too. Libraries to facilitate this are mocha, karma, jasmine, jest, enzyme, selenium webdriver, cypress, puppeteer, protractor, and many more.
- Improve your Definition of Ready -Improving your code quality starts with purpose – what is the objective of your effort? Ensure you have documented enough of your expected outcomes. Just be sure not to take it too far – this could become an agile anti-pattern.
- Improve Acceptance Criteria – Two great mnemonics to improve your acceptance criteria are INVEST and SMART. Read more about them here. Remember the thoroughness of your acceptance criteria directly impacts code quality.
- Peer Code Reviews – One of the best ways to identify bugs as early in the process as possible. Two heads are better than one. Learn from your peers and catch errors early. And here is a great article you can read about peer code reviews.
- Static Code Analysis Tools – Just like your coding standards and style guide, these tools analyze your source code (usually straight from your source code repository), compare your code against a wide range of rules, and help you identify areas that need help. Some examples of popular Static Code Analysis tools are Lint, AppScan, FxCop, StyleCop, Resharper, NUnit, SonarQube, and others.
- Dynamic Code Analysis / Vulnerability Test Tools – These tools are run against code actively running on a server in an attempt to measure resources used, find complexity, identify errors, or uncover vulnerabilities.
- Test Driven Development – Following this methodology, you think about your code first, write test cases that fail, and finally write your code until your tests pass. Then you can write more test cases, or adjust, until you are complete.
- Behavior Driven Development – This is a methodology to define test scenarios using natural language, following a specific pattern, just like the user story. In fact, these scenarios can become your acceptance criteria, and using a tool like Gherkin, can become tests directly by Cucumber. Read more about BDD, and the benefits of BDD and TDD.
- Refactor – Just as much an art as a science, refactoring your code helps you to reorganize, simplify, provide focus and improve.
- Test Data, Test Data, Test Data – Sometimes, the key to testing all your scenarios is setting up your test data. Setting up all your automated test scenarios? Need an existing user to test a new feature? Need to mock results from a downstream system? Running a load test? You need data. Plan this out just as diligently as you would your test scenarios.
- Run your tests in all environments – Can you run your tests on your local machine? In Dev, Test, and Production? Both Green and Blue environments? Can you test all your downstream systems too? Is there data to be purged, or added to the environment? Need a flag to indicate this is test data? Plan this ahead – with your infrastructure teams, your partner systems, databases, and product teams to make this happen.
- Plan your Rollback before you need to – Not every release is a success. Faced with a production issue, you have to make the tough decision… roll back, or forward fix? What if you used Flagr, your entire feature was behind a feature flag, and could be turned off at the flip of a switch? What if you deployed using a blue / green strategy, and could roll back by flipping environments? Or kept a library of deployed code to re-implement at a moment’s notice? Plan your strategy ahead of time.
My next blog post will cover test strategies and techniques that can help you better define your test cases, and approach your code in unique, thorough, and thoughtful ways.