EECS 183 Labs

EECS 183 Lab 4: Testing and Functions

Lab assignment Due Wednesday, September 29, 2021, 11:59 pm Eastern

In this lab, you are writing code and solving practice exam questions to master the use of conditionals and prepare for the first exam. The main focus of of the lab exercise is how to use (call) and test functions. You will have a lot of practice writing the definitions for functions in Project 2. While completing this lab, you will learn the testing tools necessary to master Project 2.

By completing this lab assignment, you will learn:

For all labs in EECS 183, to receive a grade, every student must individually submit the lab assingment, even if you are working in a group.

Starter Files

You can download the starter files using this link.

The IDE setup tutorials for Visual Studio and XCode include a video about how to set up a project using the starter files. You can access the tutorials here:

Lab Assignment

NOTE: The test cases you create in this lab can and should be used for your Project 2 tests. Specifically, the tests you create in this lab should be added to your test.cpp. While Project 2 is an individual assignment, the test cases you create with your lab team can be submitted for credit.

Function to test: isGregorianDate()

This is a function that returns true if the date is in the limits of the Gregorian calendar and false otherwise. We have provided a stub (empty implementation) for this function that will always return false, however (so that the program compiles). You don’t need to implement isGregorianDate in this lab.

/**
 * Requires: month, day, year may represent a date
 * Modifies: nothing
 * Effects: returns 'true' if the date is in the limits
 *          of the Gregorian calendar otherwise returns 'false'
 *          See below for definition of "limits of the Gregorian calendar"
 */
bool isGregorianDate(int month, int day, int year);

NOTE: A date is Gregorian if it is after September 13, 1752.

Function to write: test_isGregorianDate()

Write your own function test_isGregorianDate() and call it within int main().

The simplest way to test is to just print out expected and actual return values to standard output (cout). Below is the beginning of the testing for isGregorianDate(). Note that he following test_isGregorianDate() is NOT a complete test suite for isGregorianDate(). Since isGregorianDate() returns a value of type bool, this will print a 0 for false and a 1 for true.

void test_isGregorianDate() {
    cout << "Begin testing isGregorianDate() " << endl;

    cout << "Expected: 1, actual: "
         << isGregorianDate(8, 19, 2016) << endl;
    cout << "Expected: 0, actual: "
         << isGregorianDate(3, 12, 1234) << endl;
    // continue with more tests

    cout << "End testing isGregorianDate() " << endl << endl;

You could also choose to use if statements to only print out tests that fail, like this:

void test_isGregorianDate() {
    cout << "Begin testing isGregorianDate()" << endl;

    if (!isGregorianDate(8, 19, 2016)) {
        cout << "FAILED: isGregorianDate(8, 19, 2016) should have returned 'true'" << endl;
    }
    if (isGregorianDate(3, 12, 1234)) {
        cout << "FAILED: isGregorianDate(3, 12, 1234) should have returned 'false'" << endl;
    }
    // etc.
    cout << "End testing isGregorianDate()" << endl << endl;
}

The expression !isGregorianDate(8, 19, 2016) is the equivalent of isGregorianDate(8, 19, 2016) != true. The expression isGregorianDate(3, 12, 1234) is the equivalent of isGregorianDate(3, 12, 1234) == true. However, you should write the first, as comparing the bool value returned by the function to either true or false is redundant.

Function to test: isLeapYear()

This is a function that returns true if year is a leap year and false otherwise. Again, we have provided a stub (empty implementation) for isLeapYear that will always return false, so that the program compiles. You don’t need to implement this function in the lab.

/**
 * Requires: year is Gregorian
 * Modifies: nothing
 * Effects: returns true is year is a leap year
 *          false otherwise
 */
bool isLeapYear(int year);

Remember these rules:

Function to write: test_isLeapYear()

Write your own function test_isLeapYear() and call it within int main().

Notice how isLeapYear() has a Requires clause that states that “year must be a Gregorian year”. What this means is you can – and should – test years that are Gregorian such as 2015:

// because 2015 is a Gregorian year
cout << "Expected: 0, actual: " << isLeapYear(2015) << endl;

// or test 2015 this way
if (isLeapYear(2015)) {
    cout << "FAILED: isLeapYear(2015) should have returned 'false'" << endl;
}

However, the year 1750 is not a Gregorian year. The date must strictly after September 13, 1752 to be Gregorian. Therefore, even though it is legal within C++ to write

// invalid test case
cout << isLeapYear(1750) << endl;

it violates the Requires clause and the programmer should not do this. It is the responsibility of the coder to not violate the Requires clauses.

NOTE: Be cautious with the year 1752 – since the Gregorian calendar did not begin until September 1752, the year does not count as a valid Gregorian year for the purposes of the function isLeapYear().

NOTE: If your test cases call isLeapYear() on a year less than 1753, you will fail on the autograder. The autograder will produce an error along the lines of “Assertion ‘year > 1752’ failed”.

Think of a set of dates that will thoroughly test isLeapYear().

Unlike the projects, you will receive extra submissions with feedback for this lab from the autograder. You should consider carefully all of the tests necessary to thoroughly test the isGregorianDate() and isLeapYear() functions before your first sumbission to the autograder.

One of the key learning objectives of this portion of the lab is to give you feedback on the quality of the test cases you write. For this reason, you are allowed more submissions with feedback per day to the autograder than that of projects. The more care you put into writing thorough test suites, the more you will reduce the amount of time you spend debugging your function implementations for Project 2 and beyond.

Bugs To Expose

There are a total of 10 unique bugs to find in our implementations of isGregorianDate() and isLeapYear(). Your tests do not need to expose all of the bugs to receive full points for the lab – when you receive full points on the autograder, you do not need to expose more tests to receive more credit. The autograder will tell you the names of the bugs that you have exposed, from the following set:

How to Submit

Note: If you’re using Xcode and don’t know how where exactly lab4.cpp is located on your disk, right-click (or click while holding down the Control key) on the file in the Navigator area on the left side of the Xcode window and choose Show in Finder.

If you’re using Visual Studio and would like to know where lab4.cpp is on your disk, right-click on lab4.cpp in the tab above the Code pane and choose Open Containing Folder.

IMPORTANT: For all labs in EECS 183, to receive a grade, every student must individually submit the lab. Late submission for labs will not be accepted for credit. For this lab, you will receive ten submissions per day with feedback.