More on Fuzzing

Development magazines are paying more attention to fuzzing. Fuzz testing is subjecting an application to random data to see what breaks. This is applicable to web apps. It can be part of a comprehensive security test. Fuzz testing let’s you try inputs that stimulate paths a tester might not normally think about, or have time to manually perform.

There are free fuzz test generators out there. Some are Peach Fuzzer, MiniFuzz, and Spike. There are also some commercial products to assist with fuzzing as well. But let’s get back to why fuzzing is a good idea. Normally you test positive aspects of requirements. However you should also be testing for things not covered by any requirement. This is where fuzz testing can come in real handy.

I am a developer. Right now I am not employing fuzz testing yet. However I hope the independent test team on my project is hot on the technique.

Pairwise Testing

Testers often need to verify systems with many related variables. This can result in a huge amount of test cases. Often the combinations can be out of control. However a technique called Pairwise Testing can reduce the amount of test cases while still covering all scenarios. The hard part of this is generating the minimal set of cases. This is a good time to use a program to do the hard work.

One pairwise test case generator is Pairwise Independent Combinatorial Testing (PICT). This product is based on a tool that Microsoft themselves use. There is a recent new tool called QICT which accomplishes the same task. The beauty of QICT is that the source code is provided free of charge.

Pairwise testing is good for many test scenarios. Some good examples are testing databases and configuration data. I know that I often have an onslaught of test cases that I think need to be executed to provide full coverage. I might just have to use a tool such as PICT to make my job easier. This can potentially reduce the test time necessary, and improve my test throughput.

.NET Runtimes

Microsoft is changing the way that new versions of the .NET framework impact existing applications. Here are the goals that Microsoft has. Installing new versions of the .NET framework should not break existing applications that are installed. The new version should also be backward compatible. Finally applications should run against the version of the .NET framework they were released under.

These new Microsoft goals are realized in the .NET framework version 4. This is a statement that must be tested thoroughly. Previously the new .NET frameworks would be used for any existing installed application. However now Microsoft claims the latest version will not break existing apps. I can envision the need of virtual machines to test .NET framework upgrades, and the impacts on applications which depend on prior versions of the framework.

Microsoft claims that the .NET framework version 4 is the most backward compatible version yet. My recommendation is to trust, but verify.

What Matters Most

I read a whole issue of a testing magazine tonight. There was one article that stood out in my mind. It was an interview with a guy that had started as a junior tester in his company, and worked his way up to CEO. They asked him what is key for a tester to succeed. He had some very specific guidance.

A tester must know what the end user needs. The tester must also be aware of what the user wants as well. You got to know the business. You get this by getting involved with operations. Some other important traits include strong analytical skills.

This advice matches what I see on my own project. We have a bunch of GUI applications. There are some programs that run on the server that do loading and computations. Add on a couple back end programs that do communications and you have our system. There is nothing special with this layout. However the business knowledge is king. If you can somehow figure out what the heck the users are trying to accomplish, the system makes a lot of sense. Otherwise you will be totally lost.

The Trouble with ASP.NET

It is great if you can automate testing of software with unit tests. This is not too easy with ASP.NET from Microsoft. ASP.NET is a web development framework. There are multiple issues making matters difficult.

The first setback is that testing web sites requires transmission of HTTP requests, simulating browser clicks. The second trouble is the output. It is all HTML which is messy.

How do a lot of testers deal with web site verification? They end up clicking around looking for problems. Ouch. Microsoft's answer to the woe is ASP.NET MVC. So far I have no experience with the technology. However Microsoft is pitching it as the way to simplify the testing of web apps. We shall see.

Debugging Wrap Up

Two more trustworthy rules for debugging are to keep an audit trail and to only declare a bug fixed if you fixed it. The first rule is self explanatory. Just make sure you use a consistent format for all your logging. That will help later when you try to filter all the audit data.

If you think you have a fix, remove it and see if the problem comes back. If not, then you probably have not fixed the problem. You have to be sure of yourself here.

Here are some last ideas. Try and get a diagram of the whole system you are debugging. Feel free to ask for help. When you do get help, you should request that assistants just report the symptoms. You don't need theories. Good luck with your debugging. I have made a career out of this activity myself.

Details are King

