Skip to main content

Guided Project 3 Introduction

Target Audience: this guided project is geared toward the beginning Java programmer who has some experience with using Eclipse, inheritance, and running test cases.

An important practice for ensuring that software works correctly is to test it and run other verification and validation tools to minimize programmer mistakes. Since no one practice can identify all faults, developers work with a suite of practices and tools to help find problems in their code.

One practice that developers frequently use is test driven development (TDD). In TDD, a developer starts by writing tests, then uses those test to drive forward development of the implementation. By writing system and unit tests before writing the implementation, a developer can better understand the context of the problem and the area of the solution.

Guided Project 3 builds on Guided Project 1 and Guided Project 2 through another iteration of the the phases of the software lifecycle, with an emphasis on using TDD to implement the new features. You will continue to work with software practices and tools that support those practices in Guided Project 3.

WolfScheduler System

You will implement and test the remainder of the WolfScheduler system, with an emphasis on conflict identification and resolution. The WolfScheduler system enables a student to determine which course schedule may be best for them in an upcoming semester.

You will develop the WolfScheduler project over the course of the three guided projects. The WolfScheduler requirements describe the fully implemented system. Guided Project 3 will focus the [Schedule Conflict] alternative flows of Use Cases 4 & 6 around time (with an assumption of no regression in functionality on the already implemented requirements):

As part of earlier Guided Projects, you were provided with a suite of unit and system tests. You will now be adding new tests for the time conflict functionality. You may have to update the provided tests. Some may fail due to the addition of the new time conflict functionality.

Tasks

Task Time Estimate Description
1. Independent Task - Eclipse Monitor Installation10 minutesInstall the Eclipse Monitor plugin
2. Guided Task - Guided Project 3 GitHub Repository10 minutesAdd your project from GP2 to your new GitHub repository for GP3.
3. Independent Task - Write and Update System Test Plan45 minutesUpdate the system test plan to incorporate the conflict functionality for the full WolfScheduler requirements.
4. Guided Task - Create Conflict Interface20 minutesCreate an interface to support the new time conflict checks.
5. Guided Task - Implement and Test ConflictException30 minutesCreate a ConflictException to support your new Conflict interface.
6. Guided Task - Test Driven Development40 minutesPractice test driven development to improve the tests in the WolfScheduler project for the new conflict functionality.
7. Independent Task - Implement Conflict in Activity60 minutesIncorporate the Conflict interface in the Activity hierarchy.
8. Independent Task - Coverage45 minutesRun your coverage tool and create high quality test cases to consider uncovered flows.
9. Independent Task - Update WolfScheduler90 minutesUpdate WolfScheduler to incorporate behavior for the new Conflict functionality.
10. Independent Task - Update WolfSchedulerGUI45 minutesUpdate WolfSchedulerGUI and run the system tests to ensure everything works together.
11. Independent Task - Submit Project30 minutesDouble check your implementation to ensure that you're meeting all expectations.
Total Estimated Time*: 7 hours 5 minutes
* Times are only estimates. It may take you less time or more time depending on how much debugging effort is required for your specific implementation. Use the relative numbers to help guide you: for example, a task labeled as "5 minutes" should not require as much effort as a task labeled "20 minutes", regardless of how much time it takes to actually complete the task.

Eclipse Monitor Installation

You are encouraged to install a plugin developed to assist you during your CSC 216 coursework. The plugin provides a clean way to interface with your test results on Jenkins as you will need to do in this project and other projects in this course. If you have any concerns or questions about the plugin please contact Md Saminur Islam (sislam@ncsu.edu) and John Bacher (jtbacher@ncsu.edu).

In addition to the features provided to you, the plugin does collect interaction data while you use Eclipse. This data is used to help develop and improve the plugin for you and other students in this course. Additionally, that data, like other classroom data, may be used for research insofar as you have consented to participate in research collecting your classroom data. However, being part of research IS NOT required to install the plugin.

In order to install the plugin, and for instructions on how to use it, please navigate to the Installation Instructions Link. If you have trouble during installation there is a form for submitting a request for help in the installation document!

Again if you have further questions please contact Md Saminur Islam (sislam@ncsu.edu) and John Bacher (jtbacher@ncsu.edu).

Guided Task: Guided Project 3 GitHub Repository

You will be assigned a separate GitHub repository for each Guided Project and each major Project. This is to ensure that your work on each is distinct and that any work on a new project doesn’t get recorded as late work on an old project. However, you will continue with the same WolfScheduler project for GP3. You need to share the project to your GP3 repository.

Callout Box Icon

Learning Outcomes

  • Disconnect a project from a GitHub repository
  • Share a project with a new GitHub repository
  • Push changes to a new remote GitHub repository
Callout Box Icon

Best Practice: Version Control

A project can belong to only a single local repository. That is because a Git repository is represented as a folder on a file system with a special .git/ folder that stores Git metadata. A project cannot be in two locations on the file system at once. The process outlined below will let you share an existing Eclipse project with a new repository and then retain a copy of your Guided Project 2 submission in a local copy of your Guided Project 2 repository.

Callout Box Icon

Tools: Git and GitHub

Git is a distributed version control system. Git supports the creation of repositories, copying of repositories (cloning), committing changes, working with remote repositories, and merging changes. In Git, all repositories are considered equal and each maintains its own history. You can move information between connected repositories through pulling and pushing any changes.

Disconnect WolfScheduler from GP2 Repository

Disconnecting a project from a Git repository removes any associated metadata about the project from the repository. To disconnect, do the following:

  • Right click on the WolfScheduler project.
  • Select Team > Disconnect.
  • The repository name to the right of the WolfScheduler project will no longer be available.
Reminder: Working with GitHub

Push WolfScheduler to your GP3 Repository

Complete the following steps to push WolfScheduler to your GP3 repository.

  • Clone your GP3 repository provided by the teaching staff. The pattern will be csc216-XXX-GP3-YYY, where XXX is your section number and YYY is your repository number.
  • Stage your WolfScheduler to your GP3 repository by right clicking on the project and selecting Team > Share Project.
  • In the Configure Git Repository pop-up, uncheck the option Use or create repository in parent folder of project. Then select your new repository from the drop down and check your project.


Figure: Sharing Project with Repository
Figure: Sharing Project with Repository


  • Now that your project is staged for the GP3 repository, add the files to the index by right clicking on the WolfScheduler project and selecting Team > Add to index. Then Commit and Push the project to start GP3! Use a commit message like “[Skeleton] Starting GP3 with GP2 WolfScheduler”.


