Starting from:
$35

$29

Project 1: Unit Tests and Linear Structures Solution

Topics: Design, testing, UML, unit tests




Turn in: Turn in all source les - .cpp, .hpp, and/or .h les. Do not turn in Visual Studio les.




Starter les: Download from GitHub.




Building and running: If you are using Visual Studio, make sure to run with debugging. (Don't run without debugging!) Using the debugger will help you nd errors.




To prevent a program exit, use this before return 0;




cin.ignore();




cin.get();




Tips:




Always make sure it builds. Only add a few lines of code at a time and build after each small change to ensure your program still builds.




One feature at a time. Only implement one feature (or one function) at a time. Make sure it builds, runs, and works as intended before moving on to the next feature.




Search for build errors. Chances are someone else has had the same build error before. Copy the message into a search engine and look for information on why it occurs, and how to resolve it.




Use debug tools, such as breakpoints, stack trace, and variable watch.




Don't implement everything in one go. Don't just try typing out all the code in one go without building, running, and testing. It will be much harder to debug if you've tried to program everything all at once.







About



Linear data structures may be implemented in di erent ways behind-the-scenes, but the general functionality should still result in the same outcome. For this project, you will design and implement unit tests for a linear struc-ture, and these tests will be tested against the Bag data type, a smart Dy-namic Array, and eventually the Linked List object.




Test les




In the starter code, there are the following les:




tester program.cpp - contains main()




Tester.hpp - the class and function declarations Tester.cpp - the tester function de nitions




List.hpp - A List class, with stub functions







The List class will have placeholders in the methods so that the program will be buildable. You will remove the placeholders as the functions are being implemented.




Before implementing the functions, your rst task is to implement the tests. As you implement the tests, they will start of failing (for the most part), which is good. Then, when you implement the actual functionality, you can validate that it works as intended by whether it passes the tests.




Your tests may not be correct at rst since this might be a new concept, so in some cases it is okay to adjust your tests. You might also have to add additional test cases to more fully cover the functionality.




Once these tests are implemented and working with a static array-based list, then the tests should also theoretically work with other linear structures.




Three turn ins




You will turn in this project in three parts: First, the Test Outline document (edit in LibreO ce or MS Word and turn in). Second, the test implementa-tions in the code. Third, the full List implementation.





Part 1 - Planning Tests




Make sure you download the Test Outline document. This is a document you can open up in MS Word or LibreO ce. Work on planning your test sets during class. You can also brainstorm with other students on this part.




Your tests should, at minimum, cover all reasonable outputs. For example, for something that returns a boolean, we should have tests that expect a true and a false as outputs. For a function that returns an integer, such as Size(), you won't test all possible outputs, but at least for 0, 1, and several other values.










Figure 1.1: An example of tests for the IsEmpty() function, in the Test Outline document.







We will work on this part during class, and for Part 1 of the project you can brainstorm and collaborate with other students. However, keep in mind that your code in Part 2 and Part 3 should be your own.





Part 2 - Writing Tests




For this part of the project you should be working just on the tests, not the List functions. You will upload this project in two parts: Just the tests, and then the tests with the List code.




Reference the Function Speci cations section for descriptions of the functions




Writing unit tests




Each unit test is meant to test one function each, though you might have to rely on multiple functions to fully validate a function. For example, to test the Size() function, you need to be able to add new items to the list, so Push(...) will have to be implemented for the Size() test to work properly.




Each test function may need multiple tests to properly coverage all reasonable use cases.




For each test, you will need to decide on inputs to pass in, and the expected output. To get the actual output, you will call the function being tested, and store its return value in a variable.




You can use an if statement to check whether the actual output matches the expected output. If they match, the individual test can pass. If they don't match, the test fails.




It's up to you for what to output to the screen, though generally it helps if you output the inputs and outputs, and whether the test passes or fails.




Tests to implement




The tests to implement are:




Test


Init()
Test


ShiftRight()
Test


ShiftLeft()






Test


Size()
Test


IsEmpty()
Test


IsFull()






Test


PushFront()
Test


PushBack()
Test


PopFront()
Test


PopBack()
Test


Clear()
Test


Get()
Test


GetFront()
Test


GetBack()
Test


GetCountOf()
Test


Contains()
Test


Remove()
Test


Insert()

















By Rachel Singh, last updated January 5 of 16






CS 250, Project 1: Unit Tests and Linear Structures







Example test:







void Tester :: T es t_ Si ze ()




{




DrawLine () ;




cout << " TEST : Te st _S iz e " << endl ;







{ // Test begin




cout << " \ n \ n Test 1 " ;




List < int testList ;




int e x p e c t e d S i z e = 0;




int a c t u a l S i z e = testList . Size () ;







cout << " \ n Expected size : " << e x p e c t e d S i z e ;




cout << " \ n Actual size : " << a c t u a l S i z e ;







if ( a c t u a l S i z e == e x p e c t e d S i z e )




cout << " \ n Pass " ;




else




cout << " \ n Fail " ;




} // Test end







{// Test begin







cout << endl << " Test 2 " << endl ; List < int testList ;







testList . PushBack ( 1 ) ;




testList . PushBack ( 3 ) ;







int e x p e c t e d S i z e = 2;




int a c t u a l S i z e = testList . Size () ;







cout << " \ n Expected size : " << e x p e c t e d S i z e ;




cout << " \ n Actual size : " << a c t u a l S i z e ;







if ( a c t u a l S i z e == e x p e c t e d S i z e )




cout << " \ n Pass " ;




else




cout << " \ n Fail " ;




} // Test end




}





CS 250, Project 1: Unit Tests and Linear Structures







Example output:




An example of a couple of tests failing, since the List functions haven't been implemented yet.







- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TEST : T es t _S iz e







Test 1




Expected size : 0




Actual size : -1585510992




Fail







Test 2




Expected size : 1




Actual size : -1585510992




Fail
















Part 3 - Implementing the List




Once you've implemented the tests, you will be implementing the List func-tions based on the functionality speci ed. As you get each function working, your tests should be passing.




Note that certain tests may rely on the implementation of other functions, such as Size() needing a Push function implemented in order to test for more cases than just an empty list.











Function Specifications










Figure 1.2: A List class UML diagram, implemented with a static array



















IsEmpty




Function header: bool IsEmpty() const




Inputs: None




Outputs: true if there is nothing in the list (i.e., the size is 0), or false if not.














IsFull




Function header: bool IsFull() const




Inputs: None




Outputs: true if the list is full (i.e., the m itemCount is equal to ARRAY SIZE), or false if not.



















Size




Function header: int Size() const




Inputs: None




Outputs: Returns the amount of items stored in the list. Will be 0.



















GetCountOf




Function header: int GetCountOf( const T& item ) const




Inputs: const T& item, where the list contains items of type T (it is a template). The item to be searched for and counted is item.




Outputs: Returns the amount of instances of item being found in the list. Will be 0.




















Contains




Function header: bool Contains( const T& item ) const




Inputs: const T& item, where item is the item to search for.




Outputs: Returns true if item is found in the list, and false other-wise.






















List constructor




Function header: List()




Initializes the List class. The list should start o empty.




Inputs: None



















List destructor (no tests)







Nothing required for the static array version of the List.




PushFront




Function header: bool PushFront( const T& newItem )




Inputs: const T& item, the new item to add to the list at the begin-ning.




Outputs: Returns true if the operation is a success, and false other-wise.
















PushBack




Function header: bool PushBack( const T& newItem )




Inputs: const T& item, the new item to add to the list at the end.




Outputs: Returns true if the operation is a success, and false other-wise.
















Insert




Function header: bool Insert( int atIndex, const T& item )




Inserts a new item at the given index. Existing items shouldn't be re-placed. If there is an item already at the index given, it will be pushed towards the end of the list.




Inputs:




int atIndex - the index where to insert the new item. const T& item - the new item to insert.




Outputs: Returns true if the operation is a success, and false other-wise.




















Get




Function header: T* Get( int atIndex )




Inputs: int atIndex, the index of the item to return.




Outputs: Returns the address of the item at the index given, or nullptr if it isn't found.



















GetFront




Function header: T* GetFront()




Inputs: None




Outputs: Returns the address of the item at the front of the list, or nullptr if the list is empty.



















GetBack




Function header: T* GetBack()




Inputs: None




Outputs: Returns the address of the item at the end of the list, or nullptr if the list is empty.











PopFront




Function header: bool PopFront()




Inputs: None




Outputs: Returns true if removing the item is successful, and false otherwise.
















PopBack




Function header: bool PopBack()




Inputs: None




Outputs: Returns true if removing the item is successful, and false otherwise.
















Remove




Function header: bool Remove( const T& item ) Function header:




bool Remove( int atIndex )




Inputs:




const T& item - locates all instances of this item in the list and removes it.




int atIndex - removes the item at this index.




Outputs: Returns true if removing the item is successful, and false otherwise.

















Clear




Function header: void Clear()




Clears out the list. To test this function, you should ensure that the size of the list returns to 0 after this function is called.




Inputs: None




Outputs: None



















ShiftRight




Function header: bool ShiftRight( int atIndex )




Moves everything to the right of the index further to the right by one position.




Inputs: int atIndex - The index at which to begin moving items for-ward.




Outputs: Returns true if the shift is successful, or false if not.



















ShiftLeft




Function header: bool ShiftLeft( int atIndex )




Moves everything to the right of the index further to the left by one position. This will overwrite the item at the atIndex.




Inputs: None




Outputs: Returns true if the shift is successful, or false if not.









By Rachel Singh, last updated January 14 of 16


More products