Due Wednesday, July 3 at 11:59pm.
Submit by pushing your code to GitLab, as described in the final part of the project. If you intend to submit late, fill out this late submission form when you submit.
You will be writing tests in the following file:
src/test/java/junitpractice/TestBuggyDeleteElement.java
You can run your tests using the following file:
src/test/java/junitpractice/CheckTestsDetectBuggyImplementation.java
Additionally, it might be helpful to examine the following files, which may help you during test writing:
src/main/java/junitpractice/BuggyIntList.java
src/test/java/datastructures/TestLinkedIntListProblems.java
(example tests that you can follow)In CSE 143, we learned about the difference between an implementor and a client/user of a class. It turns out that as an implementor, one of the best ways of making sure your code behaves correctly is by pretending that you are a client and coming up with different scenarios of using your class. This is the basic idea behind unit testing, in which one basically aggressively tests against particular units (e.g. class methods) using different cases.
For this part, we are asking you to work with a BuggyIntList
class and to write
test cases for one unit: the method deleteElement(...)
. The BuggyIntList
class behaves exactly like the LinkedIntList
class, just with the extra
buggy method that you are testing. A description of what this method is expected to do
and what exceptions it might throw can be found in BuggyIntList.java
where it is implemented.
We have a fairly comprehensive JUnit Guide that provides a good starting point for you to learn about its syntax. Although for this part, you are primarily graded on whether if you can reasonably complete the tests that we have explicitly asked you to write, it is also good to start thinking about the different cases that a good test suite should cover.
Task: Implement testDeleteFromMiddle
and testDeleteFromFront
In these two tests we ask you to cover two cases: a middle case and a front case. For these kinds of tests, you usually have to initialize a list yourself with some sample data. You can see if the method behaves correctly by calling the method on your list, and later examining the list again to see if it is in an expected state (i.e. if its contents are what the user would reasonably expect after using the method).
Don't worry if you can't get testDeleteFromFront
to pass - the implementation that we
gave you doesn't handle certain cases correctly, so the test you write should actually fail if you run it directly. Instead of running it directly, you should run your tests using the instructions
in Part d.b later.
Hint: get(..)
and toString()
are two methods that allow you to
check the contents of the list.
Hint: you'll likely want to use assertThat
and is
to check the state is what you expect.
If so, make sure these methods are imported at the top as
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.CoreMatchers.is;
Reminder: see the JUnit Guide's examples to see these in context.Task: Implement testThrowsIllegalArgumentException
In the method comments for deleteElement(..)
, the implementation tells you that an
IllegalArgumentException
will be thrown if the given element is not
found in the list.
You should write a test to make sure that the exception is indeed correctly thrown
when the prescribed conditions are (not) met. The JUnit Guide has a section on testing exceptions that
might be helpful for this task.
As it stands, our buggy implementation actually does not throw the correct exception, and so this test that you will write is also expected to fail.
Hint: you'll likely want to use assertThrows
to check the correct exception is thrown.
If so, make sure that it's imported at the top as
import static org.junit.jupiter.api.Assertions.assertThrows;
It might be a little weird to see your tests fail, even if you know for sure that your tests are expecting the correct results. As you can tell, since the implementation that we provided is intentionally buggy, it is expected that not all the tests you write will pass as expected.
Instead, when running your tests, you should use the CheckTestsDetectBuggyImplementation
class, which lives
in the same directory as your tests. This class actually uses all the tests that you wrote earlier, but it
explicitly tells JUnit for which tests that we expect you to throw an AssertionError
. This
way your tests will be marked ✔ PASSED if they are expected to fail.