Figure: Staging Files
Figure: Staging Files


Reset your GP2 WolfScheduler

When you shared WolfScheduler with your new GP3 repo, that removed the WolfScheduler directory from your local GP2 repo. If you want to keep a copy of your GP2 WolfScheduler, you should reset your local GP2 repository to the last commit in the remote. Then your local GP2 repository will have a copy of your final WolfScheduler submission for GP2. You can use that as a backup as you’re working on GP3!

Choose to do the reset in either Eclipse or Git Bash!

In Eclipse, do the following:

  • Right click on your GP2 repository in the Git Repositories view and select Reset.
  • Make sure the last commit is selected and select the option for a Reset type of Hard (HEAD, index, and working tree updated). Click Reset.


Figure: Resetting Files
Figure: Resetting Files


  • You will receive a warning about overwriting your local changes. This is what we want since we want to bring a copy of the project back into our local GP2 repository and erase all of your uncommitted local changes (which in this case is all the deleted WolfScheduler files). Click Reset.


Figure: Reset Warning
Figure: Reset Warning


  • Check that WolfScheduler is now in the Working Tree/ directory of your GP2 repository.


Figure: WolfScheduler is now in GP2 repo
Figure: WolfScheduler is now in GP2 repo


In Git Bash, do the following:

  • Change directory to your repository location.
  • Enter the command git reset --hard HEAD. This will reset the local repository to the same information as the remote and erase all of your uncommitted local changes (which in this case is all the deleted WolfScheduler files).

Caution: Resetting a Repo

In this case, resetting the repo is useful, but the reset command can lead to major problems. Use the power of the reset command carefully!

Reminder: Running Static Analysis Tools

Set Up Static Analysis Tools

Set up your project to automatically run SpotBugs, PMD, and CheckStyle.

Check Your Submission

You should ALWAYS verify that your pushed changes are on the remote repository. You can do this by going to your repository on the GitHub website and making sure that your WolfScheduler project has been pushed to your GP3 repository.

  • Log into NCSU’s GitHub
  • Select the appropriate organization and repository.
  • Verify that your latest commit message is listed and that all pushed files are in the repository.

Verify that your Guided Project 3 Jenkins job is pulling your WolfScheduler from your GP3 repository (this job will start with GP3-. If Jenkins does not recognize your project, please notify the teaching staff via Piazza or the sup list as early as possible to ensure that your project is set up correctly for auto grading.

Caution: Red X on Jenkins is OK (at this point)

At this point, your Jenkins build will be a red X. That is expected because there are several things that we have to do in Guided Project 3 before our code will even compile. The important thing is that the job runs and gives you a red X!

Reference: Staging and Pushing to GitHub

Check Your Progress

  • Make sure that all fields, methods, and constructors are commented.
  • Resolve all static analysis notifications.
  • Fix test failures.
  • Commit and push your code changes with a meaningful commit message. Label your commit with “[Skeleton]” for future you!

Independent Task: Write and Update System Test Plan

Test Driven Development (TDD) means that tests are written before code is written. For system level tests, that means they are written as soon as the requirements are finalized. You will use the WolfScheduler Requirements to write additional test cases for the conflict functionality. Additionally, you will update any test cases that are no longer appropriate once the conflict functionality is added.

Callout Box Icon

Learning Outcomes

  • Write and update system tests

Create GP3 System Test Plan Document

If you don’t already have a project_docs folder in your WolfScheduler project, create it by right clicking on WolfScheduler and selecting New > Folder.

You’ll start with a copy of the Guided Project 2 System Test Plan that has been updated with instructions for Guided Project 3.

  1. Download the document as a Word document by selecting File > Download > Microsoft Word in Google Drive.
  2. Save your system test plan as a Word document (*.doc or *.docx)
  3. Put the system test plan in the WolfScheduler project_docs folder.
  4. Add the system test plan to the index of the repo and commit/push.

Add and Modify Tests

Read the WolfScheduler requirements. Guided Project 3 will focus the [Schedule Conflict] alternative flows of Use Cases 4 & 6 around time. The remaining requirements were implemented in Guided Projects 1 and 2.

With the new time conflict functionality, there are tests in the system test plan that were fine for Guided Project 2, but that no longer meet the requirements. These tests must be revised to meet the full WolfScheduler requirements.

Do the following tasks to update your system test plan:

  • Identify any tests that will fail with the conflict requirement fully implemented. Revise or rewrite the test(s). You MAY NOT remove them! Mark them as “(Modified)” in the Test ID column and highlight the rows in a light gray.
  • Write 5 additional tests that consider different conflict scenarios. Mark them as “(New)” in the Test ID column and highlight the rows in a darker gray.

Additional instructions about the expectations for updating the system test plan for the WolfScheduler project are IN the System Test Plan document. Please follow those instructions (especially highlighting new or modified tests) to help with grading and earning full credit for your work.

Reference: Staging and Pushing to GitHub

Check Your Progress

Complete the following tasks before pushing your work to GitHub.

  • Make sure that all fields, methods, and constructors are commented.
  • Resolve all static analysis notifications.
  • Fix test failures.
  • Double check that your GP3 System Test Plan was pushed to the repo! This is a common mistake.
  • Commit and push your code changes with a meaningful commit message. Label your commit with “[Test]” or “[System Test]” for future you!

Guided Task: Create Conflict Interface

Checking for a schedule conflict is a behavior that is useful for WolfScheduler and other applications. We will practice additive change by incorporating the checked conflict behavior as an interface. For the moment, the Conflict interface will be specific to the Activity hierarchy (i.e., we will be using classes in the Activity hierarchy rather than a generic type). You can update the Conflict interface to handle generic objects later.

Callout Box Icon

Learning Outcomes

  • Create an interface
  • Create a custom exception class

Create an Interface

Create a new Java interface called Conflict in the edu.ncsu.csc216.wolf_scheduler.course package of the WolfScheduler project. To create an interface, do the following:

  • Right click on the edu.ncsu.csc216.wolf_scheduler.course package and select New > Interface.
  • Enter the name Conflict and check the option to generate comments.
  • Click Finish to create the interface.


Figure: Create an interface
Figure: Create an interface


Add a Method

Add the method checkConflict() to the Conflict interface. The method has a void return type and accepts an Activity object as a parameter. The method must throw a ConflictException, which is a custom checked exception that you will define next.

Since checkConflict() is abstract, its header must end in a semicolon rather than an opening curly brace. However, since the method is part of an interface, it is automatically public and abstract, so you can leave out those key words. The method header is:

1
void checkConflict(Activity possibleConflictingActivity) throws ConflictException;

There are several design considerations to think about when deciding how best to set up the method for the Conflict interface. The first involves identifying the best location to handle the check for conflict. There are two choices: 1) handle in the Activity hierarchy by comparing the current instance to a parameter instance, and 2) handle in the list of Activitys. By checking for conflict in the Activity hierarchy rather than in the list, you are following a design similar to the equals() and hashCode() methods from Object and similar to the Comparable interface. An alternative would be to handle in WolfScheduler; however that implementation would likely be clunky since there are two locations where you will need to check for conflict (addCourse() and addEvent()). Since Activity will implement the Conflict interface, the idea of conflict is built into the Activity hierarchy and any other program that might use that hierarchy.

