Brendan Enrick's Blog

Daily Software Development.


Daily Dev Speedup - Use Lightweight Tools for Lightweight Work

by Brendan Enrick Thursday, June 11 2009 17:14

Everyone is always trying to use the best possible computers to do their jobs. Developers buy high performance machines so they can write code faster. Some improvements can be made to your development speed without going and spending large sums of money amassing expensive tools and machines.

As any craftsman will tell you, "you need to have the right tool for the job". A lot of times there are quick queries that we need to write to check bits of data and such. If this is what you're doing, it is sill to open up SQL Server Management Studio just to check this. The overhead of opening up and application and using it will have you wasting plenty of time. Use a tool like LINQPad, so you have a lightweight application you can easily open and work with.

If you need to make a code change to a config file or some very minor edit to a text file of a variety of languages I recommend using a lightweight text editor like Notepad++. This will save you a lot of time over opening Visual Studio, and it is much more advanced than Notepad. It has a good amount of advanced features and isn't a full-featured IDE like Visual Studio.

Using these lightweight tools in combination with the heavy-duty tools like SQL Server Management Studio and Visual Studio will make things a lot easier.

Comments (0)
Tagged as: , ,

Time-Tested Testing Tips - Part 5

by Brendan Enrick Monday, June 8 2009 12:22

Welcome back for another exciting tip for those developers writing unit tests. Today we will be looking at assertions in unit tests.

Only Assert On One Case Per Test

When people start writing unit tests they do the natural thing with their Assert statements; they write a bunch of them in the test. This makes a bunch of sense, because you don't want to repeat yourself in your tests. This is not bad as long as all of the asserts are asserting the same expectation with different values. If you are testing different cases then they need to be separate test.

The reason for this is that unit testing frameworks tend to abandon a test as soon as an assertion has failed, so you get less information if you have grouped many tests cases into one test method. By making sure that every test method contains only assertions dealing with the case in question, we will garner valuable information from each test. Maybe we will discover that the cases with negative numbers and the edge case, zero were the ones to fail. If we had grouped the assertions into one method, we would have only had one failed assertion and wouldn't have gotten all of this info. For example we might have only had zero fail if its assert was first, and then we would be thinking this was a problem with the edge case when it was really a problem with all numbers less than one.

Group Your Asserts Together

If you can, try to keep your asserts together at the end of the method. This will make them much easier to read and keep track of. I've seen some tests where someone wanted to assert before changing a value. A better way to handle this is to store the value you need to hang on to in a variable and assert at the end with everything else. This will make your tests a lot more maintainable, and someone down the road editing the test will sure thank you.

Keep Your Assertions Concise

You should have no logic in your assertions. Don't ever access a property or call a method in an assert statement. These are what someone looks at to try and figure out what is going on. Use simple, concise variable names which explain things. If assertions are cluttered and confusing, your tests will be very difficult to use.

Remember to be careful with your asserts. They should be clean, easy to read, and managed nicely. Their maintenance is extremely important to your tests.

Daily Dev Speedup - Using Visual Studio Snippets

by Brendan Enrick Monday, June 8 2009 08:53

In Visual Studio there are code snippets which can be used with auto-completion. These are a lot of the common structures used by developers when writing code. They are customizable using Visual Studio, but I find it much easier to use editors like Snippy. So if you were not using snippets because one of them was not exactly the way you wanted it to be, give a snippet editor a shot.

I highly recommend creating your own snippets as well as customizing them. I for example use one to create tests. I type 3 letters hit tab and type the name of the test method. This saves me the time of typing the attribute as well as "public void" and some curly braces every time I write a test. Yes, I know that a lot of these are simple little things, but trust me when I say that they all add up into faster development. How do you think all of the visual studio add-ins make money? They allow for a lot of little speed boosts which keep developers coding faster.

Daily Dev Speedup - Working With Words

by Brendan Enrick Tuesday, June 2 2009 15:52

A lot of applications allow you to work with a group of text at a time. For the purposes of this post I'll call them "words". When I say a lot of applications this includes the powerful IDE called Notepad. This cool trick can be applied in a lot of different places. I am sure you'll figure out some interesting uses for this.

The key (literally) to achieving this productivity from working with words is the Ctrl key. By holding it in combination with other keys we can work with words. The three main things I want to discuss when working with words are: moving from over a word, selecting a word, and deleting a word. As you can probably guess to move through a word you use Ctrl with an arrow key. To select a word you hold Ctrl as well as Shift while using the arrow key. To delete a word you can use Ctrl  in combination with Delete or Backspace. (Yes, I lumped delete and backspace together even though they are technically separate operations.)

Here is a demonstration in Visual Studio showing how to move over words followed by select words followed by deleting words.

Comments (0)
Tagged as: ,

