PP Lect09 Testing
PP Lect09 Testing
Introduction
• Critically reviewing and testing a procedural programming solution
involves examining its logic, efficiency, readability, and correctness.
Here’s a step-by-step guide:
1. Understand the Problem Statement:
• Clarify Requirements: Ensure that the solution addresses the problem
it is meant to solve. A clear understanding of the problem statement
is essential.
• Input/Output Expectations: Verify what inputs the program is
expected to handle and what outputs it should produce.
2) Examine the Code Structure:
• Modularity: Check if the solution is broken down into functions or
procedures, making the code more manageable and reusable.
• Code Flow: Review the flow of control structures (loops,
conditionals). Ensure that the logic is clear and follows a logical
sequence.
• Variables: Evaluate variable naming conventions, ensuring they are
descriptive and consistent.
3. Evaluate Algorithm Efficiency:
• Time Complexity: Assess the efficiency of the algorithm in terms of
time complexity. Are there loops within loops that could be
optimized?
• Space Complexity: Consider the space usage. Is the program using
more memory than necessary?
• Optimization: Look for opportunities to simplify or optimize the code
without losing clarity.
4. Test the Solution:
• Test Cases:
• Normal Cases: Test the solution with typical input values to see if it produces
the correct output.
• Edge Cases: Test with boundary conditions (e.g., maximum/minimum input
values).
• Error Cases: Check how the solution handles invalid inputs, such as null
values, non-numeric input, or out-of-range values.
• Performance Testing: If applicable, test the solution with large
datasets or in performance-intensive situations to assess its
scalability.
5. Check for Readability and Maintenance:
• Code Comments: Ensure that the code is well-documented with
comments explaining non-trivial parts of the code.
• Consistency: Review the consistency in indentation, spacing, and
style. Consistent coding style enhances readability.
• Code Duplication: Look for repetitive code that could be refactored
into a function or procedure.
6. Error Handling:
• Robustness: Check if the solution includes proper error handling
mechanisms.
• Input Validation: Ensure the program validates inputs before
processing them.
• Exceptions: Verify if exceptions are handled appropriately, preventing
the program from crashing unexpectedly.
7. Consider Extensibility:
• Future Modifications: Evaluate how easy it would be to extend or modify the
solution. Is the code modular and flexible enough to accommodate changes?
• Scalability: Determine if the solution can scale as the problem size increases.
• 8. Review Output:
• Correctness: Verify that the output of the program is correct for all tested
inputs.
• Format: Ensure that the output format matches the problem requirements.
Example: Testing a Procedural
Solution
• Let's say we have a simple procedural program that calculates the
factorial of a number:
• def factorial(n):
• result = 1
• for i in range(2, n + 1):
• result *= i
• return result
• Testing the Solution:
• Normal Case: factorial(5) should return 120.
• Edge Case: factorial(0) should return 1 (by definition of 0! = 1).
• Error Case: Test with negative input, e.g., factorial(-5).
• Should the function raise an error or return an invalid response?
• Critical Review:
• Efficiency: The time complexity is O(n), which is optimal for this
problem.
• Modularity: The function is modular and can be reused easily.
• Input Validation: The current solution does not handle invalid inputs
like negative numbers. Adding a check for n < 0 could enhance
robustness.
• Readability: The function is concise and readable, with clear variable
naming.
• Conclusion
• After completing these steps, you’ll have a thorough understanding of
the strengths and weaknesses of the procedural solution. You can
then provide recommendations for improvement or confirm that the
solution meets the required standards. If you have a specific
procedural solution in mind, feel free to share it, and I can help you
critically review and test it further.
• To critically review and prepare a test document for the factorial
function provided earlier, we will proceed with the following steps:
• 1. Understanding the Problem StatementProblem:The function
calculates the factorial of a non-negative integer n. The factorial of a
number n (denoted as n!) is the product of all positive integers less
than or equal to n.
• Input:A non-negative integer n.
• Output:The factorial of n.
• Constraints:The input n should be a non-negative integer.
• Factorial of 0 is 1 (by definition).
2. Code Structure and Review
• def factorial(n):
• result = 1
• for i in range(2, n + 1):
• result *= i
• return result
• Review of Code Structure:
• Modularity: The function is modular and reusable.
• Flow: The logic of the loop is clear and follows a straightforward
approach.
• Variables: The variable result is appropriately named, though an
additional comment could clarify its role as an accumulator.
• Suggestions for Improvement:
• Input Validation: The function does not handle invalid inputs (e.g.,
negative numbers, non-integers). Adding input validation would
improve robustness.
• Edge Cases: Currently, the function handles the edge case for 0
correctly, but it does not handle invalid input gracefully.
3. Test Cases
We will define a series of test cases, including normal, edge, and error cases.
Factorial of 1 1 1 1! = 1
3.2 Edge Cases
Factorial of 0 0 1 0! is defined as 1