A second design consideration is how to report a conflict to the client. There are two choices: 1) return a boolean specifying if there is conflict or not, and 2) throwing an exception. The first choice would work, but the client could easily ignore the return type and end up with a conflict! The second choice of throwing an exception is a stronger alternative. However, it depends on the type of exception that you throw. If you throw something like an IllegalArgumentException, that can also be ignored or not handled. IllegalArgumentException is an unchecked exception, and the compiler doesn’t provide feedback about handling it. It’s the developer’s responsibility to fully read the documentation to know to check for it to avoid a possible program crash (you did document all the methods that throw IllegalArgumentExceptions, right?). A checked exception requires the the developer do something to handle the exception or the code won’t even compile. You’ll be using a custom checked exception specifically for conflicts: ConflictException. This means that clients of the Conflict interface MUST handle the exceptions in their code!

The design for the full WolfScheduler project, including the Conflict interface and ConflictException is below.


Figure: Full WolfScheduler Class Diagram
Figure: Full WolfScheduler Class Diagram


Reminder: Quick Fix for Class Creation

If you need help creating the ConflictException Java Class using Eclipse Quick Fix, see Guided Task: Eclipse Quick Fix Tool - Quick Fix.

Create ConflictException

Use the Quick Fix tool to create a ConflictException in the edu.ncsu.csc216.wolf_scheduler.course package. Since ConflictException is a checked exception, it should inherit from Exception. You’ll finish implementing ConflictException on the next page.


Figure: Create an exception
Figure: Create an exception


Comment Conflict

Interfaces define behaviors that implementing classes must define. That means the interface must be well commented so that others can use the interface for other classes. Fully Javadoc the interface at both the interface and method levels. Remember to use the @throws tag to describe when the ConflictException is thrown.

Reference: Staging and Pushing to GitHub

Check Your Progress

Complete the following tasks before pushing your work to GitHub.

  • Make sure that all fields, methods, and constructors are commented.
  • Resolve all static analysis notifications.
  • Fix test failures.
  • Commit and push your code changes with a meaningful commit message. Label your commit with “[Implementation]” for future you!

Guided Task: Implement and Test ConflictException

Implementing and test a custom Exception.

Callout Box Icon

Learning Outcomes

  • Implement and test a custom exception class

serialVersionUID Warning

Since the ConflictException class extends Exception, which implements the Serializable interface, the Java compiler will provide a warning about ConflictException lacking a serialVersionUID. An object and its state is serialized when the information about the object, including the current values in the fields, are written to a file in a Java-specific format. Serialized files can then be deserialized or read in as Java objects. Serialization is a way of saving object state when an application is closed. Instead of using serialization, however, you are using specifically formatted files for saving state of our application.

One of the key items in serialization is that each object type requires a unique id so the serializier knows what object to work with when reading and writing Java objects. If you’re not planning to use serialization and you want to get rid of the compiler warning, you can use the default serialVersionUID of 1L (which is the value 1 stored into a long primitive type; a long takes twice the memory of an int). Use the Eclipse Quick Fix tool to create the default serialVersionUID. Make sure you comment the field. We suggest using the comment:

1
2
/** ID used for serialization. */
private static final long serialVersionUID = 1L;

Exception Constructors

Any custom Exception requires the author to create two constructors. The first is a parameterized constructor with a String specifying a message for the Exception object. The message is passed to the parent’s constructor. The second is a parameterless constructor that calls the parameterized constructor with an author specified default message. A custom Exception needs no additional state or behavior.

Write the two constructors for ConflictException. The default message should be "Schedule conflict.".

Creating a Test Class

In Guided Project 1, you created a test class directly in the test/ folder. Eclipse provides additional support for generating JUnit tests. Follow the steps below to create ConflictExceptionTest.

  • Right click on ConflictException in the Package Explorer. Select New > JUnit Test Case.
  • Update the New JUnit Test Case wizard dialog with the following information:
    • New JUnit Jupiter test should be selected
    • Source folder: WolfScheduler/test (circled in red)
    • Check Generate comments
    • Click Next >. (If you click Finish that’s ok. You’ll have to either delete the class and start over or manually create the test methods.)


Figure: Creating a New JUnit Test Case
Figure: Creating a New JUnit Test Case


  • The next page lets you select the test methods that you want to create from the methods in the class under test. For ConflictExceptionTest, you want to test both constructors. Check ConflictException(String) and ConflictException(). Then click Finish.


Figure: Selecting Test Methods
Figure: Selecting Test Methods


Writing Test Methods

When writing unit tests, you first need to think about the goals of the test. Most of ConflictException’s functionality is inherited from Exception. Since that parent class has been extensively tested by the Java API authors, you should focus your attention on what is different and custom about the child class - the new constructors! The tests will use the new constructors and verify that the correct message is available.

Below is the test case for the parameterized constructor:

1
2
3
4
5
@Test
public void testConflictExceptionString() {
    ConflictException ce = new ConflictException("Custom exception message");
    assertEquals("Custom exception message", ce.getMessage());
}

Write the test for the parameterless ConflictException constructor.

Comment ConflictException and ConflictExceptionTest

Javadoc both your ConflictException and the associated ConflictExceptionTest.

Run Your Tests

Run your new ConflictExceptionTest class and ensure the tests pass. You may need to update your ConflictException implementation or the tests until they pass.

Also, continue to run the other unit tests in your suite! Make sure they still pass, ensuring no regression in functionality.