Here are more tips to debug a problem. Keep testing older versions of the software until the problem goes away. Now you have narrowed down the build when the problem was first introduced. It should be easier to determine what changed at that time.

There are many instances where the smallest detail is the key to the problem. Let me tell you a story. My customer's acceptance team keep making the application crash. They said it happened at random. That never happened to me or any internal testers on my project. So I enlisted the help of the people experiencing the trouble.

I asked the testers to notice everything that happened before and after the problem. What was the weather like outside? Were the lights on? Did you sit close to the desk? Was there anybody sitting next to you? What time did it happen? You know. I needed to know all the facts, even if they seemed insignificant. Guess what? This helped us crack the case.

One tester found that when she swiveled her chair to the right, the application sometimes broke. Also when she dragged her spiral notebook from left to right the problem always happened. This keep attention to details helped her identify the cause of the problem. Each time she was doing these movements, she was pressing the space key on the keyboard. Sure enough that was the cause of the application aborting. Amazing.

One Thing at a Time

Here is a guideline for debugging. Only change one variable at a time. I am not talking about programming variables. I am talking about one factor in the state of the system.

This can be taken a bit further as well. Make a change and check the result. If the bug was not fixed, undo the change and make exactly one more change. Repeat. The converse is to fix just one thing at a time as well. Then you can go on to other bugs.

Now let's talk a little about tools. Don't throw them away even if they seem like one time tools. You should actually build the tools into the initial design of the system. Make it easy to inspect the internal state of the system during runs.

Next time I will talk about audit trails and logging in general.

Say No To Guessing

Here is a pseudo rule for debugging: Don't make guesses. What you should do instead is to compare runs that exhibit the problem with those that do not. That way you can narrow down the exact effects which contribute to the problem. This leads us to the Divide and Conquer rule I wrote about previously.

Theories about what the problem might be are not worth much. In fact, the can be counter productive. You will most likely waste time tyring to check whether your theory is correct or not. You end up right where you started, except it is much later in the day.

Now this is not to say that you should never harbor a guess at the source of a bug. You should just limit the amount of guesses you make. Once you get good at debugging, you can use few guesses to get to the source of the problem.

Stay tuned for a commentary on the use of tools for debugging. I will leave you with another debugging gem. Change but one variable each time you run a test. This will help focus your cause and effect research.

Hints for Debugging

Here are some more hints and tips to debug problems in systems. Let's start with some more general rules for debugging:
  • Duplicate the problem
  • Do not think too much
  • Narrow down and focus
Ok let's now get back to the tips and tricks. You got to really know the tools you use. That includes knowing the limitations of the tool set.

Don't guess. Act like a detective and look at clues. Once you think you have a solution, run the system with the same conditions that exhibited the problem and demonstrate that the specific problem was indeed fixed.

Record each step required to make the problem occur. Do not fake the problem. Actually make it happen like it does in real use. You might need to employ automation to speed up the process of creating the bug. That is fine.

I will continue next time with some more general rules for debugging. You know I will come back to tools. And I will examine cause and effect.

Understanding the System

You must understand the system before you can begin debugging it. Here is a novel thought. Read the instructions. This means you should go over the specification for the system. You can also read source code comments. Review the design documentation to gain understand.

Now you must understand one other thing which reading the documentation. You need to take what you read with a grain of salt. Don't trust everything you read.

On the other hand, you really need to know the contents of the user manual. Read it many times until you know it well. You must have a firm grasp on the fundamentals of the system. When I come back, we will get to the second rules of debugging - Make It Fail.

Debugging

Halfway though reading a book on debugging, I realized that I had read it before. It was a good book. So I completed it for a second time. There were a lot of good stories and examples.

The book was written in 2002. However the rules it presented were timeless. The author was actually a hardware/electronics dude. But he nailed the software debugging process down well.

The goal of the advice in the book is to help you find out what is wrong with a system quickly. If you fix your commercial software first, you get a competitive advantage. That translates to more money for your company. So you had better listen up.

When you figure problems out fast, you get to go home quicker too. I know this all too well. If I do not solve problems, I am there to midnight, and I have to return on Saturday morning.

It is difficult to find debuggers who follow the rules in this book. That means if you do learn and use these rules, you will be valuable. Let's first define some terms. Troubleshooting is trying to find out what is broken. Debugging is finding out why. This book is about debugging.