Writing Clean Code is a Process

by Brendan Enrick Tuesday, June 2 2009 15:02

I was copied on an email recently from someone reluctant to begin writing unit tests for code. One of the complaints about the idea of starting late game adding in testing was an interesting one. The person mentioned that because they're starting to test so late that they will not get "all the benefits of TDD". Well, that person is correct. However, that should not stop anyone from making things better.

Recently the "boy scout rule" was brought up to me in the context of coding, and I admit I'd never thought of how well that example applies. The scouts have a rule to leave a camp site cleaner than they found it. This is a great idea since it means that gradually overtime you will be making improvements. No one is saying to go and spend a month cleaning things. That would be a HUGE waste of developer effort from the customer's perspective.

A good rule to live by and one I try to practice regularly is to refactor and clean a little bit every time you touch a file. Even if this just means adding a test or even renaming a bad class, interface, or variable name, the important thing is to make these minor improvements every time you get into some piece of code.

Another complaint about switching was that developers would be spending 50% of their time writing tests. Well I will say that that isn't quite right, but the idea there is accurate. The amount of code written is about half test code and half production code. The advantage of having the tests is less time spent debugging and fixing. Most developers have heard about the cost to fix bugs at different points during the development lifecycle, but I will summarize it as, "the sooner you catch a bug the cheaper it is to fix". If we have tests in place we find the bug sooner. This means the end cost is less, so writing the tests should save us money during development as well as during maintenance.

I admit when I first got introduced to testing I thought a lot of the same stuff. I figured the tests would slow down the development and wouldn't help very much. I figured there would be all these issues, and I'll also admit that it is pretty tough to start doing. Once you start writing tests for things you start to see some of the benefits. The best thing to see is when you change some piece of code and something seemingly unrelated has a test break. That is when you realize the connection and prevent a bug from being created. That is one of the best aspects of testing.

Daily Dev Speedup - Selecting and Dragging Lines

by Brendan Enrick Tuesday, June 2 2009 09:24

Yesterday I posted about how important it is to use keyboard shortcuts and tools to help you write code faster. Any developer working towards self-improvement should be looking not only into how to program better but also how to program faster.

Today I'll start by mentioning a pretty easy one. If you use Visual Studio I really hope you keep line numbers on. I could probably claim that as the first tip since it does speed things up. This is especially true when collaborating with someone when they can say the line number about which they are speaking. For the real tip I'll be mentioning here you do not need to have the line numbers enabled, but they give you more surface area to click on.

This actually works in a lot of programs, but I'll explain how to use it in Visual Studio. All you need to do is click on the left hand edge of a line and you will be able to select the whole line (this includes the new line at the end). If you click and drag you can select multiple whole lines easily.

Along with this trick you are also able to easily select any text that is highlighted and you can click and drag it to a new location. These work well in combination because rearranging lines becomes very easy. Moving any code at all in fact becomes very easy.

Below is a demonstration of what can be done by clicking and dragging text around and highlighting using the line numbers.

Keeping Code Out of the Code Behind

by Brendan Enrick Monday, June 1 2009 13:52

In ASP.NET development (and yes even in MVC) each page is able to have associated code. This is traditionally (before MVC) how someone would add code to a page. This was much nicer than what was seen a lot on the classic ASP days when a lot of code would be littered between HTML controls.

However, when one is introducing code into the code behind great care must be taken. This is because the code behind is really not the location where most logic goes. If we take a moment to think about what the ".aspx" file is, we will probably come up with something along the lines of, "the file where we decide how we're going to display things to the user." So this is about display issues.

Should it know anything about a database?

NO!

Should it know that there is any form of persistent storage?

Probably not.

So what should it know about?

It needs to know how to display things to a user and that is it.

So what do I do once I've got code in the code behind that is business logic?

Step 1 is to try to get it refactored into the correct class. Create new classes to handle the business logic. Your pages will call these classes to do the required work.

If you don't know where to put something yet there is an intermediate step better than having it in the code behind. You can make pseudo-MVC by creating another class. So create a class with the same name as the page but add "Controller" onto the it as a suffix. Then put the logic in there. This will give you a bit of seam which should allow you to test the code.

Keep in mind that the MVC pattern is very cool. ASP.NET is very cool, but it is a fairly old pattern. The idea of it is just separating things. We can do the same thing with ASP.NET if we are careful not to clutter things. We can achieve similar results. Sure it isn't as nice and pretty as MVC, but it gives us seams while separating the concerns of our code so that it is maintainable.

Comments (0)
Tagged as: , ,

Time-Tested Testing Tips - Part 4

by Brendan Enrick Thursday, May 21 2009 22:20

Rather than spending the time with needless introduction, I think I’ll just jump right in today. I’ve got a few tips I am going to post today.