Reference: Staging and Pushing to GitHub

Check Your Progress

Complete the following tasks before pushing your work to GitHub.

  • Make sure that all fields, methods, and constructors are commented.
  • Resolve all static analysis notifications.
  • Fix test failures.
  • Commit and push your code changes with a meaningful commit message. Label your commit with “[Implementation]” and “[Test]” for future you!

Guided Task: Test Driven Development

In this section, you will start creating tests for the implementation of the Conflict interface in Activity.

Callout Box Icon

Learning Outcomes

  • Create a test class
  • Implement a test for an exception
Callout Box Icon

Best Practice: Test Driven Development (TDD)

Test Driven Development (TDD) is the process of using the requirements and object design to write the unit tests for a class first, and then use the tests to drive the implementation of the methods in the class. The process is typically iterative. Start with the simplest test first and implement the functionality to pass. Then add additional tests that consider other paths, edge cases, and error cases. After adding each test, implement the functionality to pass it (if needed).

TDD is a highly effective process for developing code that is well tested. By testing right away and letting the tests drive development, you will implement more high quality code more quickly and not run out of time for testing!

Implement the Conflict Interface in Activity

Since Activity contains the fields related to the meetingDays, startTime, and endTime, you can implement the Conflict.checkConflict() functionality in the Activity class. If the child classes need custom conflict implementation later, they can override the method.

You can use your tests to drive the creation of new methods in your code as in using Quick Fixes for Error-Driven Development. However, this may not be appropriate in all cases - Quick Fix will help you create the checkConflict() method, but will not know that the method is part of implementing the Conflict interface. Instead, you’ll set up the appropriate structure and generate a test class from the structure.

Follow these steps to set up Activity for testing the Conflict functionality:

  • Open Activity in the editor.
  • Update the Activity class header to include implements Conflict. When complete, the header should look like public abstract class Activity implements Conflict {.
  • Because Activity is an abstract class, there are no compiler errors about Activity needing an implementation of Conflict’s method. Instead, Course and Event won’t compile. However, you want Activity to contain the checkConflict() implementation. You can use Eclipse’s source generation tool to implement the method in Activity by right clicking in the editor and selecting Source > Override/Implement Methods. Check the option for Conflict.checkConflict(Activity) and click OK.


Figure: Implementing `Conflict.checkConflict(Activity)
Figure: Implementing `Conflict.checkConflict(Activity)


Now that Activity implements the Conflict.checkConflict() method, the compiler errors in Course and Event are resolved.

Reminder: Creating a JUnit Test Class from a Class Under Test

Create ActivityTest for Testing Conflict Functionality.

Now, create the JUnit class to test the Activity.checkConflict() implementation. Create a new JUnit test for Activity named ActivityTest in the edu.ncsu.csc216.wolf_scheduler.course package of the test/ folder in WolfScheduler. Since you’ve been provided test classes that test the other methods, you should only generate a test method for the checkConflict() method. After generating the test, you can remove the fail() statement since you are about to implement the test.

checkConflict() Overview

The checkConflict() method is an instance method of Activity. That means it compares the current instance (i.e., this) with the parameter possibleConflictingActivity to see if there is any conflict in their days and times. If there is a conflict, the checked ConflictException is thrown. If there is no conflict, nothing happens and the statement in the client code following the call to checkConflict() is executed.

Two Activity objects are in conflict if there is at least one day with an overlapping time. A time is overlapping if the minute is the same. For example, an Activity on Monday from 1:30PM-2:45PM would conflict with an Activity on Monday from 2:45PM-3:30PM because of the overlap on the 2:45 minute. You’ll encode this test shortly.

Start by Javadocing your checkConflict() method to describe how the conflict check works in the context of the Activity hierarchy.

Writing Tests

The following sections will detail the tests that you should write to fully test the checkConflict() method.

Setting Up the Test

Start by creating two two Activity objects to check for conflict. Since Activity is abstract, you cannot directly construct Activity. Instead, you must construct a Course or Event object for the comparison.

An example of two Activitys that do not conflict are:

1
2
Activity a1 = new Course("CSC 216", "Software Development Fundamentals", "001", 3, "sesmith5", "MW", 1330, 1445);
Activity a2 = new Course("CSC 216", "Software Development Fundamentals", "001", 3, "sesmith5", "TH", 1330, 1445);

Next, the checkConflict() method is called on one of the objects. The other is passed as a parameter.

No Conflict Test

If the two activities should NOT lead to a conflict, then a call to Activity.checkConflict() should not throw an exception. We can test this with the assertDoesNotThrow() method from JUnit 5.

The general test structure is:

1
assertDoesNotThrow(() -> activityReference.checkConflict(otherActivityReference));

An example no conflict test would be the following. Note that we’re testing that the conflict check works in both directions.

1
2
3
4
5
6
7
8
@Test
public void testCheckConflict() {
    Activity a1 = new Course("CSC 216", "Software Development Fundamentals", "001", 3, "sesmith5", "MW", 1330, 1445);
    Activity a2 = new Course("CSC 216", "Software Development Fundamentals", "001", 3, "sesmith5", "TH", 1330, 1445);
    
    assertDoesNotThrow(() -> a1.checkConflict(a2));
    assertDoesNotThrow(() -> a2.checkConflict(a1));
}

Run the test. Since you have not yet implemented checkConflict(), the test should pass!!!? For now, that’s ok. We will shortly be implementing the checkConflict() method once we have a failing test to help us with our implementation. However, our happy path test is an important test to ensure that as you implement the rest of checkConflict() that you do not start finding a conflict where there should be no conflict!

Testing an Exception - Conflict Test

The next test type to consider is a test when there is a conflict. In this case, the expected results are that the ConflictException is thrown. The initial test structure is:

1
2
Exception e1 = assertThrows(ConflictException.class, () -> activityReference.checkConflict(otherActivityReference));
assertEquals("Schedule conflict.", e1.getMessage());

We can continue writing tests in the same testCheckConflict() method or we can create a new test method to consider this specific case. By continuing with the previous test method, we can work with the existing local variables a1 and a2 and modify the days or times to lead to a conflict. By writing another test method, we can more clearly identify which functionality is passing or failing. The example below is a separate test method, but you are welcome to continue the implementation in the testCheckConflict() test method.

1
2
3
4
5
6
7
8
9
10
11
@Test
public void testCheckConflictWithConflict() {
    Activity a1 = new Course("CSC 216", "Software Development Fundamentals", "001", 3, "sesmith5", "MW", 1330, 1445);
    Activity a2 = new Course("CSC 216", "Software Development Fundamentals", "001", 3, "sesmith5", "M", 1330, 1445);
	
    Exception e1 = assertThrows(ConflictException.class, () -> a1.checkConflict(a2));
    assertEquals("Schedule conflict.", e1.getMessage());
	
    Exception e2 = assertThrows(ConflictException.class, () -> a2.checkConflict(a1));
    assertEquals("Schedule conflict.", e2.getMessage());
}

Run the test. It fails! But that is exactly what you want. It means you have a test that you can use to start driving the implementation of the checkConflict() functionality in Activity, which you’ll work on in the next step.

Testing Behaviors to Avoid

There are behaviors that you want to avoid when testing. PMD will flag some of these behaviors with notifications (and a PMD notification leads to a loss of a point AND PMD testing notifications will block the teaching staff tests from running on your code!)

Test Class without a Test Method

Every test class should have at least one test method with the @Test annotation.

Test Method with No assert*()

Every test method should have at least one assert*() method call. The goal of a test method is to assert or check something about the code under test to verify the code is working correctly. It’s very tempting to leave out an assert*() method call because your test method will pass (and you may also achieve coverage). But that means you can have no confidence in your code! Always write a test method to assert something about the code under test!

Meaningless assert*() Statements

A meaningless assert*() statement is something like assertTrue(true);, assertFalse(false);, or assertNull(null);. There is ALWAYS something to check about the code under test. At a minimum you can check that the state has not changed or that the type is correct. Avoid meaningless assert statements. If you need help identifying what you should check, contact the teaching staff.

Reference: Staging and Pushing to GitHub

Check Your Progress

Complete the following tasks before pushing your work to GitHub.

  • Make sure that all fields, methods, and constructors are commented.
  • Resolve all static analysis notifications.
  • Fix test failures.
  • Commit and push your code changes with a meaningful commit message. Label your commit with “[Test]” for future you!
  • Check Jenkins results for a yellow ball! At this point, your code should compile against the teaching staff tests.

Independent Task: Implement Conflict in Activity

Use TDD to implement the checkConflict() method in Activity.

Callout Box Icon

Learning Outcomes

  • Use test driven development to implement and test a method.
Callout Box Icon

Best Practice: Test Driven Development (TDD)

Test Driven Development (TDD) is the process of using the requirements and object design to write the unit tests for a class first, and then use the tests to drive the implementation of the methods in the class. The process is typically iterative. Start with the simplest test first and implement the functionality to pass. Then add additional tests that consider other paths, edge cases, and error cases. After adding each test, implement the functionality to pass it (if needed).

TDD is a highly effective process for developing code that is well tested. By testing right away, and letting the tests drive development, you will implement more high quality code more quickly and not run out of time for testing!

Reminder: Resources on Writing Tests

There are several resources provided for writing tests, including sample test code:

Use the provided tests from Guided Projects 1 & 2 to help you write your own tests for Guided Project 3!

Callout Box Icon

Reference: GP3 Design

See the Guided Project 3 Design for details on how checkConflict() integrates into the Activity hierarchy and the expected method behavior.

Test and Implement Activity.checkConflict()

Use TDD to implement the checkConflict() method in Activity. The teaching staff has provided a list of tests to consider, but this is by no means an exhaustive list or all of the tests that the teaching staff will evaluate you on. Use your testing skills to develop an extensive set of tests for Activity.checkConflict().

Tests for consideration:

  • No conflict test where a2.checkConflict(a1) is called. This switches the this and parameter to make sure that the method is commutative.
  • Conflict on a single day.
  • Conflict where the endTime for this is the same as the startTime for possiblyConflictingActivity.

As you write each test (which can continue in the same method or a separate test method for each test), update Activity.checkConflict() as appropriate to test the new tests without failing the old tests (or any other tests in the test suite).

When you are confident that your Activity.checkConflict() method is working correctly, you can move on to the next steps.

Jenkins and Teaching Staff Tests

Now that you are writing your own tests, the teaching staff unit tests will be hidden from you. The teaching staff tests will run if 1) you have no testing-related PMD notifications and 2) you have greater than 80% statement coverage on non-UI classes. Teaching staff test are listed with a starting TS. A failing teaching staff test has a hint that is provided so that you can try creating your own version of the test locally for debugging. If you have a question about a hint, please post it to Piazza for clarification.

