Software testing is a crucial phase of a software development life cycle that helps evaluate whether the application meets the expected requirements. A common approach is examining the software’s behavior and artifacts through component verification and validation. As an interdisciplinary application development field, testing relies on manual and automated tools to evaluate and document the risks associated with software implementation.
While there are various approaches to product-based testing, two such techniques include destructive and non-destructive testing, which follow contrarian methods to test for flaws and vulnerabilities. Destructive testing causes a component of the application to fail uncontrollably, allowing security experts to gauge the software’s robustness and identify the points of failure. The non-destructive testing technique, also known as positive or happy path testing, involves engaging with the application per the intended workflow and producing the desired output to ensure the software works as expected.
In this article, we discuss how destructive and non-destructive testing approaches work in application development and how they differ from each other.
What is Destructive Testing in Application Development?
Destructive testing is a discipline of systems engineering that checks the functionality of an application by trying to fail its application code. Destructive testing examines unpredictable user behavior within the software, which further helps uncover failure points that average usability doesn’t encounter. This involves special inspections carried out under stressful conditions until the software fails.
A destructive testing process involves introducing known flaws to the software and observing the error detection rate. The testing can be performed without knowledge of the original software requirements and usually goes through the following steps:
- The Client sends a copy of the application and user requirements to the initial testing team
- Testing team analyzes and provides the application’s minimum requirements to the security and quality analyst
- Security analyst establishes the application’s function boundaries and develops the software’s usability limits.
- Security testers then test the application within established boundaries and record the test workflows, errors and exceptions.
- The testing team also shares the defect directory with the client/development team.
- The testing cycle is repeated as the client requires or as defined in business requirements.
Strategies for Destructive Software Testing
Some methods of performing destructive application testing include:
Failure point analysis
This involves a method of inspection using a review and examination of every processing path to determine what can fail at different points of the application configuration. Failure point analysis involves all three stages, including initial service testing, the identification of failure modes, and flaws’ effects to identify the application code sections that require change.
The application is checked by a fellow developer/tester unfamiliar with the product features. This form of software testing helps developers uncover defects that are not visible to them while building the application code.
A type of testing where test cases are established on the fly to discover, investigate and remediate software flaws. Exploratory testing emphasizes learning and adaptability while following a session-based test management cycle. The testing mechanism is considered perfect as an initial service testing technique for a team with experienced testers.
Testing with invalid inputs
A security tester supplies the software with improper data in this testing technique, such as malformed inputs and wrong processes. As part of the analysis, testers analyze if the invalid test data is rejected and handled appropriately by the software.
Types and Examples of Destructive Testing
Quality analysts can perform destructive testing through several techniques, including:
Regression tests are typically performed to assess if recent updates, bug fixes, or the introduction of new features do not break the application.
The code snippet below shows a regression test system for a Python program. The test runs a CLI program with a set of input files and then compares the output of each test iteration with the results of a previous test:
import os, sys
from stat import ST_SIZE
from glob import glob
from os.path import exists
from time import time, ctime
print ‘RegTest start.’
print ‘user:’, os.environ[‘USER’]
print ‘path:’, os.getcwd( )
print ‘time:’, ctime(time( )), ‘\n’
program = sys.argv
testdir = sys.argv
for test in glob(testdir + ‘/*.in’):
if not exists(‘%s.out’ % test)
os.system(‘%s < %s > %s.out 2>&1’ % (program, test, test))
print ‘GENERATED:’, test
os.rename(test + ‘.out’, test + ‘.out.bkp’)
os.system(‘%s < %s > %s.out 2>&1’ % (program, test, test))
os.system(‘diff %s.out %s.out.bkp > %s.diffs’ % ((test,)*3) )
if os.stat(test + ‘.diffs’)[ST_SIZE] == 0:
print ‘PASSED:’, test
os.remove(test + ‘.diffs’)
print ‘FAILED:’, test, ‘(see %s.diffs)’ % test
print ‘RegTest done:’, ctime(time( ))
Assuming we had an executable script called darwin in a directory named test-folder1, the typical test run would look similar to:
|% regtest.py darwin test-folder1|
time: Mon Feb 26 21:13:20 1996
FAILED: test1/t1.in (see test1/t1.in.diffs)
FAILED: test1/t3.in (see test1/t3.in.diffs)
RegTest done: Wed Aug 24 08:13:27 2022
Here, darwin is run thrice (test1/t1.in, test2/t2.in, and test3/t3.in), and the result for each input file is compared to the results obtained for the same inputs in a previous test.
Boundary value testing
Boundary values denote the upper and lower limit of a variable. Boundary value testing helps analyze whether the software generates the correct output depending on the input value supplied.
Assume a web application requires a password whose length is between 8 and 15 characters long. In such a case, the valid test cases can contain passwords with lengths of 8,9,10,11,12,13,14, and 15 characters. While all other password lengths will be marked invalid, the invalid test cases can be closer to the boundaries to test the application logic, such as 16-24 character and 0-7 character passwords.
The code snippet for a Python program (passValue.py) to test whether the supplied password is within the accepted values would look similar to:
|userPass=input(“Enter your Password: “)|
print(“Password too long”)
print(“Password too short”)
The program accepts a password string and stores it as userPass. The code then checks the length of the supplied password and saves it as passValue. Following this, the program compares the size of the password with the upper limit (maxValue) and the lower limit (minValue). As part of a destructive testing mechanism, the test involves supplying the application with passwords whose length is outside the specified boundaries. In a usual scenario, the program should prevent the user from entering a longer password by printing a warning as soon as they try logging in before they press enter.
What is Non-destructive Testing in Application Development?
Contrary to destructive testing, the non-destructive testing technique involves interacting with the software using expected actions on the application. These tests allow security analysts to assess the software without damaging the application’s functionality. As such, the primary purpose of non-destructive testing is to verify if the system behaves as intended on receiving valid data inputs.
Non-destructive Testing – When to Use
A non-destructive testing technique is primarily used with the intended flow of an application and forms the basis of initial testing to verify if the software meets business requirements. Test results of non-destructive testing help to identify flaws in functionality but not design while verifying if the software works fine when testers engage with the program appropriately.
Non-destructive testing uses precise values and test cases to follow the expected application flows and produce results. This test is recommended to be carried out at the onset of an SDLC to verify that only one happy path exists while eliminating all alternative scenarios that can produce a valid result.
A non-destructive testing approach offers cost savings, efficiency, accuracy, and application security since it allows the software to survive the test unharmed. The testing mechanism can also be performed on all software components since it does not impact the design or functionality.
Destructive vs. Non-destructive Testing – Quick Comparison
The table below compares destructive and non-destructive testing techniques:
|Destructive Testing||Non-destructive testing|
|Tests for defects in design||Inspects flaws in functionality|
|Can be performed without knowledge of business requirements||Verifies application functionality against acceptance criteria and business requirements|
|Designed to break the software by supplying malformed inputs to identify points of weakness||Uses positive paths to engage the application without impacting the source code|
Automated Security Testing with Crashtest Security
Software testing is an interdisciplinary field of software engineering that utilizes multiple techniques to ensure the application is defect-free. Destructive testing involves breaking the application using malformed input or an unexpected user workflow to examine unpredictable behavior. Non-destructive testing, on the other hand, consists in engaging the software with the correct application workflow, allowing professionals to inspect the software without damaging it.
Modern deployments rely on multiple automated testing processes to ensure the detection and mitigation of security flaws. Through a suite of different vulnerability scanners, Crashtest Security helps automate comprehensive testing of an application stack to save time on vulnerability detection and remediation.
To know more about how Crashtest Security can help reduce risk exposure and mitigate critical security vulnerabilities, try a free, 14-day demo today.