Reproduce Bugs Using Unit Tests

Yes, this is another test driven development method. When you’re looking for a bug, it is very common to try to reproduce it. What you might try to do instead of doing this is reproduce the bug manually, fix the bug, and then write a test to prevent it. Well I think that is a pretty bad way of doing things. Reason number one is DRY; don’t repeat yourself. Why did you reproduce it once manually and once automatically? I also wonder how you know you’ve written the test correctly. If it never failed you can’t be certain you’re testing the bug.

If you write this test first you jump right to finding the bug. Seeing the red of the test failing tells you that you’ve found the bug. Having this test will also let you run the buggy code multiple times, which can be useful if you can’t tell right away what is causing the issue. This becomes a faster, easier process. Since you managed to get the failing test, you know that once you’ve fixed it that you’ve at least fixed the bug you tested. Going the other route you were left to assume that you fixed the bug. We all know what happens when we assume… Yes, that is correct, we are sometimes not accurate.

Keep Dependencies to a Minimum

Yes, this is another situation where we are thinking about both the test code and the production code. If you’re finding that the objects you’re testing are requiring a lot of set up you probably need to simplify things. Get some of these tests in place first. These will help you to clamp down the behavior you want to maintain while you refactor. You’ll want to observe plenty of principles while doing this especially the single responsibility principle.

For example if you have a method which takes in a parameter called BankAccount, but all it really needed was the AccountNumber you should alter your method so it takes the AccountNumber instead. This will make testing easier and it will also lessen your dependence. These are great things to do.

Do not pass an object used to get another. Pass only what is required for something to achieve what it needs to. You need to keep things minimal in this sense. It will make testing as well as maintenance much easier.

Make Things Work Before Making Them Right

It is difficult for a lot of us to follow this, because we know so well how bad some types of code are. We try to avoid having ugly code by spending lots of time and effort trying to get things right the first time. Then we aren’t even sure they work.

Plenty of times in the past, I’ve had programming partners who wanted me to write my code better than I did the first time. Sometimes I made the foolish mistake of listening to them. If you’re dealing with some complicated logic you need to write it the ugliest easiest way you can. This will let you get your tests passing. Once your tests are passing you are free! By knowing that the test and the code are working you have freed yourself up to refactor. You don’t have to think quite so hard since you have this safety net in place. Try something. If it does not work, just revert back and try something else. You will quickly find a design that you like and keeps those tests passing.

Sometimes just seeing the working code will lead you to seeing a better design for it. This situation is much better than if you had spent a lot of time coming up with some way of designing it. The design might not even have worked the first time, and then you would really be wasting time.

I hope you’ve enjoyed these tips. Remember that testing takes a lot of practice. You’ll never see any benefits from testing if you don’t keep writing tests.

Time-Tested Testing Tips - Part 3

by Brendan Enrick Wednesday, May 20 2009 09:23

Context switching is very costly and this same issue can be seen when writing tests, but I would argue most importantly in maintaining and reading tests.

There are three main parts to a test. The first part sets everything up, the second part takes some action, and the third part expects certain results given the the start and the action taken. In this tip I'll be talking about the first part, the setup.

Keep Test-Relevant Details Visible

I've said in the past to treat test code just like any other code. However, there are a few reasons to break from this rule. One is the context switching which will be caused by extracting information which is important to a test. Let me explain what I mean with two examples.

Example Using Helper Method

[Test]
public void CalcInterestRoundsToTenthPennies()
{
    decimal initialMoney = 100.00;
    decimal expectedInterest = 33.333
    InterestCalculator ic = GetTestInterestCalculator();
    
    decimal actualInterest = ic.CalcInterest(initialMoney);
    
    Assert.AreEqual(expectedInterest, actualInterest, 
      "CalcInterest did not round to a tenth of a penny correctly");
}

Example Without Helper Method

[Test]
public void CalcInterestRoundsToTenthPennies()
{
    decimal initialMoney = 100.00;
    decimal interestRate = 0.3333333333;
    decimal expectedInterest = 33.333
    InterestCalculator ic = new InterestCalculator(interestRate);
    
    decimal actualInterest = ic.CalcInterest(initialMoney);
    
    Assert.AreEqual(expectedInterest, actualInterest, 
      "CalcInterest did not round to a tenth of a penny correctly");
}

Notice here that you can tell a lot more about what is going on in the second one, because you know what percentage is being used to calculate. You cannot tell that the first one is accurate since you can't see the percent. I recommend trying to keep the amount of values to a minimum and if you're writing your code well you'll have few enough dependencies that you will not have a problem. These helper methods as you can see make it so you will need to go to another location to see what was initially created. In some instances they are useful, but use them sparingly as they might hide away details.

Do Not Unit Test Third Party Frameworks