When working on your projects, you may end with lots of teaching staff test failures. That’s ok! They are there to help you improve your code. However, you need to be strategic in how to go about fixing them. You can’t just start at the top of the list and work your way down. Because we utilized composition relationships, certain classes have dependencies on other classes. You should focus on fixing the contained classes before fixing the containers. For WolfScheduler, you should focus on fixing bugs in the Activity hierarchy before fixing bugs in WolfScheduler!

Document Activity.checkConflict()

As always, you should document the method with details about the implementation that would help a client of Activity work with the method correctly in their own code!

Reference: Staging and Pushing to GitHub

Check Your Progress

Complete the following tasks before pushing your work to GitHub.

  • Make sure that all fields, methods, and constructors are commented.
  • Resolve all static analysis notifications.
  • Fix test failures.
  • Commit and push your code changes with a meaningful commit message. Label your commit with “[Implementation]” and “[Test]” for future you!
  • Check Jenkins results for a yellow ball. Fix any failing tests in TSActivityTest and in the course package. Test failures in the scheduler package can wait until later in the Guided Project.

Independent Task: Coverage

Use EclEmma to evaluate coverage on checkConflict() method in Activity.

Callout Box Icon

Learning Outcomes

  • Use coverage to determine if additional tests are needed to execute other, uncovered, paths
Callout Box Icon

Best Practice: Coverage

Coverage is a measure of the code executed when running a test case. The principle behind coverage is that a line of code that has been executed is less likely to contain a bug than a non-executed line of code. There are four levels of coverage:

  • Method coverage: every method called at least once.
  • Statement/Line coverage: every statement executed at least once.
  • Branch coverage: every conditional statement evaluated on both its true and false paths.
  • Condition coverage: every predicate in a compound conditional evalue on both its true and false paths.

For CSC 216, the teaching staff expects that you will achieve at least 80% statement coverage on each model class (which are any of the classes not in the ui package). A coverage tool can identify paths that you have not yet executed with your tests. Using the feedback you can write additional tests to exercise other portions of your code.

