HW4: Cypherdelic
9 minute read
Homework 4

🛑 To Know Before You Start
As discussed below, on this assignment you may submit to Gradescope at most ten times. Hence, you should be confident that your code is correct before you submit the first time.Learning Objectives
This homework assignment is designed to help you understand unit testing and debugging. This includes an understanding of black-box/closed-box testing, white-box/open-box testing (and the JUnit framework), test coverage (and the EclEmma/JaCoCo framework), the debugging process, and instrumentation techniques.
Overview
The (fictitious) company Cypherdelic has written a PhraseCypher
class that can be used to encrypt and decrypt messages using a secret
key phrase. They have also written a suite of white box tests that
covers all statements and branches in this class. They have come to
you to do additional testing to debug the PhraseCypher class if
necessary. (Hint: It will be necessary to debug the PhraseCypher
class. In other words, it does contain defects.)
Existing Classes
They have provided you with an implementation of the PhraseCypher
class and a white box test suite (written in Java using the JUnit
framework) that covers all statements and branches in the
PhraseCypher class.
Some of the specifications for the PhraseCypher class are
illustrated in the following UML class diagram:

The remaining specifications are included in the comments for the class.
Your Tasks
You must test and debug the PhraseCypher class that you have been
given. The end result must be a correct version of the PhraseCypher
class with every change you make documented in the
comments. Specifically, you must:
- Create a class named
HeuristicTests.javathat contains JUnit tests based on “rules of thumb” about the inputs for all of the methods in thePhraseCypherclass. - Create a class named
RandomTests.javathat contains JUnit tests based on random inputs for all of the methods in thePhraseCypherclass.⚠️ Note: posted 9/29@12:40PM
The use of the word “random” here is a bit of a misnomer (it was intentional to try to make of use of more colloquial language in an attempt to make it easier to comprehend the spec). The inputs to the methods in thePhraseCypherclass are not random. Rather, you should come up (just arbitrarily see definition1b, and notice the use of “random” in definition1a) with some examples that aren’t already covered by the white-box tests or the heuristic tests. If you are on your way down some kind of rabbit hole that has to do with “randomg number generators or the like, 🛑 stop! Make a u-turn ↪️ 😆.
Both classes must have at least four methods. These methods
must be preceded by the JUnit @Test annotation and must have names
that begin with each of the following:
charOfTestvalueOfTestdecryptTestencryptTest
(They can have suffixes like charOfTest1(),
charOfTest2(), etc. if you would like to have more than four in
total). You should add these methods one at a time, running all of the
tests on your machine each time you do so. Obviously, you should
not submit to Gradescope until you are confident that HeuristicTests.java and
RandomTests.java are correct.
When the actual output of one of your tests does not equal the expected output you should understand the symptom and the trigger condition (i.e., stabilize the fault). Then, localize the fault, correct the fault (documenting the correction in the source code), and verify the correction.
Some Likely Rules of Thumb
There are a variety of rules of thumb that people use when testing code.
The Explicit Value Constructor
The explicit value constructor must be passed a String that contains
all of the letters in ALPHABET. Some obvious parameters to pass
include:
- A
Stringthat is missing one letter - A
Stringthat is identical toALPHABET - A
Stringthat is identical toALPHABETwith the characters in reverse - A
Stringthat is missing the first letter (i.e., the' 'character) - A
Stringthat is missing the last letter in lower-case (i.e., the'z'character) - A
Stringthat is missing the last letter in upper case (i.e., the'Z'character) - A
Stringthat contains no letters
You should be able to think of other rules-of-thumb that might be
likely to uncover defects in a method that is passed a String.
The charOf() Method
The charOf() method is passed an int that is supposed to
correspond to a char in ALPHABET. Some obvious parameters to pass
include:
- 0
- 1
- The length of
ALPHABET - One less than the length of
ALPHABET - A negative number
- A large number
You should be able to think of other rules-of-thumb that might be
likely to uncover defects in a method that is passed an int.
The valueOf() Method
The valueOf() method is passed a char that is in ALPHABET. Some
obvious parameters to pass include:
- The 0th
charinALPHABET - The 1st
charinALPHABET - The next to last
charinALPHABET - The last
charinALPHABET - A
charnot inALPHABET
You should be able to think of other rules-of-thumb that might be
likely to uncover defects in a method that is passed a char.
The encrypt() Method
The encrypt() method is passed a String that contains some or all
of the characters in ALPHABET. Some obvious parameters to pass
include:
- A
Stringthat contains all of the letters inALPHABET - A
Stringthat is identical toALPHABET - A
Stringthat is identical toALPHABETwith the characters in reverse - An upper-case
String - A lower-case
String - A mixed-case
String - A short
String - A long
Stringthat contains some letters more than once - A
Stringthat contains acharthat isn’t inALPHABET - A
Stringthat contains multiplechars that aren’t inALPHABET
You should be able to think of other rules-of-thumb that might be
likely to uncover defects in a method that is passed a String.
The decrypt() Method
The decrypt() method is passed an int[] that contains the indexes
of some or all of the characters in ALPHABET. Some obvious
parameters to pass include:
- An array with 1 element
- A long array
- An array in which all of the elements are the same
- An array sorted in ascending order
- An array sorted in descending order
- An array containing zeroes
You should be able to think of other rules-of-thumb that might be
likely to uncover defects in a method that is passed an int[].
Before Submission
Before you submit your code to Gradescope for the first time you should be able to check-off each of the following items.
☐ PhraseCypher.java has no style defects
☐ The PhraseCypher constructor throws an IllegalArgumentException as specified
☐ The decrypt() method returns the empty String as specified
☐ The encrypt() method returns an array of length 0 as specified
☐ HeuristicTests.java has a charOfTest() method
☐ HeuristicTests.java has a valueOfTest() method
☐ HeuristicTests.java has a decryptTest() method
☐ HeuristicTests.java has an encryptTest() method
☐ RandomTests.java has a charOfTest() method
☐ RandomTests.java has a valueOfTest() method
☐ RandomTests.java has a decryptTest() method
☐ RandomTests.java has an encryptTest() method
Note that if your submission does not include all of the required tests it will fail the Official Tests (not the Self Tests), and you will not receive any hints that indicate this. Hence, it is very important that you manually ensure that your submission is correct.
Submission
You must submit (using Gradescope):
- Your corrected implementation of the
PhraseCypherclass (with appropriate comments). - Your
RandomTests.javaandHeuristicTests.java.
Because you should not be using Gradescope to verify your code (i.e., because you must be able to test and debug code without the help of a submission system), you may submit to Gradescope at most ten times and you will not receive any hints about the official tests from Gradescope.
Note that your test classes do not need to comply with the style guide.
Grading
Your code will first be graded by Gradescope and then by the Professor. The grade you receive from Gradescope is the maximum grade that you can receive on the assignment
Gradescope Grading
Your code must compile (in Gradescope, this will be indicated in the section on “Does your code compile?”) and all class names and method signatures must comply with the specifications (in Gradescope, this will be indicated in the section on “Do your class names, method signatures, etc. comply with the specifications?”) for you to receive any points on this assignment. Gradescope will then grade your submission as follows:
| Criterion | Points | Details |
|---|---|---|
| Conformance to the Style Guide (Style) | 0 points | (All or Nothing; Success Required) |
| Passing Your Tests (SelfTests) | 20 points | (All or Nothing; Success Required) |
| Correctness (Official Tests) | 80 points | (Partial Credit Possible) |
As discussed above, you may submit to Gradescope at most ten times. The grade on your last allowed submission will be the grade you receive from Gradescope.
If your submission does not contain all of the required tests, you will receive a 0 for correctness.
Manual Grading
After the due date, the Professor may manually review your code. At this time, points may be deducted for inelegant code, inappropriate variable names, bad comments, etc.
Questions to Think About
You don’t have to submit your answers to these questions, but you should try to answer them because they will help you determine whether or not you understand some of the important concepts covered in this assignment.
- The assignment does not require that your tests completely cover the code. Why not?
- The white-box tests completely covered the code. How could the code still contain defects?
- Why are both heuristic tests (based on rules of thumb) and random tests necessary (in addition to white-box tests)?
- As you know, applications written in Java must have a main class that contains a method with the signature
public static void main(String[])that is called the entry point of the application. When you write JUnit tests, you do not need to create such a class. What must the JUnit framework be providing behind the scenes? With this in mind, why does Eclipse differentiate betweenRun Configurationsfor Java applications and JUnit tests? - How does your answer to the previous question make it a little more convenient to use JUnit than the
Testclass you have used on previous assignments? - JUnit contains
assertEquals()methods that are passed twointvalues, twodoublevalues, twoStringvalues, etc. What term is used to describe methods that have the same name but different formal parameters? - When a JUnit test fails, an exception is thrown. What happens if the code you are testing throws an exception for other reasons?
Vocabulary
- black-box testing
- Testing that is based on the specification of the code being tested (without insight into the actual implementation).
- white-box testing
- Testing that is based on the implementation of the code being tested, i.e. the test author has access to the source code under test.
- heuristic
- Describing something that is an acceptable approximation, compromising some completeness or perfection for practicality. Often heuristics are informed from (past) empirical observations. ([more on wikipedia](https://en.wikipedia.org/wiki/Heuristic))
- rule of thumb
- Guideline, informed by past experience. Anachronistically associated with jurisdictional tolerance of domestic violence. ([more on wikipedia](https://en.wikipedia.org/wiki/Rule_of_thumb#Folk_etymology))
- random test
- A test with inputs that were chosen at random by the tester (along with the associated expected output)