Tag: software development

  • Don’t Use Code Coverage

    I got asked in a seminar recently how to perform code coverage for T-SQL. There aren’t a lot of options, but there is a project from Ed Elliot called SQLCover that looks to examine how much of your code gets called from a test. There may be other methods, but my question back was why does code coverage matter? There were a few reasons given by various people, but ultimately the original questioner said that their boss wanted a report.

    That’s fine, and it’s a valid reason to try and measure code coverage, but is that an effective use of developer time? I don’t think so, especially as trying to meet some code coverage goal is fraught with all sorts of issues. Apart from various good points on Stack Overflow, no shortage of people have blogged about the problems of relying heavily on a code coverage metric. I won’t repeat all the arguments, but I’ll give a few of my own.

    First, someone pointed out that you want to be sure all your code is tested. I disagree with that, especially in many  long dev cycle applications. There are all sorts of enhancements I’ve seen in many applications that never get used. While you should certainly check them for security issues, if the features aren’t being used, remove them. Since most of you don’t implement tests for security issues, I’m not sure there’s value in telling you to write a unit test for logic or functionality.

    The other issue with code coverage is that anyone other than a developer using this metric will put pressure on the developers to write more tests. Some developers may write good tests, but I wouldn’t be surprised to have tests written that always pass and aren’t checked for correctness. Tests like these are misleading and potentially create more bugs since anyone refactoring code might think their changes haven’t caused an issue if the test passes. Bad tests, IMHO, are worse than no tests.

    I do think that code coverage can be valuable. If a developer is looking to ensure that some part of their code is being checked, especially in long stored procedures, then code coverage can guide them to a place that might need  testing. Since most code needs more than one test, covering more than one case, code coverage doesn’t help. I’d prefer a developer spent more time thinking about how to build better tests (or experimenting) than looking at coverage reports.

    And if you need a code coverage report, try my technique for building one

    Steve Jones

    The Voice of the DBA Podcast

    Listen to the MP3 Audio ( 3.8MB) podcast or subscribe to the feed at iTunes and Libsyn.

  • Rewrite Your Code Tomorrow

    One of the things that many developers learn over time is that they write better code with practice. In fact, some of the time a developer will find that if they write a bit of code to solve a problem, they’ll come up with a better solution a day or two later, as they’ve had a chance to think about the problem. Even while moving on to other code, their brain will continue to examine the previous solution, inherently knowing the approach wasn’t the best.

    Many of us see this with our code over time. If we look back at something we wrote a year or two ago, many of us cringe. At least, most of us cringe, especially if we constantly look to improve our skills. We see that old code as poorly written, in a way that we might never want to repeat in our career. I think that’s a good sign that we are moving forward and learning better patterns over time. If you don’t view any of your old code as poorly written, I’d stop and get a second opinion. You certainly might have written some great routines that stand the test of time, but more often than not, I find places where I’d improve code. Having someone else review my work might help me build better skills.

    One of the things I heard recommended recently was that developers solve some problem, commit the code in their VCS, and then tomorrow, redo the work. Start the day by deleting that section of code (that proc, method, class, etc.). Then move forward and rewrite the solution, not trying to remember what was there, but by resolving the issue. Plenty of application developers find they’ll write similar logic, but better structured code. Even if you don’t believe this, conduct an experiment on a small section of your code.

    I don’t know if we’d come up with the same results with T-SQL as many of us tend to solve the problems the same way across a short period of time. However, maybe you’d like to post a mock up of your challenge and solution, and ask for some opinions. We have great forums at SQLServerCentral and some really sharp SQL developers. You might get the validation that you built a great solution, or maybe you’d get some ideas on how to improve both your code and your skills.

    Steve Jones

    The Voice of the DBA Podcast

    Listen to the MP3 Audio ( 3.1MB) podcast or subscribe to the feed at iTunes and Libsyn.

  • I Will Write Bad Code

    I’ll write bad code. I know it will happen. I’ll produce a bad query, incorrect logic, or the wrong data transformation being returned.

    This won’t be a malicious act. It might be because of ignorance, or perhaps just a simple mistake. My code might be the result of short-sightedness or not accounting for a potential situation. I might even misinterpret poorly written specifications and place the blame on others. Maybe I’ll misread the code and won’t realize there’s a problem.

    And, for sure, this code will get deployed to production.

    At some point I know this will happen, to me or someone else. And for whatever reason, I need to account for that fact in my software development process. I can’t prevent mistakes, as decades of software development have proven. Despite my best efforts, code reviews, the tests implemented in QA and elsewhere, bad code is going to get deployed.

    The important thing in any software development project is how you handle the mistakes. How do you move forward, and certainly, how do you apply a patch? Can you do it quick enough to minimize the impact to clients? Or must they deal with the issues, developing the workaround or missing functionality for a significant portion of time? Or will they consider abandoning your software for some other vendor?

    One of the reasons I continue to advocate for a DevOps approach is that a known process can enable you to fix your mistakes in a timely manner. With a consistent approach to writing, testing, and deploying software, you can apply a patch when it is needed. Certainly the code needs to be logically fixed, but a reliable process will help ease all the overhead of getting your code to a production system.

    DevOps can be implemented many ways, and if applied in name only, things won’t improve. We can’t say we’re using DevOps, or we’re coding faster, or we release every week. We need to really implement the three ways. However, if you approach your project and staff with the idea that although things are flawed, they can be improved and made better, you’ll find that you can deliver those fixes for clients in an extremely timely manner with a minimum of risk.

    DevOps allows us to move faster, but that’s not the goal. The goal is that we improve things and have confidence that we can release when we want to, in a repeatable, reliable, less risky fashion.

    Steve Jones

    The Voice of the DBA Podcast

    Listen to the MP3 Audio ( 3.7MB) podcast or subscribe to the feed at iTunes and Libsyn.

  • Database Development Made Easy

    I ran across this post on developing database with SSDT. It has a lot of steps, and reading through it, I find this to make some sense, but I’m not sure I think this is easy. I can see why developers find databases to be a pain to work with. There are a lot of steps in this post to just setup and configure a database project. Databases are fundamentally hard to work with, as the model of maintaining state between changes and ensuring data is not lost can be hard. While the concept is similar to keeping track of configuration files, the scale of data in a database is vast and ever changing. Tooling to manage data that might need to be recovered isn’t very practical.

    I ran across a developer that was trying to automate their database development. They used tooling to deploy a table to a production system. The application connected and data was stored in the table. The developer then dropped a column from a table and deployed this change. It worked, but this was a mistake and this person decided to deploy the previous version of the database, with the additional column restored. The deployment worked, but there wasn’t data in the column that had been dropped, and added back. Why not, asked the developer?

    Many people are of two minds here. One, any tooling or automation should preserve data and allow for rollbacks. In the application world, this makes perfect sense, and even the data our application uses (reference files, configuration files, etc.) are restored if we rollback to a previous version.

    For the data people, this makes no sense. The data in a column could be of significant size. We often plan for systems to reach millions (or more) rows of data, and trying to save the state of this data before a change isn’t practical. Even if we were to store changes items for a few deployments, it’s entirely possible that putting the data back wouldn’t make sense as related information in other tables might not match up correctly. Consider the case of a financial system and restoring old money values. Who knows what issues would be created?

    For developers, this highlights one of the things they dislike about databases. They are must manage state transitions across deployments, and rolling back to previous versions isn’t often possible. This is one reason that I have often performed a backup before major deployments, and even today, in an automated DevOps process, I’d want to perform a backup if any significant data were being changed or deleted.

    I’ve spent a lot of time advocating for DevOps and smoother, modern database development practices for the last few years. I don’t want the database to be a hindrance or impediment to change, but I also don’t want to compromise the integrity or safety of data. My pitch has always been that our database automation tools at Redgate don’t perform any magic. They smooth, and hopefully speed up, the process of making database changes that we’ve used for decades. They save you time and effort, just as other tools may do, but they can’t change the rules of relational database changes.

    Everyone developing code inside or connecting to a database needs to understand how transactions and data changes work. There are rules and restrictions the protect our data. These mean we need to sometimes plan and consider the consequences of our actions. This should also mean that despite wanting to move faster and make changes, we can’t treat data placed in columns as malleable in the way a method in C# can be changed back and forth. We need to account for, and protect, the information stored in our systems. There are patterns that can help you evolve your database from one state to the next, but there isn’t any magic that lets you drop and add data storage elements without some preparation for handling the data itself.

    Steve Jones

    The Voice of the DBA Podcast

    Listen to the MP3 Audio ( 5.1MB) podcast or subscribe to the feed at iTunes and Libsyn.