There are some limitations to code coverage. Since you are using your existing code to drive your testing, your tests won’t tell you if you’re missing functionality. That is one reason why you should use TDD to drive the implementation and a reason for why we have multiple types of testing - the missing functionality might be caught in system level tests.

Also, don’t write poor tests just to make your coverage tool happy. Take the time to write a meaningful test so that you may have increased confidence that your code works correctly. PMD will provide notifications on poor test practices!

Callout Box Icon

Grading: Line Coverage Only

For GP3, only Line/Statement coverage is graded, requiring at least 80% on each non-UI class. Branch coverage is displayed by in the console view of Jenkins, but is not graded. Coverage metrics are tracked for source files (src), not test files.

Run Tests for Coverage

To run tests for coverage, right click on the test/ source folder and select Coverage As > JUnit Test.

When evaluating coverage locally, focus only on the coverage of classes that are not in the *.ui package. The coverage of the test classes themselves and any user interface classes are not considered when evaluating the coverage of your tests. Jenkins is set up to exclude test classes and user interface classes, but your local EclEmma is not. Don’t panic if the numbers seem low.

One last thing to check is that EclEmma is reporting the right metrics. Click the down arrow (View Menu) option in the Coverage view. Select Line Counters for seeing statement/line coverage. If you want to see condition coverage, use the Branch Counters option.

Reminder: Resources on Coverage

There are several resources provided about code coverage:

Use Coverage to Drive Testing

The CSC 216 Teaching Staff expect 80% statement coverage on every non-UI and non-test class. While the unit tests provided by the teaching staff for the rest of the project are extensive, they may not achieve 80% coverage on your implementation. Add additional tests to reach the 80% coverage threshold for all non-UI and non-test classes: Activity, Course, Event, ConflictException, ActivityRecordIO, CourseRecordIO, and WolfScheduler.

Jenkins and Teaching Staff Tests

Now that you are writing your own tests, the teaching staff unit tests will be hidden from you. The teaching staff tests will run if 1) you have no testing-related PMD notifications and 2) you have greater than 80% statement coverage on non-UI classes. Teaching staff test are listed with a starting TS. A failing teaching staff test has a hint that is provided so that you can try creating your own version of the test locally for debugging. If you have a question about a hint, please post it to Piazza for clarification.

When working on your projects, you may end with lots of teaching staff test failures. That’s ok! They are there to help you improve your code. However, you need to be strategic in how to go about fixing them. You can’t just start at the top of the list and work your way down. Because we utilized composition relationships, certain classes have dependencies on other classes. You should focus on fixing the contained classes before fixing the containers. For WolfScheduler, you should focus on fixing bugs in the Activity hierarchy before fixing bugs in WolfScheduler!

When you look at Jenkins feedback at this step, make sure you look at the console output. That provides a listing of the statement coverage for your non-UI classes and will let you know about PMD notifications. If the teaching staff test cases are blocked, the statement SKIPPING TEACHING STAFF TEST CASES will be displayed. There are some sample console outputs below. Note, you can ignore the output lines about the Nashorn engine.

Callout Box Icon

Troubleshooting: Jenkins Skipping Tests

If Jenkins shows SKIPPING TEACHING STAFF TEST CASES, check the console output for:

  1. PMD Notifications: Fix any JUnit-related PMD alerts (e.g., missing assertions, poor test practices)
  2. Coverage Below 80%: Ensure all non-UI classes have at least 80% line coverage
  3. Compilation Errors: Even if local JUnit tests pass, a compilation error in your code may prevent teaching staff tests from running. Check for any BUILD FAILED messages earlier in the console output.

PMD Notification There is a statement Project contains X JUnit-related PMD alerts, which leads to the statement SKIPPING TEACHING STAFF TEST CASES.

1
2
3
4
5
6
7
11:26:14      [echo] ---> Checking coverage thresholds for source files
11:26:14    [script] Warning: Nashorn engine is planned to be removed from a future JDK release
11:26:14      [exec] Project contains 1 JUnit-related PMD alerts
11:26:14      [exec] Result: 1
11:26:14    [script] Warning: Nashorn engine is planned to be removed from a future JDK release
11:26:14      [echo] 
11:26:14      [echo] *****SKIPPING TEACHING STAFF TEST CASES*****

Coverage Report - Insufficient Coverage If the statement/line coverage (last column) for one or more classes is under 80%, a message of TOTAL of X classes not meeting the 80% line coverage threshold will be displayed, which leads to the statement of SKIPPING TEACHING STAFF TEST CASES.

1
2
3
4
5
6
7
8
9
10
11
12
13
11:55:08      [exec] 	CLASS                                    METHOD COVERAGE      LINE COVERAGE       
11:55:08      [exec] 	Activity                                 100                  83                  
11:55:08      [exec] 	Event                                    90                   93                  
11:55:08      [exec] 	Course                                   82                   72                  
11:55:08      [exec] 	ConflictException                        100                  100                 
11:55:08      [exec] 	CourseRecordIO                           66                   97                  
11:55:08      [exec] 	ActivityRecordIO                         50                   85                  
11:55:08      [exec] 	WolfScheduler                            0                    0                   
11:55:08      [exec] TOTAL of 2 classes not meeting the 80% line coverage threshold
11:55:08      [exec] Result: 1
11:55:08    [script] Warning: Nashorn engine is planned to be removed from a future JDK release
11:55:08      [echo] 
11:55:08      [echo] *****SKIPPING TEACHING STAFF TEST CASES*****

Coverage Report - No Problems The statement/line coverage (last column) exceeds the 80% threshold per class. There is a statement that a TOTAL of 0 classes not meeting the 80% line coverage threshold and there are lines stating that the teaching staff tests are building and executing. You can see the full results, including hints, in the test reports.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
11:40:24      [exec] 	CLASS                                    METHOD COVERAGE      LINE COVERAGE       
11:40:24      [exec] 	Activity                                 100                  91                  
11:40:24      [exec] 	Event                                    100                  100                 
11:40:24      [exec] 	Course                                   100                  93                  
11:40:24      [exec] 	ConflictException                        100                  100                 
11:40:24      [exec] 	CourseRecordIO                           66                   97                  
11:40:24      [exec] 	ActivityRecordIO                         50                   85                  
11:40:24      [exec] 	WolfScheduler                            100                  93                  
11:40:24      [exec] TOTAL of 0 classes not meeting the 80% line coverage threshold
11:40:24    [script] Warning: Nashorn engine is planned to be removed from a future JDK release
11:40:24    [script] Warning: Nashorn engine is planned to be removed from a future JDK release
11:40:24      [echo] 
11:40:24      [echo] ---> Building Teaching Staff Tests
11:40:25      [echo] 
11:40:25      [echo] ---> Executing Teaching Staff unit tests
Reference: Staging and Pushing to GitHub

