HW4: Cypherdelic

Homework 4

Cypherdelic

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.

📄PhraseCypher.java

📄WhiteBoxTests.java

Some of the specifications for the PhraseCypher class are illustrated in the following UML class diagram:

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:

  1. Create a class named HeuristicTests.java that contains JUnit tests based on “rules of thumb” about the inputs for all of the methods in the PhraseCypher class.
  2. Create a class named RandomTests.java that contains JUnit tests based on random inputs for all of the methods in the PhraseCypher class.

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:

  • charOfTest
  • valueOfTest
  • decryptTest
  • encryptTest

(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 String that is missing one letter
  • A String that is identical to ALPHABET
  • A String that is identical to ALPHABET with the characters in reverse
  • A String that is missing the first letter (i.e., the ' ' character)
  • A String that is missing the last letter in lower-case (i.e., the 'z' character)
  • A String that is missing the last letter in upper case (i.e., the 'Z' character)
  • A String that 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 char in ALPHABET
  • The 1st char in ALPHABET
  • The next to last char in ALPHABET
  • The last char in ALPHABET
  • A char not in ALPHABET

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 String that contains all of the letters in ALPHABET
  • A String that is identical to ALPHABET
  • A String that is identical to ALPHABET with the characters in reverse
  • An upper-case String
  • A lower-case String
  • A mixed-case String
  • A short String
  • A long String that contains some letters more than once
  • A String that contains a char that isn’t in ALPHABET
  • A String that contains multiple chars that aren’t in ALPHABET

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):

  1. Your corrected implementation of the PhraseCypher class (with appropriate comments).
  2. Your RandomTests.java and HeuristicTests.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:

CriterionPointsDetails
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.

  1. The assignment does not require that your tests completely cover the code. Why not?
  2. The white-box tests completely covered the code. How could the code still contain defects?
  3. Why are both heuristic tests (based on rules of thumb) and random tests necessary (in addition to white-box tests)?
  4. 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 between Run Configurations for Java applications and JUnit tests?
  5. How does your answer to the previous question make it a little more convenient to use JUnit than the Test class you have used on previous assignments?
  6. JUnit contains assertEquals() methods that are passed two int values, two double values, two String values, etc. What term is used to describe methods that have the same name but different formal parameters?
  7. 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)