Let's get on with it. The first rule is "understand the system". There are eight more rules. I will be sharing some of these in future posts. Until them, happy hunting.

Acceptance Test Limitations

Our customer has a pretty mature organization. They have their own acceptance test group. They are all employees of the customer organization. Their goal is to test everything we do to ensure the stuff with work in Production.

A while back we delivered a major release. The customer has found all kinds of problems that we missed upon delivery. Luckily we were able to fix most of those issues. However there was a significant piece we were not able to deliver on time. We have been trying to deliver the results piecemeal. However the acceptance team is discovering this effort is producing a lot of bugs. Back to the drawing board.

Recently I read an article about the limits of acceptance tests. They cannot conduct a full regression test. You should not depend too heavily on tools for the tests. The testing only adds value to the effort. It needs management support. And the testers need to learn many skills for the project to benefit. I can honestly say that our customer organization has not let these limits hold back their testing. The acceptance test team really does add significant value to the project. My hat is off to them.

Stolen Art of Unit Testing

I just read a blog post by the author of the book The Art of Unit Testing. He said a PDF version of his book was being shared illegally. The guy even posted a link to one such illegal download. So I downloaded it. I read the first chapter. That's as far as I got. I won't be buying the book.

Even though I took a pass, there were some things to learn from Chapter 1. Your project may fail even if you have unit tests. If fact the unit tests can be a liability. It does not matter whether you employ Test Driven Development. You might still fail. I believe that.

The author does encourage you to use a unit test framework. The examples in his book use NUnit. He also states that unit tests should run quickly. They should be able to finish in a few minutes. He must be talking about some specific unit tests, not the tests for a big system. You should also set up you tests so they do not require manually configuration before running.

I will give the guy one thing. The PDF version of his book was pretty good for a PDF. Most PDFs I view are boring black and white things. He used color appropriately. Since he was getting ripped off by people passing around free copies of his book, I will give out a link to buy The Art of Unit Testing on Amazon. Good luck Roy.

Automated Acceptance Tests

Our customer is a savvy one. They have a full time team that conducts acceptance tests of our software. This team keeps on top of new requirements and the overall business. They make sure they are in the loop at all times during the decision making process. In the end, this team makes the final call on whether our software is ready for prime time.

Here is something new I have read that might help our customer's acceptance test team. That is automated acceptance tests. No that will not put them out of a job. It may make their lives easier. You write up your test cases in some English like language. Most of the time you focus on positive testing. That is, you test the normal case. The benefit it that you can run the tests against every new release.

Currently my customer does acceptance tests manually. That requires them to load up on resources during the software delivery period. It also means that the testers are forever generating huge volumes of interesting test data. That is a good step. However the tedious manual execution of the tests makes me dread the job. I must confess that they are successful in finding where our software breaks down or does not meet the business need. Automated acceptance testing might take their game to the next level. Do I hear a promotion in some acceptance tester's future?

Test Automation

A common theme I read a lot about is the automation of testing. At the root this is wise move. Automate your testing. Then you can code up some changes, and retesting quickly by kicking off the tests. The big three places where automation can be used are unit, regression, and system acceptance tests.

On our own project, most of the test phases are manual. Once in a while I will automate a unit test if I have the time. However we normally have no time in development. Everything is rush rush rush.

Let's step back a minute and define our testing. Unit tests is where small units of code are tested. Normally you write your test cases in the same language that the product is implemented in. You try to cover all the lines of code in your tests. There are popular frameworks which assist in this endeavor.

Regression tests are supposed to cover all the functionality in your product. This is difficult to achieve. There is not really a framework you can pick up to help with this. That is because the products themselves are very diverse. The regression tests themselves can check different characteristics of the system. This includes things like performance.

This one is getting long. So I will pick up with System Acceptance tests next time.

Time for TDD

Test Driven Development (TDD) is gaining more acceptance in programming circles. But at least one question still remains. When should you apply TDD? In other words, when do you develop the tests? A simple answer is to create the tests first. That way you have tested code from day one. However this may not always be the right way to go.

I read a blog entry stressing that TDD is beneficial for maintenance work. You should have mature code complete with self tests. However the very first class you write for a new system may not need tests right away. Testing may in fact get in the way of rapid progress. I myself am divided on this very topic.