Check Your Progress

Complete the following tasks before pushing your work to GitHub.

  • Make sure that all fields, methods, and constructors are commented.
  • Resolve all static analysis notifications.
  • Fix test failures.
  • Commit and push your code changes with a meaningful commit message. Label your commit with “[Test]” for future you!
  • Check Jenkins results for a yellow ball! Fix any coverage issues in the course and io packages. Other test failures and coverage issues from the scheduler package can wait for the next step.

Independent Task: Update WolfScheduler

There are several updates required for WolfScheduler to work with the Activity.checkConflict functionality. WolfScheduler will catch any ConflictExceptions and throw IllegalArgumentExceptions out to the client.

Callout Box Icon

Learning Outcomes

  • Refactor WolfScheduler to check for conflict
Callout Box Icon

Important: Test Regression Expected

Implementing conflict checking will cause some previously passing GP1/GP2 tests to fail. The provided WolfSchedulerTest tests were written before the conflict functionality was added. Tests that add overlapping courses or events to a schedule will now throw exceptions instead of succeeding silently. You must update these tests to verify that the appropriate IllegalArgumentException is thrown with the correct message (e.g., “The course cannot be added due to a conflict.”).

Update WolfSchedulerTest and WolfScheduler

WolfScheduler should check for possible conflicts when addCourseToSchedule() and addEventToSchedule() are called. Update WolfSchedulerTest to include tests for the conflict functionality.

Then update addCourseToSchedule() and addEventToSchedule() to pass the tests. WolfScheduler will catch any ConflictExceptions and throw IllegalArgumentExceptions out to the client with appropriate messages for the dialog boxes.

  • If a ConflictException is caught in addCourseToSchedule() and IllegalArgumentException is thrown with the message "The course cannot be added due to a conflict.".
  • If a ConflictException is caught in addEventToSchedule() and IllegalArgumentException is thrown with the message "The event cannot be added due to a conflict.".

You may need to go back and update some of the tests that were provided with WolfSchedulerTest! The tests were written before the time conflict functionality was added and will need to be modified based on the full implementation. You cannot delete the provided test methods, but you can revise them to check that the appropriate exceptions are thrown and that the correct schedule information is there afterwards (i.e., without the conflicting activity).

Jenkins and Teaching Staff Tests

Now that you are writing your own tests, the teaching staff unit tests will be hidden from you. The teaching staff tests will run if 1) you have no testing-related PMD notifications and 2) you have greater than 80% statement coverage on non-UI classes. Teaching staff test are listed with a starting TS. A failing teaching staff test has a hint that is provided so that you can try creating your own version of the test locally for debugging. If you have a question about a hint, please post it to Piazza for clarification.

When working on your projects, you may end with lots of teaching staff test failures. That’s ok! They are there to help you improve your code. However, you need to be strategic in how to go about fixing them. You can’t just start at the top of the list and work your way down. Because we utilized composition relationships, certain classes have dependencies on other classes. You should focus on fixing the contained classes before fixing the containers. For WolfScheduler, you should focus on fixing bugs in the Activity hierarchy before fixing bugs in WolfScheduler!

Run Coverage

Ensure that WolfScheduler has 80% or higher statement coverage. If not, use the coverage feedback to create more high quality tests.

Reference: Staging and Pushing to GitHub

Check Your Progress

Complete the following tasks before pushing your work to GitHub.

  • Make sure that all fields, methods, and constructors are commented.
  • Resolve all static analysis notifications.
  • Fix test failures.
  • Commit and push your code changes with a meaningful commit message. Label your commit with “[Implementation]” and “[Test]” for future you!
  • Check Jenkins results for a green ball! Fix any Jenkins issues.

Independent Task: Update WolfSchedulerGUI

Black box test the WolfScheduler system to ensure that the conflict functionality is working correctly from end-to-end.

Callout Box Icon

Learning Outcomes

  • Run (and revise) black box tests

WolfSchedulerGUI

WolfSchedulerGUI did not require any changes from GP2. But if you need a new copy, copy the code from WolfSchedulerGUI.java into your Eclipse file. Overwrite the entirety of the old file.

Run System Tests

Run your system tests! If any are still failing, use the debugger to help you find the problem. Report the actual results of your tests.

If you need to revise your tests to more correctly describe the inputs or outputs, you may do so.

Record the actual results of execution for your tests. If you run low on time, remember it is better to record the actual test failure; you’ll get credit for reporting what’s actually happening.

Make sure that you successfully push your System Test Plan to the remote GitHub repository! Check the website to make sure it’s there!

Reference: Staging and Pushing to GitHub

Check Your Progress

Complete the following tasks before pushing your work to GitHub.

  • Make sure that all fields, methods, and constructors are commented.
  • Resolve all static analysis notifications.
  • Fix test failures.
  • Commit and push your code changes with a meaningful commit message. Label your commit with “[GUI]” and “[Test]” for future you!
  • Check Jenkins results for a green ball! Fix any Jenkins issues.

Independent Task: Submit Project

There are a few tasks that you must complete to wrap up Guided Project 3 for grading.

Callout Box Icon

Learning Outcomes

  • Run static analysis tools and fix notifications
Reminder: Running Static Analysis Tools

Run Static Analysis Tools

Run SpotBugs, PMD, and CheckStyle on your code (if you haven’t been already) and remove any notifications.

Reminder: Generating Javadoc

Generate Javadoc

If you haven’t been commenting your code all along, go back and comment your code with Javadoc. All classes, methods, and fields should be commented. If you have been commenting as you have implemented the Activity hierarchy, go back and double check that the comments are up to date for the implemented functionality.

Make sure you include comments for overridden method that describe why the override was important.

Generate Javadoc for WolfScheduler. You may want to delete the existing doc/ folder before generating a new one to ensure that all Javadoc is updated. Double check that everything was generated!

Reminder: Jenkins Feedback

Continuous Integration and Automated Grading

