A central goal of software testing is to find issues, especially critical ones, before they cause a problem in production. For example, it’s usual for software to have been designed with a specific use in mind, but the user doesn’t always understand the same way as the developers and testers. As a result, when used other than intended, the software can cause a crash, bringing business to a halt. This article discusses one measure to prevent these kinds of errors, known as destructive testing.
What is Destructive Testing?
As a tester, you have probably been in a situation where an issue is reported because a user did something unexpected. Your thoughts may have been: “Why would someone ever do that?” “What were they thinking?” or “Isn’t it obvious what you’re supposed to put in that field?”. Destructive testing is a method that uses the system in a way other than intended to make the software program deliberately fail. How the system responds is then analyzed.
Imagine you want to test an image upload feature, and the requirements include: .jpeg only, 10 MB maximum. As a tester, you will check .jpeg images at 3 MB, 8 MB, 10 MB, and 10.1 MB. Next, you test for .bmp and .png file types to make sure they are not accepted. Now, you picture yourself as a user and attempt to upload a word doc, .csv, .pdf, and .txt. Can the user drag and drop the file? Can you enter the text as the file without uploading anything? If one of these tests gives an error, does it also crash the site? This is just one small example, but it is easy to imagine a user doing any of these actions.
Tools for Testing
It may be challenging to anticipate erroneous actions of users, but luckily, several tools are available to help in destructive testing. Some of the tools are data-driven and allow the tester to perform actions as a user who is uninformed about the internal workings of the software program. Other tools are automated that let the tester fuzz test the system using fault injection techniques.
- Personas – Many Agile teams use personas, which are fictional characters that can help give an idea of how the customer would be using the software. For example, take a website that sells coffee. One persona might be Hazelnut Harry, a college student who orders from his phone or mobile device. He only buys flavored coffee, always takes advantage of a promo code, and only buys coffees that make individual cups. Another persona could be Medium roast Melody. She’s a business owner who uses a company credit card or purchase order, needs a variety of flavors and roasts, is interested in subscription services, and wants to buy in bulk. This type of data can be very beneficial to testers because it gives insight into multiple ways the system can be used. It’s often the Marketing or Design team who provide personas.
- Market Testing Feedback – Unlike personas, market data is drawn from actual users. It is collected through analytics, A/B testing, beta testing, user acceptance testing, or a more formal market test using volunteers. The data can provide useful feedback about any fields or actions that may have been unclear to the user, leading them to perform an erroneous action. Different teams provide this data, depending on who conducted the research.
Automated destructive testing can be done by fuzz testing or fuzzing, a form of fault injection. Random data, known as ‘fuzz,’ is entered into the system to find vulnerabilities.
- API Fuzzer – This is a free tool that does not require any coding skills. By simply providing API information into either Swagger or OpenAPI, the tool will work step by step to fuzz each field. Once completed, the data is analyzed, and a report is generated.
- Code Intelligence – This is a tool from Code Intelligence that integrates fuzzing into your build system. It has an attractive GUI with easy-to-read statistics of your system’s performance. It is an excellent addition to build verification tests.
- American Fuzzy Lop – This is a free tool that uses a complex algorithm for fuzzing. However, the algorithm is the only complex part as the tool is easy to install and has few configurations.
Methods of Use
- Use Case Testing – Testers can use personas and perform use case testing by envisioning how each character would use the application. For example, consider our coffee website from earlier. Would someone with limited technical knowledge know how to easily checkout? Would they know how to check out as a guest? If the user was technologically proficient, would they get frustrated with the complicated cart-editing process? What if the user has a store gift card, but it can only cover part of the balance; would they know how to checkout? By using personas, the tester can attempt to use invalid data or perform actions that the software doesn’t intend and then verify the software’s response.
- Exploratory session – Destructive testing can be performed during an exploratory session. The tester can perform functions as intended, then purposely execute them incorrectly to create an error. Test results are then compared to determine if any permissible functions need to be prohibited.
- Robustness testing – Robustness testing involves analyzing how ‘robust’ a system is, meaning how the system responds to errors and erroneous input. Is it strong (robust) or fragile and crashes quickly? Robustness testing can include fuzz testing, which is an automated way of entering invalid data.
- Load Testing – Overloading a system until it crashes is another way to perform destructive testing, which can be done using performance testing tools. Continue increasing the number of threads until you start seeing errors or continue until the site crashes.
- SQL Injection – SQL injection is a technique often used in web hacking, where a malicious SQL statement is entered into a data field, allowing a rogue code to run on your database. This method is something usually tested by a security team because of its intentional misuse of a system. It’s mentioned here as a means of crashing or breaking a system.
It’s also important to note that some methods can permanently disable a system. Therefore, testers should make sure they understand the complexity of the test and any potential consequences of destructive testing. SQL injection has the power to change data, so ideally, the tester would ensure database backups have been performed and rollback measures have been planned. Load testing can take all network resources, so the tester could inquire about a devoted network. Fuzzing can put a strain on a CPU, causing it to overheat or consume all available memory. A tester should make sure their environment and its resources meet the needs of the test. These tests could also set off alerts in other departments, who, if uninformed, may believe the threat is viable. The best practice is to communicate with other teams and departments, so they know when you are performing this type of testing.
Destructive testing can be valuable when issues are found and then resolved before reaching production. Testing can be challenging if you lack information about the user. Some tools can help the tester to identify with the user. However, these are often provided by another department and may not be readily available. Destructive testing can break a system, so it should be performed in a controlled test environment. Analyzing the results can help improve the system’s performance when the issues are addressed by developers.