Programming lesson
Mastering Category-Partition Testing for Java CLI Apps: edittxt Deliverable 1 Guide
Learn how to apply category-partition testing to the edittxt Java CLI project, covering test frames, TSL files, and constraints for CS6300 Deliverable 1.
Introduction to Category-Partition Testing for edittxt
In the CS6300 individual project, you're building a Java command-line utility called edittxt that performs text transformations. For Deliverable 1, you need to generate 50–90 test frames using the category-partition method. This guide walks you through creating a robust TSL file, using constraints and properties, and avoiding common pitfalls—all while keeping your tests within the required range. Whether you're a seasoned tester or new to automated test generation, this tutorial will help you ace the assignment.
Understanding the edittxt Domain
edittxt is a file-based text processor. It accepts options like -i (ignore case), -k substring (keep lines containing substring), -s suffix (sort by suffix), -p ch num (print lines at position), -d factor (duplicate lines), and -r target (remove lines). The last argument is always the filename. Your test frames must cover valid and invalid inputs, option combinations, and edge cases.
Why Category-Partition?
Category-partition testing helps you systematically cover input space without manually listing every combination. You define categories (e.g., file existence, number of options) and choices (e.g., file exists, file missing). The TSLCompiler then generates test frames. This is especially useful for CLI tools where many options interact.
Step-by-Step: Building Your TSL File
Let's create a TSL file for edittxt. Start with the basic categories: File, Options, and Option Arguments. Use constraints to avoid invalid combos.
1. Define Categories and Choices
For the file category, choices: file exists, file missing, file empty. For options, each option can be present or absent. But to keep frames manageable, group options by behavior: OptionGroup with choices: no options, single option, multiple options. Then add subcategories for each option's argument.
Category: File
Choice: exists
Choice: missing
Choice: empty
Category: OptionGroup
Choice: none
Choice: single
Choice: multiple
Category: OptionType
Choice: -i
Choice: -k
Choice: -s
Choice: -p
Choice: -d
Choice: -r
2. Add Properties and Constraints
Use error and single properties. For example, file missing should be an error case. Use if to link option type to its arguments. For -k, you need a substring; for -p, a character and number. Use single to ensure only one option type per frame when multiple options are chosen.
Property: error [file missing]
If OptionGroup == single
Then OptionType single
If OptionGroup == multiple
Then OptionType single // but actually multiple allowed; use constraints
Better: use a separate category for each option's presence, but that explodes frames. Instead, use a single category OptionsPresent with choices like just -i, -k and -s, etc., but that's manual combination. The correct approach: use if and single to let the tool combine.
3. Use Selector Expressions
For -k substring, valid substrings: exists in file, does not exist, empty string. Use if to only include when -k is present.
Category: Substring
Choice: present_in_file
Choice: not_present
Choice: empty
If OptionType == -k
Avoiding Common Mistakes
Many students manually combine choices (e.g., adding a choice add and multiply in one category). Instead, let the tool generate combos using constraints. Also, keep the number of frames between 50 and 90. Use properties to mark error cases (like missing file) so they appear but don't count toward the lower bound? Actually, all frames count. If you have too many, add constraints to reduce. If too few, add more categories like LineCount (1 line, multiple lines) or SpecialCharacters.
Example TSL Snippet
Category: File
Choice: exists
Choice: missing error
Choice: empty
Category: OptionCombination
Choice: none
Choice: single single
Choice: multiple
Category: OptionType
Choice: -i
Choice: -k
Choice: -s
Choice: -p
Choice: -d
Choice: -r
If OptionCombination == single
Category: Substring
Choice: present
Choice: absent
Choice: empty
If OptionType == -k
Category: SuffixLength
Choice: valid
Choice: zero
If OptionType == -s
Then run TSLCompiler to get frames. Each frame becomes a test case in JUnit.
Trend Connection: Testing Like a Pro
Think of this like testing a new AI chatbot feature: you need to cover diverse inputs, edge cases, and error handling. Just as developers test prompt variations and system limits, you're ensuring edittxt handles all valid and invalid arguments gracefully. This skill is in high demand as apps become more complex.
Implementing Test Cases in JUnit
Once you have test frames, convert them to JUnit tests. Use the provided MainTest skeleton. For each frame, call Main.main(args) with appropriate args and assert on stdout/stderr. For error cases, expect usage message on stderr. For valid cases, check transformed output.
@Test
public void testFileMissing() {
String[] args = {"missing.txt"};
ByteArrayOutputStream err = new ByteArrayOutputStream();
System.setErr(new PrintStream(err));
Main.main(args);
assertTrue(err.toString().contains("Usage"));
}
Final Tips for Deliverable 1
- Use the TSLCompiler on Linux (same as Gradescope).
- Include at least 50 frames; aim for 70-80 to be safe.
- Review the provided
cp-example.txtfor format reference. - Post on Ed Discussion if you hit tool issues.
By mastering category-partition testing, you'll not only ace this deliverable but also build a skill essential for software quality assurance. Good luck!