As with Guided Project 1 & 2, and all programming assignments for CSC 216/217, we are using Jenkins as an automated grading and feedback system. Check your Jenkins results and use them to estimate your grade against the Guided Project 3 rubric.

Final Tasks

Before you complete your final submission to GitHub, you should ensure the following:

Make sure that all code is pushed to GitHub by the assignment deadline (check all the files are on the remote!). There are deductions for any late work up to 48 hours.

AI Usage Documentation

As stated in the syllabus, the use of AI assistants (e.g., ChatGPT, Claude, Copilot) is permitted for programming assignments. All AI assistance MUST be documented in your README.md file. Include for each use:

  • The AI tool used
  • The prompt given
  • A summary of the AI response
  • How you verified the AI response
  • How you used the AI response in your solution

Undocumented AI usage is a violation of academic integrity. Include an AI documentation section in your README.md even if you did not use AI tools (state that no AI tools were used).

Grading Rubric

Your Wolf Scheduler Guided Project 3 will be evaluated on the following items:

Overall Rubric

Phase Grade Item Points Details
Student JUnit Tests 20 Pass all of *your* JUnit tests.
Student Coverage 20 Achieve at least 80% statement coverage on each non-UI class.
Teaching Staff JUnit Tests 20 Pass all of the teaching staff JUnit tests (this includes the originally provided tests, with some updates as per the requirements and new hidden tests for the schedule conflict functionality).
Student System Tests 20 There are 20 tests. You should both pass the test and report the actual results of execution. You will receive partial credit for reporting failing results for any of these tests that fail.
Teaching Staff System Tests 20 Pass the teaching staff's system tests.
Javadoc Contents 5 See the Javadoc rubric, below. The rubric will be applied per class and will be averaged by the number of classes.
Javadoc Generation 5 Javadoc tool was used to generate the HTML version of the API, which matches the current version of the in-code Javadoc.
Style 5 Any PMD, CheckStyle, or SpotBugs Scary or Scariest notifications will result in a one point deduction, up to the available points.
  Total Points 115  

Deductions

Grade Item Points Details
Misnamed file or incorrect project structure -5 Incorrect names of files or incorrect project structure. This can include problems when importing the project to Eclipse for acceptance testing, incorrect location of the system test file, etc.
Late varies You will lose 1 point for every 2 hours your projects is late, up to 24 points in 48 hours.

Javadoc Rubric

Item Strong - 3 points Adequate - 2 points Inadequate - 1 point
Class comments Class comments fully describe the behavior and abstraction of the class. Author tag is there. Class comments lack some details of the class’ behavior and abstraction. Author tag may be missing. Class comments are there but provide no detail about the class’ purpose. Author tag may be missing.
Method comments Method comments fully describe the behavior of the method. Param, return, and throws (for both checked and unchecked exceptions) tags are there and fully specified as appropriate for the method. Method comments lack some details about the method’s behavior. Param and return tags are there, but not fully specified. Method comments are there but provide no detail about the method’s purpose. Param and return tags are missing.
Field comments Field comments fully describe the field’s state as part of the class’ abstraction Field comments lack some details about the field’s state as part of the class. Field comments are minimal and provide no detail about the field’s purpose.
Spelling No spelling errors A few minor spelling errors that do not distract from the content. Many spelling errors that distract from the content
Grammar No grammatical errors A few grammatical errors that do not distract from the content Many grammatical errors that distract from the content.
Reference: Staging and Pushing to GitHub

Check Your Progress

Complete the following tasks before pushing your work to GitHub.

  • Make sure that all fields, methods, and constructors are commented.
  • Resolve all static analysis notifications.
  • Fix test failures.
  • Commit and push your code changes with a meaningful commit message. Label your commit with “[Final Submission]” for future you!
  • Check Jenkins results for a green ball! Fix any Jenkins issues.

Grading Rubric

Your Wolf Scheduler Guided Project 3 will be evaluated on the following items:

Overall Rubric

Phase Grade Item Points Details
Student JUnit Tests 20 Pass all of *your* JUnit tests.
Student Coverage 20 Achieve at least 80% statement coverage on each non-UI class.
Teaching Staff JUnit Tests 20 Pass all of the teaching staff JUnit tests (this includes the originally provided tests, with some updates as per the requirements and new hidden tests for the schedule conflict functionality).
Student System Tests 20 There are 20 tests. You should both pass the test and report the actual results of execution. You will receive partial credit for reporting failing results for any of these tests that fail.
Teaching Staff System Tests 20 Pass the teaching staff's system tests.
Javadoc Contents 5 See the Javadoc rubric, below. The rubric will be applied per class and will be averaged by the number of classes.
Javadoc Generation 5 Javadoc tool was used to generate the HTML version of the API, which matches the current version of the in-code Javadoc.
Style 5 Any PMD, CheckStyle, or SpotBugs Scary or Scariest notifications will result in a one point deduction, up to the available points.
  Total Points 115  

Deductions

Grade Item Points Details
Misnamed file or incorrect project structure -5 Incorrect names of files or incorrect project structure. This can include problems when importing the project to Eclipse for acceptance testing, incorrect location of the system test file, etc.
Late varies You will lose 1 point for every 2 hours your projects is late, up to 24 points in 48 hours.

Javadoc Rubric

Item Strong - 3 points Adequate - 2 points Inadequate - 1 point
Class comments Class comments fully describe the behavior and abstraction of the class. Author tag is there. Class comments lack some details of the class’ behavior and abstraction. Author tag may be missing. Class comments are there but provide no detail about the class’ purpose. Author tag may be missing.
Method comments Method comments fully describe the behavior of the method. Param, return, and throws (for both checked and unchecked exceptions) tags are there and fully specified as appropriate for the method. Method comments lack some details about the method’s behavior. Param and return tags are there, but not fully specified. Method comments are there but provide no detail about the method’s purpose. Param and return tags are missing.
Field comments Field comments fully describe the field’s state as part of the class’ abstraction Field comments lack some details about the field’s state as part of the class. Field comments are minimal and provide no detail about the field’s purpose.
Spelling No spelling errors A few minor spelling errors that do not distract from the content. Many spelling errors that distract from the content
Grammar No grammatical errors A few grammatical errors that do not distract from the content Many grammatical errors that distract from the content.

Jenkins Server

We are using the Jenkins Continuous Integration system to automatically evaluate your work and provide feedback on your submission. Go to the Guided Project and Project Jenkins Server by using https://csc216-jenkins.csc.ncsu.edu/.