Static and Dynamic Code Analysis: Comprehensive Techniques
Static Analysis
Static Analysis is the analysis of computer software that is performed without actually executing programs. It is used for software fault detection, code-style recommendation, and metrics to determine the complexity of software.
Features:
- Covers all the code.
- Does not depend on the compiler.
- Can find errors years after deployment.
- Can identify problems with copy-paste of code.
Metrics:
The analysis can be performed at different levels:
- Functions.
- Files.
- Project level.
Each company should decide its own metrics and values to accept a project and pass it to testing.
- Clarity: Effort to understand the code.
- Maintainability: Effort to maintain the code.
- Testability: Effort needed to obtain concrete coverage.
Complexity Metrics:
Indicates the complexity level of a function. A higher level means it is more probable to have problems during execution and also harder to understand.
Structure Metrics:
Verify that the code has a good structure.
Volume Metrics:
Indicates the number of statements, lines, etc., of a function. This impacts understanding. A high volume is more difficult to understand.
Dynamic Analysis
Dynamic Analysis is the execution of code to find errors. A good test case is one that has a high probability of finding a previously unknown error. A test is successful if it finds a new error. Testing shows the presence of defects, but cannot prove that there are no defects. If no defects are found, it is not proof of correctness. It is good to start testing early in software development and testing should be focused on defined objectives. It is better to use risks and priorities to test instead of testing everything.
Unit Tests
Isolate the smallest piece of code and check that it does exactly what you expect. Each unit is tested separately before integrating them into modules to test the interface.
Integration Tests
Take some modules and test them together.
System Tests
Complete and integrated software is tested.
Acceptance Tests
A testing technique performed to determine if the software system has met the requirement specifications.
Regression Tests
The process of testing changes to computer programs to make sure that the older programming still works with the new changes.
Unit Testing
Black-Box Testing
Treats the software under test as a black box without knowing its internals. The tester is aware of what the program should do but does not have knowledge of how it does it.
Advantages
- Efficient for large segments of code.
- Code access is not required.
- Separation between the user’s and the developer’s perspective.
Disadvantages
- Limited coverage since only a fraction of test scenarios is performed.
- Inefficient testing due to the tester’s lack of knowledge about software internals.
- Blind coverage since the tester has limited knowledge about the application.
White-Box Testing
Looks inside the software that is being tested and uses that knowledge as part of the testing process. Requires internal knowledge of the system and programming skills.
Advantages
- Efficient in finding errors and problems.
- Required knowledge of the internals of the software under test is beneficial for thorough testing.
- Allows finding hidden errors.
- Programmer introspection.
- Helps optimize the code.
- Due to the required internal knowledge of the software, maximum coverage is obtained.
Disadvantages
- Might not find unimplemented or missing features.
- Requires high-level knowledge of the internals of the software under test.
- Requires code access.
Coverage
Statement Coverage
Every executable statement in the program is invoked at least once during testing.
Decision Coverage
Complete testing of the control construct.
Condition Coverage
Complete testing of the conditions of the project.
Condition/Decision Coverage
Combines the requirements for decision coverage with those for condition coverage.
@Before: Used in a method to execute before testing. It is used to create objects for the test. @Ignore: Used to ignore the method during the test. It is used when there are a lot of methods in the class and the tester only wants to use some of them.@Test(expected = exception.class): Used to test a method that is going to give exception.@RunWith(Parametrized.class): Allows a developer to run the same test over and over again using different values. @RunWith(Suite.class): To bundle a few unit test cases and run them together.VerifyAll(): Verifies all registered mock objects.ReplayAll(): Objects) to replay mode.StrictMock():