In a perfect world, you would have understood all the requirements and performed a full analysis and design on the project. At that point you are ready to add TDD before you write the first line of code. The real world is never perfect. So this may not be the way to go. Sometimes you need to write some code to figure things out. I would not call this production code. This may be throw away code. And that code does not need TDD applied to it.

We do not use TDD in general on my project. I have tried it. For small tasks it seems to work well. But when everything is crazy and we are terribly behind schedule, the TDD goes out the window and we hack together solutions. Sure it is not the best way to go. But it is life. There is probably a time and place for TDD. That time may not be before you write any code.

Cost of TDD

I read a blog about a developer that tried Test Driven Development (TDD) for a day. He found that a useful way to generate the tests is to debug your code. When you find errors, you can write a test that checks for that bug. This would be perfect for my project. It is a maintenance project. We get trouble tickets all the tine that we resolve. It would not take much more effort to integrate the tests for the bugs we fix into a automated test script. We already do the unit testing for each fix anyway.

Getting back to the subject of TDD, the developer who tried it and wrote about it did not like it. He said the TDD technique led to very little actual debugging. He did gain some new respect for the method in general. However he would still not use it for everyday programming purposes. While the effort did seem to result in higher quality code, it took much longer to develop code that way.

When can you use TDD? I know we can’t use it on our project. We hardly have the time to race through coding and hack together some solutions on my project. If TDD causes the development cycle to double in time, we would never get anything done at my job. Here is the funny thing about this.

Perhaps we really are the best candidates for a TDD approach. The problem is that it would be a hard sell. One of the main things that drives our schedule is customer needs. And our particular customer wants more functionality in less time. They don’t seem to care about our methodology. Yes they do not like bugs. However they will tolerate bugs if it means they get a lot of features right away.

Production Volume

I read this blog about how you should test using volume comparable to production. Big hard disks cost little these days right? Wrong. Well yes some el cheapo hard disk can be found for a bargain. However that disk will never match the characteristics of our production server box.

Now I don't know all the details. But we have a massive box to run our production system. There is probably something like 128 processors on the darn thing. And there is more RAM in there than you could find on a mainframe.

Don't get me started about the super speed disk array we got powering our database. But I guess you get the point. You cannot compare your little bitty workstation with a production box. To do some is futile. I guess the only pearl of wisdom from the blog post I read was that you should not do tests if you only have a couple records in your tests tables. Point taken.

Oracle Application Suite

You would think a tool called Oracle Application Suite would be focused on some type of database work. Specifically it sounds like it does something with the Oracle Database. However I just read an article that tells how this tool can be used for testing.

The Oracle Application Suite is actually a part of Oracle Enterprise Manager. Now I have heard of this product. However I have seen DBAs use this to manage Oracle databases. But I digress. Let's get back to how Oracle Application Suite can be used to test.

There are three things that Oracle Application Suite does to assist testing. It helps load testing by simulating a lot of users logging on to the database. It also performs functional testing by automating test scripts. Finally it helps with all kinds of chores related to web application testing.

Now like most Oracle tools, I hope this one is free. If so I plan on checking it out. On a final note, I understand this tool integrates with other products. I guess I will have to play with it to find out how that works.

Fuzzing

I read an article in Software Test and Performance magazine about the topic “Fuzzing”. This was the first time I had heard this term. However recently I heard some of my team’s tester talking about the issues involved with fuzzing. So I thought I would write about this as well.

Fuzzing is a negative software testing method. That means you do not test for whether the system works correctly with correct inputs. Instead fuzzing concentrates on things such as inputting malformed data to an application. It also involves attempts to defeat system security. This used to be a hacking technique. Now it has been formalized as a testing methodology.

Requirements themselves can be written in a positive and negative form. That is, requirements usually dictate what the software must do. However some requirements also define the desired system behavior by describing also what the system shall not do.

A way to perform fuzzing is to start with a test case. Then you can modify the test data and rerun the test. The more general realm of testing is robustness testing. This is where you test how the system behaves when there are invalid inputs. One such form of robustness testing is fuzzing. The main purpose of fuzzing is to identify security problems in the system.