Make sure that what you're testing is part of your code and not someone else's. If you're testing code you have no access to you better not be keeping that around as an automated test. You're wasting your time if you're creating automated tests for this code. If you find a bug in the code you can tell someone about it, but you probably can't fix the code. If it is an open source project you're testing then go test the code in their test library and fix issues you find. You will be doing them and yourself a favor. Don't clutter your own test library.

Write Automated Tests Whenever You Are Curious

If I ever wonder how some piece of code or a class works or something, I could go write a simple application and test something out. I certainly do not waste my time though. It tends to be much faster just to write a test to answer my question or learn something new. If I want to try something out I just write a test. If it is an internal piece of code I go look at the existing tests, and if it is not I write a temporary one just to try something out.

Unit tests are quite useful for this sort of thing, and since I have keyboard shortcuts mapped to run them they're very fast. If you really want to test a lot, you need to start using them all the time. They become very easy to come up with and write once you practice them enough.

Time-Tested Testing Tips - Part 2

by Brendan Enrick Tuesday, May 19 2009 22:25

In the first part of this series of testing tips, I mentioned a couple of tips I believe to be quite useful. I am going to continue this series today by writing about a couple of more ways to write better tests. I also plan to give reasons for testing and describe different benefits of the practice as I go.

Test Driven Development

Yes, I am going to bring this up. Plenty of people have latched onto the idea that testing code helps make code better. A lot of people even believe that it makes the process of writing the code faster. I see a lot of people who are reluctant still to use test driven development. I know I am throwing around a buzzword… or maybe I mean buzzphrase since that’s actually three words.

I don’t plan on doing TDD justice here since I am trying to keep these tips relatively short. I just hope this is enough to inspire people to go read, learn more, and try some test driven development. I am going to give some quick reasons why developers testing their code should write the tests first.

  • You will not want to go back and write it later. Sometimes you are going to go back and write the tests for the code you have already written, but what happens if you decide you’re going to write a lot of code and then go back and add the tests. Now you’re talking about a lot of testing all at once. There is a good chance you’ll cut corners and maybe skip entire aspects of the testing. I know I would be tempted.
  • How do you know what kind of interface your new code needs if you’ve never used it? If you start by trying to use some code that does not exist yet, you’ll be deciding how you would want to use it. Now you’re probably thinking you could do that anyway. If you write code to use some new feature you will know the design is easy to use and work with. You just made it up and used it in the test. If you didn’t write the test you had to guess what interface you will want later.

Organize, Refactor, and Take Care of Your Tests

I recommend you repeat this daily, “My test code is just as important as my production code”. I think this is a very good point to remember when you’re writing tests. All of those principles you apply when writing production code should be followed with test code. DRY, SOLID, YAGNI, etc. are all important even with the testing code.

Obviously duplicating code can make your tests difficult to maintain. What if some business logic changes? If you were repeating yourself you now have the fun task of going through a dozen tests changing each one, but if you had not repeated the same code you might have been able to update one location in the test code. A lot of people are concerned when the line count of a single file gets large and they will refactor it into multiple manageable files. This same policy should apply to test classes. If you’ve ever gone into a test class with way too many classes, you probably know how difficult it can be to maintain.

Tests exist to make development easier, and if they become difficult to maintain then something needs to change. I certainly don’t advocate spending large amounts of time refactoring the tests, but since they are supposed to increase the longevity of the application they must also be maintained.

Adjust Your Style to Your Test Framework

I obviously recommend that everyone use a testing framework. There are plenty of them out there, and they supply a great deal of the tools you’ll need for testing. They come in all languages, flavors, and colors. You might look into these NUnit, MSTest, JUnit, CppUnit. What is important is that you make sure you know how your tools work so you can test best with them.

I will elaborate on a couple of examples and perhaps down the road I’ll give some more specific examples.

Some tools show you a list of test names, and only minor details about why the test failed. For this you usually need to go the a description view or something similar. In these cases it is important to name your tests effectively.

As an example if I have a method called Add and it takes two parameters a and b. I might write a test for that method. If I name my test TestAdd, and that test fails you know something is wrong in that method, but you do not know what failed. If I had instead made a few more specific methods you could glean more information from the test having failed. Some examples of tests I might create are AddTwoZerosShouldBeZero, AddNumberToZeroShouldBeTheNumber, AddPositiveNumbersTest, AddNegativeNumbersTest, etc.

Some parts I would lump together like positive numbers and negative numbers. It is important to handle a couple of different scenarios as well as the edge cases. I could have done negative and natural numbers and that would cover all numbers, but I wanted to make sure the edge case, zero, was handled correctly, so I test it separately.

People can argue back and forth all day long about whether you should have a lot of small tests or group them together, but this is what has worked well for me in the past and I hope it works well for you also.