Debugging and Testing Python Scripts
The backup script automates file archiving by combining directory management, dynamic filename generation, and shell command execution.
The Backup Workflow
A backup script is easier to debug when you treat it as a sequence of connected stages rather than as one large task. The workflow checks for a main backup directory, creates it when necessary, creates a date-based subdirectory when necessary, builds a filename from the current time and an optional comment, and then executes a zip command. Debugging means tracing these stages and checking the values produced at each one.
Directory Checks First
The script uses os.path.exists before os.mkdir for both directory levels. os.path.exists returns True when the directory exists and False when it does not. Applying not reverses that result, so the creation step runs only when the directory is missing. The same pattern is used first for the main backup directory and then for the date-based subdirectory inside it.
Tracing a missing directory
Determine what the directory-management stage does when the main backup directory is missing but the date-based subdirectory has not yet been checked.
Check the main directory: os.path.exists reports False because the main backup directory is missing.
Reverse the result: The not operator makes the creation condition True.
Create the main directory: os.mkdir creates the main backup directory.
Continue to the date directory: The script then checks whether the date-based subdirectory exists inside the main directory.
The workflow creates the missing parent directory before it proceeds to the date-based directory.
Building the Backup Name
The date and time serve different organizational purposes. The date is used to create the subdirectory, while the time and optional comment are used to form the archive filename. time.strftime formats these values without separators: %Y%m%d produces a year-month-day sequence, and %H%M%S produces an hour-minute-second sequence. os.sep supplies the path separator for the current operating system.
The comment follows a conditional path. The len function checks whether the comment contains any characters. If its length is zero, the filename contains the time and the .zip extension. If the length is not zero, the script replaces spaces in the comment with underscores before appending it to the filename. Replacing spaces is the sanitization step described in the workflow.
Two comment inputs
Compare the filename logic for an empty comment and for a comment containing spaces.
Empty comment: len reports zero, so the filename uses the time and the .zip extension without a comment.
Comment with spaces: len reports a nonzero value, so the script replaces every space with an underscore and appends the sanitized comment.
Check the result: The resulting filename should match the selected branch and should not retain spaces from the comment.
The conditional logic produces one filename pattern for an empty comment and another for a nonempty, sanitized comment.
Following Execution
A useful trace records the key state after each stage: whether the main directory exists, whether the date-based subdirectory exists, what date and time strings were produced, what comment was entered, what sanitized comment was produced, and what command was assembled. The script's print statements expose directory creation and the zip command, allowing you to compare the intended workflow with the actual values.
Fixing Broken Execution
When a multi-step script stops before showing its directory or command output, first determine whether execution reached those print statements. A syntax problem prevents the intended workflow from continuing, so inspect the script's structure before investigating directory contents or shell results. After correcting the malformed part, trace the workflow again from the beginning and verify each stage with the available print statements.
Creating a directory without checking whether it exists.
Repeated runs can fail when creation is attempted for an existing directory.
Fix:
Use os.path.exists and create the directory only when the existence check indicates that it is missing.Treating an empty comment as though it were a nonempty comment.
The empty-comment case is supposed to use only the time and the .zip extension.
Fix:
Use len to distinguish a zero-length comment from a nonempty comment.Appending a comment without replacing spaces.
Spaces in filenames can cause problems in many contexts.
Fix:
Replace spaces with underscores before appending the comment.Running the shell command without checking its result.
The returned status code indicates whether execution succeeded or failed.
Fix:
Check the status code after execution; zero indicates success and any other value indicates failure.
Testing Input Variations
Testing should vary the input and compare the observed output with the expected directory and filename behavior. Start with an empty comment, then use a comment containing spaces, and then test a comment containing special characters. For each run, inspect the printed directory information, the generated filename, and the assembled zip command. If the result differs from the expectation, use the trace to locate the stage where the value changed incorrectly.
Create a test checklist for the backup workflow. For each input, record whether the main directory already exists, whether the date-based subdirectory already exists, what the comment length indicates, what sanitized comment should be produced, and whether the final status code indicates success.
Hints
- Include an empty comment.
- Include a comment with at least one space.
- Include a comment with special characters, as suggested by the testing guidance.
- Check the printed command rather than assuming the filename was assembled correctly.
Key Debugging Principles
- Check each directory with os.path.exists before using os.mkdir, for both the main directory and the date-based subdirectory.
- Use the date to organize the backup subdirectory and the time plus optional comment to form the archive filename.
- Use len to separate the empty-comment case from the nonempty-comment case.
- Sanitize comments by replacing spaces with underscores before adding them to filenames.
- Print important values and inspect the os.system status code so that execution can be traced and backup success can be checked.
Key Takeaways
- A reliable backup workflow checks and creates directories before constructing the archive command.
- The date-based directory and time-based filename organize backups while allowing dynamic names.
- Conditional logic handles empty comments separately from comments that require space replacement.
- Print statements and status-code checks make it possible to trace execution and identify failures.
- Testing multiple comment inputs and repeated runs exposes directory, naming, and command-construction bugs.