When I was with some of our team’s testers, I heard them talking about their negative testing. I did not drop the “fuzzing” buzzword with them. However it was good to see that they are addressing modern topics in the test world.

Changing Test Data

Our customer reported a bug in production. There were many theories as to why this problem was happening. I told people that these were all interesting theories. But these theories, like any opinions, were really not worth much. When I got some time, I dug into the problem. I traced the problem back to the line of code that caused the problem. In the end I determined some configuration data was missing. That resulted in the good code causing a bad transaction. I unit tested my fix by hacking together some data to meet the specific scenario where the error occurs.

Then the fix went to our internal test team. A tester called me up and asked me about the problem. I explained the problem from top to bottom. You would think that would be sufficient for a tester to run with the fix and test it out. However I got back a question that I seem to get a lot from our internal test team. How do I test that? In essence they wanted to know how you set up the data conditions that result in replication of the error.

Now I am sympathetic somewhat to the testers. They do not have the source code in front of them. The documentation for our system is merely average. So it might be unreasonable to assume they had all the tools they needed to figure things out. Therefore I outlined a set of steps that could be taken to replicate this problem.

Development had previously produced a tool which generated input files for our loads component. You could use the tool to generate input files which contain the data the make the problem happen. I recommended that the testers generate up the input files with the tool, run them through the loads program, and duplicate the problem.

I guess this was too much work. The testers tried to simulate all that work by taking data previously mocked and loaded, and performing updates on that data. This is not a bad decision. But you have to know what you are doing. Unfortunately they were unable to replicate the problem. My boss told me to get in there and help them out to get this fix shipped. Essentially I had to reverse engineer our loading code. Then I kept giving them all the data they needed to change manually in order to duplicate the problem.

This is not a good scene. I have things to do. If you want to add value as a tester, you got to do the hard work. Then you will come out smarter and be able to wing it one day. But not now guys.

Testing is Hard Work

Yesterday the test manager on my project came to visit me. She was planning the tests for some new changes I am working on. She asked me to explain some of the changes as they did not make much sense to her.

I tried to get into the details with her. She took some notes. Then she said she would get some people from her team to dig into it. Today I got a message from her. She said her team could not make heads or tails of the requirements, and asked me to help them.

Well I shot off an informative email on the current state of the application, and what the customer wanted instead. Then I got a response on how they could test that. I gave the test team a little more information. Then I got another response asking how they could set up data to do the tests.

I did not want to just provide them with my own unit test plan. Then they would not be adding any value to the work. In an ideal world, they would be able to figure out how to test according to the documented requirements. Unfortunately the requirements team does not know much more than the testers. So I continued to try to give more ideas until they felt like they had enough to go on. How do we get to that ideal world where there is independent validation of my work?

Application Lifecycle Management

Recently I subscribed to Software Testing and Performance magazine. I just got my first issue. There were 30 pages in the issue. Within these pages, there were 3 large ads for conferences. I started to get suspicious that this magazine might be a front for advertising. Then I found a couple articles with technical content. One of these was the ST and Pedia column.

This particular column boasted that it was “translating the jargon of testing into plain English”. This month’s column focused on describing parts of the ALM. There was one main problem with this. It did not define what ALM stood for. Perhaps every tester knows this acronym by now. I think I will email the many testers I know and see if that is true.

Regardless, I did not know what ALM stood for. That made the whole column a damper. It was not quite clear how the different parts were related. Come on guys. You spell out SOA (Service Oriented Architecture). SOA is more common than ALM. Perhaps this was just an oversight. You should always write for an audience that does not know all the buzz words and acronyms. I will try to take this lesson to heart and spell out acronyms I use myself in my blog.

The whole point of receiving a print magazine like Software Testing and Performance is that I like to read it in places where I do not have a computer in front of me. Once I got to the computer, I was able to head over to Wikipedia for guidance. There I found that ALM stands for Application Lifecycle Management. But at this point, I no longer needed or wanted to read the magazine. I was in Wikipedia for my research.

I don’t know how else to combat this problem. Maybe I should write to the editor of the magazine. It did not look like the author’s of the column in question had listed their email addresses near the column. That is not too good. So far this magazine has shown me it has a lot of advertisements, and seems to be written for a specific audience which know more about testing than me.